From c7b155b6390441c54961346298e16fe26285fb00 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 17 Nov 2016 21:44:16 -0700 Subject: [PATCH] Allow initfs to be written --- kernel/scheme/initfs.rs | 53 +++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/kernel/scheme/initfs.rs b/kernel/scheme/initfs.rs index 4857426..449260c 100644 --- a/kernel/scheme/initfs.rs +++ b/kernel/scheme/initfs.rs @@ -1,4 +1,5 @@ -use collections::BTreeMap; +use alloc::arc::Arc; +use collections::{BTreeMap, Vec}; use core::{cmp, str}; use core::sync::atomic::{AtomicUsize, Ordering}; use spin::RwLock; @@ -20,22 +21,27 @@ mod gen; struct Handle { path: &'static [u8], - data: &'static [u8], + data: Arc>>, mode: u16, seek: usize } pub struct InitFsScheme { next_id: AtomicUsize, - files: BTreeMap<&'static [u8], (&'static [u8], bool)>, + files: BTreeMap<&'static [u8], (Arc>>, bool)>, handles: RwLock> } impl InitFsScheme { pub fn new() -> InitFsScheme { + let mut files = BTreeMap::new(); + for (path, (data, folder)) in gen::gen() { + files.insert(path, (Arc::new(RwLock::new(data.to_vec())), folder)); + } + InitFsScheme { next_id: AtomicUsize::new(0), - files: gen::gen(), + files: files, handles: RwLock::new(BTreeMap::new()) } } @@ -52,7 +58,7 @@ impl Scheme for InitFsScheme { let id = self.next_id.fetch_add(1, Ordering::SeqCst); self.handles.write().insert(id, Handle { path: entry.0, - data: (entry.1).0, + data: (entry.1).0.clone(), mode: if (entry.1).1 { MODE_DIR | 0o755 } else { MODE_FILE | 0o744 }, seek: 0 }); @@ -68,7 +74,7 @@ impl Scheme for InitFsScheme { let (path, data, mode, seek) = { let handles = self.handles.read(); let handle = handles.get(&id).ok_or(Error::new(EBADF))?; - (handle.path, handle.data, handle.mode, handle.seek) + (handle.path, handle.data.clone(), handle.mode, handle.seek) }; let id = self.next_id.fetch_add(1, Ordering::SeqCst); @@ -85,10 +91,26 @@ impl Scheme for InitFsScheme { fn read(&self, id: usize, buffer: &mut [u8]) -> Result { let mut handles = self.handles.write(); let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; + let data = handle.data.read(); let mut i = 0; - while i < buffer.len() && handle.seek < handle.data.len() { - buffer[i] = handle.data[handle.seek]; + while i < buffer.len() && handle.seek < data.len() { + buffer[i] = data[handle.seek]; + i += 1; + handle.seek += 1; + } + + Ok(i) + } + + fn write(&self, id: usize, buffer: &[u8]) -> Result { + let mut handles = self.handles.write(); + let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; + let mut data = handle.data.write(); + + let mut i = 0; + while i < buffer.len() && handle.seek < data.len() { + data[handle.seek] = buffer[i]; i += 1; handle.seek += 1; } @@ -99,11 +121,12 @@ impl Scheme for InitFsScheme { fn seek(&self, id: usize, pos: usize, whence: usize) -> Result { let mut handles = self.handles.write(); let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; + let data = handle.data.read(); handle.seek = match whence { - SEEK_SET => cmp::min(handle.data.len(), pos), - SEEK_CUR => cmp::max(0, cmp::min(handle.data.len() as isize, handle.seek as isize + pos as isize)) as usize, - SEEK_END => cmp::max(0, cmp::min(handle.data.len() as isize, handle.data.len() as isize + pos as isize)) as usize, + SEEK_SET => cmp::min(data.len(), pos), + SEEK_CUR => cmp::max(0, cmp::min(data.len() as isize, handle.seek as isize + pos as isize)) as usize, + SEEK_END => cmp::max(0, cmp::min(data.len() as isize, data.len() as isize + pos as isize)) as usize, _ => return Err(Error::new(EINVAL)) }; @@ -135,16 +158,20 @@ impl Scheme for InitFsScheme { fn fstat(&self, id: usize, stat: &mut Stat) -> Result { let handles = self.handles.read(); let handle = handles.get(&id).ok_or(Error::new(EBADF))?; + let data = handle.data.read(); stat.st_mode = handle.mode; stat.st_uid = 0; stat.st_gid = 0; - stat.st_size = handle.data.len() as u64; + stat.st_size = data.len() as u64; Ok(0) } - fn fsync(&self, _id: usize) -> Result { + fn fsync(&self, id: usize) -> Result { + let handles = self.handles.read(); + let _handle = handles.get(&id).ok_or(Error::new(EBADF))?; + Ok(0) }