diff --git a/Cargo.lock b/Cargo.lock index 5f1536253f..e39315763d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -303,7 +303,7 @@ checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717" [[package]] name = "redox-scheme" version = "0.2.0" -source = "git+https://gitlab.redox-os.org/4lDO2/redox-scheme.git?branch=schemev2#40c29c6f08e095e7b3739feae47a3c24f469c4d3" +source = "git+https://gitlab.redox-os.org/4lDO2/redox-scheme.git?branch=schemev2plus#ca239589c873374a17715b637be1f9385345721c" dependencies = [ "libredox 0.1.3", "redox_syscall 0.5.1", @@ -321,7 +321,7 @@ dependencies = [ [[package]] name = "redox_syscall" version = "0.5.1" -source = "git+https://gitlab.redox-os.org/4lDO2/syscall.git?branch=schemev2#495a0adbd8333fd21fae2d97129b094607878ba7" +source = "git+https://gitlab.redox-os.org/4lDO2/syscall.git?branch=schemev2plus#b4f9a8952cec870ed7f457e3c15652d09aa0c9c7" dependencies = [ "bitflags 2.5.0", ] diff --git a/Cargo.toml b/Cargo.toml index 32147269e4..6dbf764a9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ termion = { version = "2", optional = true } uuid = { version = "1.4", default-features = false } redox-path = "0.3.0" libredox = { version = "0.1.3", optional = true } -redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2" } +redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2plus" } [features] default = ["std", "log"] @@ -71,4 +71,4 @@ libc = { version = "0.2", optional = true } time = { version = "0.1", optional = true } [patch.crates-io] -redox_syscall = { git = "https://gitlab.redox-os.org/4lDO2/syscall.git", branch = "schemev2", features = ["std"] } +redox_syscall = { git = "https://gitlab.redox-os.org/4lDO2/syscall.git", branch = "schemev2plus", features = ["std"] } diff --git a/src/mount/redox/resource.rs b/src/mount/redox/resource.rs index 7012d5615a..d9354ba3f5 100644 --- a/src/mount/redox/resource.rs +++ b/src/mount/redox/resource.rs @@ -29,11 +29,11 @@ pub trait Resource { fn set_path(&mut self, path: &str); - fn read(&mut self, buf: &mut [u8], tx: &mut Transaction) -> Result; + fn read(&mut self, buf: &mut [u8], offset: u64, tx: &mut Transaction) -> Result; - fn write(&mut self, buf: &[u8], tx: &mut Transaction) -> Result; + fn write(&mut self, buf: &[u8], offset: u64, tx: &mut Transaction) -> Result; - fn seek(&mut self, offset: isize, whence: usize, tx: &mut Transaction) -> Result; + fn fsize(&mut self, tx: &mut Transaction) -> Result; fn fmap( &mut self, @@ -143,7 +143,6 @@ pub struct DirResource { parent_ptr_opt: Option>, node_ptr: TreePtr, data: Option>, - seek: isize, uid: u32, } @@ -160,7 +159,6 @@ impl DirResource { parent_ptr_opt, node_ptr, data, - seek: 0, uid, } } @@ -185,7 +183,6 @@ impl Resource for DirResource { parent_ptr_opt: self.parent_ptr_opt, node_ptr: self.node_ptr, data: self.data.clone(), - seek: self.seek, uid: self.uid, })) } @@ -194,32 +191,21 @@ impl Resource for DirResource { self.path = path.to_string(); } - fn read(&mut self, buf: &mut [u8], _tx: &mut Transaction) -> Result { + fn read(&mut self, buf: &mut [u8], offset: u64, _tx: &mut Transaction) -> Result { let data = self.data.as_ref().ok_or(Error::new(EISDIR))?; - let size = data.len() as isize; - let mut i = 0; - while i < buf.len() && self.seek < size { - buf[i] = data[self.seek as usize]; - i += 1; - self.seek += 1; - } - Ok(i) + let src = usize::try_from(offset).ok().and_then(|o| data.get(o..)).unwrap_or(&[]); + + let byte_count = core::cmp::min(src.len(), buf.len()); + buf[..byte_count].copy_from_slice(&src[..byte_count]); + Ok(byte_count) } - fn write(&mut self, _buf: &[u8], _tx: &mut Transaction) -> Result { + fn write(&mut self, _buf: &[u8], _offset: u64, _tx: &mut Transaction) -> Result { Err(Error::new(EBADF)) } - fn seek(&mut self, offset: isize, whence: usize, _tx: &mut Transaction) -> Result { - let data = self.data.as_ref().ok_or(Error::new(EBADF))?; - let size = data.len() as isize; - self.seek = match whence { - SEEK_SET => max(0, min(size, offset)), - SEEK_CUR => max(0, min(size, self.seek + offset)), - SEEK_END => max(0, min(size, size + offset)), - _ => return Err(Error::new(EINVAL)), - }; - Ok(self.seek) + fn fsize(&mut self, _tx: &mut Transaction) -> Result { + Ok(self.data.as_ref().ok_or(Error::new(EBADF))?.len() as u64) } fn fmap( @@ -336,7 +322,6 @@ pub struct FileResource { parent_ptr_opt: Option>, node_ptr: TreePtr, flags: usize, - seek: isize, uid: u32, } #[derive(Debug)] @@ -370,7 +355,6 @@ impl FileResource { parent_ptr_opt, node_ptr, flags, - seek: 0, uid, } } @@ -395,7 +379,6 @@ impl Resource for FileResource { parent_ptr_opt: self.parent_ptr_opt, node_ptr: self.node_ptr, flags: self.flags, - seek: self.seek, uid: self.uid, })) } @@ -404,55 +387,43 @@ impl Resource for FileResource { self.path = path.to_string(); } - fn read(&mut self, buf: &mut [u8], tx: &mut Transaction) -> Result { - if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_RDONLY { - let atime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); - let count = tx.read_node( - self.node_ptr, - self.seek as u64, - buf, - atime.as_secs(), - atime.subsec_nanos(), - )?; - self.seek += count as isize; - Ok(count) - } else { - Err(Error::new(EBADF)) + fn read(&mut self, buf: &mut [u8], offset: u64, tx: &mut Transaction) -> Result { + if self.flags & O_ACCMODE != O_RDWR && self.flags & O_ACCMODE != O_RDONLY { + return Err(Error::new(EBADF)); } + let atime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + tx.read_node( + self.node_ptr, + offset, + buf, + atime.as_secs(), + atime.subsec_nanos(), + ) } - fn write(&mut self, buf: &[u8], tx: &mut Transaction) -> Result { - if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_WRONLY { - if self.flags & O_APPEND == O_APPEND { - let node = tx.read_tree(self.node_ptr)?; - self.seek = node.data().size() as isize; - } - let mtime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); - let count = tx.write_node( - self.node_ptr, - self.seek as u64, - buf, - mtime.as_secs(), - mtime.subsec_nanos(), - )?; - self.seek += count as isize; - Ok(count) - } else { - Err(Error::new(EBADF)) + fn write(&mut self, buf: &[u8], offset: u64, tx: &mut Transaction) -> Result { + if self.flags & O_ACCMODE != O_RDWR && self.flags & O_ACCMODE != O_WRONLY { + return Err(Error::new(EBADF)); } - } - - fn seek(&mut self, offset: isize, whence: usize, tx: &mut Transaction) -> Result { - self.seek = match whence { - SEEK_SET => max(0, offset), - SEEK_CUR => max(0, self.seek + offset), - SEEK_END => { - let node = tx.read_tree(self.node_ptr)?; - max(0, node.data().size() as isize + offset) - } - _ => return Err(Error::new(EINVAL)), + let effective_offset = if self.flags & O_APPEND == O_APPEND { + let node = tx.read_tree(self.node_ptr)?; + node.data().size() + } else { + offset }; - Ok(self.seek) + let mtime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + tx.write_node( + self.node_ptr, + effective_offset, + buf, + mtime.as_secs(), + mtime.subsec_nanos(), + ) + } + + fn fsize(&mut self, tx: &mut Transaction) -> Result { + let node = tx.read_tree(self.node_ptr)?; + Ok(node.data().size()) } fn fmap( diff --git a/src/mount/redox/scheme.rs b/src/mount/redox/scheme.rs index 17b890860c..a9f1ca88bc 100644 --- a/src/mount/redox/scheme.rs +++ b/src/mount/redox/scheme.rs @@ -12,8 +12,9 @@ use syscall::flag::{ EventFlags, MapFlags, MODE_PERM, O_ACCMODE, O_CREAT, O_DIRECTORY, O_EXCL, O_NOFOLLOW, O_RDONLY, O_RDWR, O_STAT, O_SYMLINK, O_TRUNC, O_WRONLY, }; +use syscall::schemev2::NewFdFlags; use syscall::{MunmapFlags, EBADFD}; -use redox_scheme::SchemeMut; +use redox_scheme::{CallerCtx, OpenResult, SchemeMut}; use redox_path::{canonicalize_to_standard, canonicalize_using_cwd, canonicalize_using_scheme, scheme_path, RedoxPath}; @@ -161,7 +162,9 @@ fn dirname(path: &str) -> Option { } impl SchemeMut for FileScheme { - fn open(&mut self, url: &str, flags: usize, uid: u32, gid: u32) -> Result { + fn xopen(&mut self, url: &str, flags: usize, ctx: &CallerCtx) -> Result { + let CallerCtx { uid, gid, .. } = *ctx; + let path = url.trim_matches('/'); // println!("Open '{}' {:X}", path, flags); @@ -234,7 +237,7 @@ impl SchemeMut for FileScheme { &mut resolve_nodes, ) })?; - return self.open(&resolved, flags, uid, gid); + return self.xopen(&resolved, flags, ctx); } else if !node.data().is_symlink() && flags & O_SYMLINK == O_SYMLINK { return Err(Error::new(EINVAL)); } else { @@ -355,39 +358,10 @@ impl SchemeMut for FileScheme { .or_insert_with(Default::default) .open_fds += 1; - let id = self.next_id.fetch_add(1, Ordering::SeqCst); + let id = self.next_id.fetch_add(1, Ordering::Relaxed); self.files.insert(id, resource); - Ok(id) - } - - fn chmod(&mut self, url: &str, mode: u16, uid: u32, gid: u32) -> Result { - let path = url.trim_matches('/'); - - // println!("Chmod '{}'", path); - - let scheme_name = &self.name; - self.fs.tx(|tx| { - let mut nodes = Vec::new(); - if let Some((mut node, _node_name)) = - Self::path_nodes(scheme_name, tx, path, uid, gid, &mut nodes)? - { - if node.data().uid() == uid || uid == 0 { - let old_mode = node.data().mode(); - let new_mode = (old_mode & !MODE_PERM) | (mode & MODE_PERM); - if old_mode != new_mode { - node.data_mut().set_mode(new_mode); - tx.sync_tree(node)?; - } - - Ok(0) - } else { - Err(Error::new(EPERM)) - } - } else { - Err(Error::new(ENOENT)) - } - }) + Ok(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED }) } fn rmdir(&mut self, url: &str, uid: u32, gid: u32) -> Result { @@ -497,32 +471,22 @@ impl SchemeMut for FileScheme { Ok(id) } - #[allow(unused_variables)] - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result { + fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result { // println!("Read {}, {:X} {}", id, buf.as_ptr() as usize, buf.len()); - if let Some(file) = self.files.get_mut(&id) { - self.fs.tx(|tx| file.read(buf, tx)) - } else { - Err(Error::new(EBADF)) - } + let file = self.files.get_mut(&id).ok_or(Error::new(EBADF))?; + self.fs.tx(|tx| file.read(buf, offset, tx)) } - fn write(&mut self, id: usize, buf: &[u8]) -> Result { + fn write(&mut self, id: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result { // println!("Write {}, {:X} {}", id, buf.as_ptr() as usize, buf.len()); - if let Some(file) = self.files.get_mut(&id) { - self.fs.tx(|tx| file.write(buf, tx)) - } else { - Err(Error::new(EBADF)) - } + let file = self.files.get_mut(&id).ok_or(Error::new(EBADF))?; + self.fs.tx(|tx| file.write(buf, offset, tx)) } - fn seek(&mut self, id: usize, pos: isize, whence: usize) -> Result { + fn fsize(&mut self, id: usize) -> Result { // println!("Seek {}, {} {}", id, pos, whence); - if let Some(file) = self.files.get_mut(&id) { - self.fs.tx(|tx| file.seek(pos, whence, tx)) - } else { - Err(Error::new(EBADF)) - } + let file = self.files.get_mut(&id).ok_or(Error::new(EBADF))?; + self.fs.tx(|tx| file.fsize(tx)) } fn fchmod(&mut self, id: usize, mode: u16) -> Result {