diff --git a/src/scheme/live.rs b/src/scheme/live.rs index acf14a03fef808698dd7abdfb6e9a9e6f8ca934c..375b7ca218fa97b1df4997c352d7b1bb76780225 100644 --- a/src/scheme/live.rs +++ b/src/scheme/live.rs @@ -8,18 +8,21 @@ use spin::RwLock; use rmm::Flusher; use syscall::data::Stat; -use syscall::error::*; +use syscall::{error::*, CallerCtx}; use syscall::flag::{MODE_DIR, MODE_FILE}; use syscall::scheme::{calc_seek_offset_usize, Scheme}; use crate::memory::Frame; use crate::paging::{KernelMapper, Page, PageFlags, PhysicalAddress, VirtualAddress}; use crate::paging::mapper::PageFlushAll; +use crate::syscall::usercopy::{UserSliceWo, UserSliceRo}; + +use super::OpenResult; static mut LIST: [u8; 2] = [b'0', b'\n']; struct Handle { - path: &'static [u8], + path: &'static str, data: Arc<RwLock<&'static mut [u8]>>, mode: u16, seek: usize @@ -85,123 +88,109 @@ impl DiskScheme { } impl Scheme for DiskScheme { - fn open(&self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> { + fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> { + let mut handles = self.handles.write(); + let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; + let data = handle.data.read(); + let new_offset = calc_seek_offset_usize(handle.seek, pos, whence, data.len())?; + handle.seek = new_offset as usize; + Ok(new_offset) + } + + fn fcntl(&self, id: usize, _cmd: usize, _arg: usize) -> Result<usize> { + let handles = self.handles.read(); + let _handle = handles.get(&id).ok_or(Error::new(EBADF))?; + + Ok(0) + } + + fn fsync(&self, id: usize) -> Result<usize> { + let handles = self.handles.read(); + let _handle = handles.get(&id).ok_or(Error::new(EBADF))?; + + Ok(0) + } + + fn close(&self, id: usize) -> Result<usize> { + self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0)) + } +} +impl crate::scheme::KernelScheme for DiskScheme { + fn kopen(&self, path: &str, _flags: usize, _caller: CallerCtx) -> Result<OpenResult> { let path_trimmed = path.trim_matches('/'); match path_trimmed { "" => { let id = self.next_id.fetch_add(1, Ordering::SeqCst); self.handles.write().insert(id, Handle { - path: b"", + path: "", data: self.list.clone(), mode: MODE_DIR | 0o755, seek: 0 }); - Ok(id) + Ok(OpenResult::SchemeLocal(id)) }, "0" => { let id = self.next_id.fetch_add(1, Ordering::SeqCst); self.handles.write().insert(id, Handle { - path: b"0", + path: "0", data: self.data.clone(), mode: MODE_FILE | 0o644, seek: 0 }); - Ok(id) + Ok(OpenResult::SchemeLocal(id)) } _ => Err(Error::new(ENOENT)) } } - - fn read(&self, id: usize, buffer: &mut [u8]) -> Result<usize> { + fn kread(&self, id: usize, buffer: UserSliceWo) -> Result<usize> { let mut handles = self.handles.write(); let 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 < data.len() { - buffer[i] = data[handle.seek]; - i += 1; - handle.seek += 1; - } + let src = data.get(handle.seek..).unwrap_or(&[]); + let bytes_read = buffer.copy_common_bytes_from_slice(src)?; + handle.seek += bytes_read; - Ok(i) + Ok(bytes_read) } - fn write(&self, id: usize, buffer: &[u8]) -> Result<usize> { + fn kwrite(&self, id: usize, buffer: UserSliceRo) -> Result<usize> { let mut handles = self.handles.write(); let 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; - } + let dst = data.get_mut(handle.seek..).unwrap_or(&mut []); + let bytes_written = buffer.copy_common_bytes_to_slice(dst)?; + handle.seek += bytes_written; - Ok(i) + Ok(bytes_written) } - - fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> { - let mut handles = self.handles.write(); - let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; - let data = handle.data.read(); - let new_offset = calc_seek_offset_usize(handle.seek, pos, whence, data.len())?; - handle.seek = new_offset as usize; - Ok(new_offset) - } - - fn fcntl(&self, id: usize, _cmd: usize, _arg: usize) -> Result<usize> { - let handles = self.handles.read(); - let _handle = handles.get(&id).ok_or(Error::new(EBADF))?; - - Ok(0) - } - - fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> { + fn kfpath(&self, id: usize, buf: UserSliceWo) -> Result<usize> { let handles = self.handles.read(); let handle = handles.get(&id).ok_or(Error::new(EBADF))?; - //TODO: Copy scheme part in kernel - let mut i = 0; - let scheme_path = b"disk/live:"; - while i < buf.len() && i < scheme_path.len() { - buf[i] = scheme_path[i]; - i += 1; - } - - let mut j = 0; - while i < buf.len() && j < handle.path.len() { - buf[i] = handle.path[j]; - i += 1; - j += 1; - } + let src = format!("disk/live:{}", handle.path); + let byte_count = buf.copy_common_bytes_from_slice(src.as_bytes())?; - Ok(i) + Ok(byte_count) } - - fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> { - 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 = data.len() as u64; - - Ok(0) - } - - fn fsync(&self, id: usize) -> Result<usize> { - let handles = self.handles.read(); - let _handle = handles.get(&id).ok_or(Error::new(EBADF))?; + fn kfstat(&self, id: usize, stat_buf: UserSliceWo) -> Result<usize> { + let stat = { + 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, + st_uid: 0, + st_gid: 0, + st_size: data.len() as u64, + ..Stat::default() + } + }; + stat_buf.copy_exactly(&stat)?; Ok(0) } - fn close(&self, id: usize) -> Result<usize> { - self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0)) - } } -impl crate::scheme::KernelScheme for DiskScheme {}