From 8faf1278947e54c5e6c9e7bad48eff96b07543ed Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Fri, 30 Aug 2024 21:22:00 +0200 Subject: [PATCH] Replace seek() with fsize(). --- Cargo.lock | 16 +++++----- Cargo.toml | 2 +- src/main.rs | 20 ++++++++---- src/scheme.rs | 87 ++++++++++++++++++++++++++------------------------- 4 files changed, 67 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 525c58454a..cdeae99868 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,15 +4,15 @@ version = 3 [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libredox" @@ -47,9 +47,9 @@ dependencies = [ [[package]] name = "redox-scheme" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a4d4161697395d7cc9b182a14a753b2ba0243dcf622e278e644c6e7f74904c1" +checksum = "2148c23b7ed5bf1cc3919b4830e4bf2a674a5d3691c619317624ccd78d13a3ac" dependencies = [ "libredox", "redox_syscall", @@ -57,9 +57,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ "bitflags", ] diff --git a/Cargo.toml b/Cargo.toml index d5fa4b92fd..517251bc61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,5 @@ description = "In-memory filesystem for Redox, which is useful for early logging [dependencies] redox-daemon = "0.1.2" redox_syscall = "0.5.1" -redox-scheme = "0.2" +redox-scheme = "0.2.1" libredox = "0.1.3" diff --git a/src/main.rs b/src/main.rs index dd86c3d48f..20ad47d17f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,29 +11,37 @@ fn main() { let scheme_name = env::args().nth(1).expect("Usage:\n\tramfs SCHEME_NAME"); redox_daemon::Daemon::new(move |daemon| { - let socket = redox_scheme::Socket::create(&scheme_name).expect("ramfs: failed to create socket"); + let socket = redox_scheme::Socket::::create(&scheme_name) + .expect("ramfs: failed to create socket"); let mut scheme = Scheme::new(scheme_name).expect("ramfs: failed to initialize scheme"); libredox::call::setrens(0, 0).expect("ramfs: failed to enter null namespace"); - daemon.ready().expect("ramfs: failed to mark daemon as ready"); + daemon + .ready() + .expect("ramfs: failed to mark daemon as ready"); loop { - let Some(request) = socket.next_request(SignalBehavior::Restart).expect("ramfs: failed to get next scheme request") else { + let Some(request) = socket + .next_request(SignalBehavior::Restart) + .expect("ramfs: failed to get next scheme request") + else { break; }; match request.kind() { RequestKind::Call(call) => { let response = call.handle_scheme_mut(&mut scheme); - socket.write_responses(&[response], SignalBehavior::Restart).expect("ramfs: failed to write next scheme response"); + socket + .write_responses(&[response], SignalBehavior::Restart) + .expect("ramfs: failed to write next scheme response"); } _ => (), } - } process::exit(0); - }).expect("ramfs: failed to create daemon"); + }) + .expect("ramfs: failed to create daemon"); } diff --git a/src/scheme.rs b/src/scheme.rs index b0069bf77c..2a24c850e1 100644 --- a/src/scheme.rs +++ b/src/scheme.rs @@ -10,18 +10,19 @@ use syscall::error::{ use syscall::flag::{ O_ACCMODE, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY, O_RDWR, O_STAT, O_TRUNC, O_WRONLY, }; +use syscall::schemev2::NewFdFlags; use syscall::{Error, EventFlags, Map, Result, Stat, StatVfs, TimeSpec}; use syscall::{MODE_DIR, MODE_FILE, MODE_PERM, MODE_TYPE, SEEK_CUR, SEEK_END, SEEK_SET}; -use redox_scheme::SchemeMut; +use redox_scheme::{CallerCtx, OpenResult, SchemeMut}; use crate::filesystem::{self, DirEntry, File, FileData, Filesystem}; #[derive(Clone)] struct Handle { inode: usize, - offset: usize, + // TODO: fcntl_flags? opened_as_read: bool, // opened with O_RDONLY or O_RDWR opened_as_write: bool, // opened with O_WRONLY or O_RDWR @@ -167,7 +168,6 @@ impl Scheme { Ok(Handle { inode, - offset: 0, opened_as_read, opened_as_write, current_perm, @@ -176,14 +176,14 @@ impl Scheme { } impl SchemeMut for Scheme { - fn open(&mut self, path: &str, flags: usize, uid: u32, gid: u32) -> Result { + fn xopen(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result { let exists = self.filesystem.resolve(path.as_bytes(), 0, 0).is_ok(); if flags & O_CREAT != 0 && flags & O_EXCL != 0 && exists { return Err(Error::new(EEXIST)); } let handle = if flags & O_CREAT != 0 && exists { - self.open_existing(path.as_bytes(), flags, uid, gid)? + self.open_existing(path.as_bytes(), flags, ctx.uid, ctx.gid)? } else if flags & O_CREAT != 0 { if flags & O_STAT != 0 { return Err(Error::new(EINVAL)); @@ -191,7 +191,7 @@ impl SchemeMut for Scheme { let (parent_dir_inode, new_name) = self.filesystem - .resolve_except_last(path.as_bytes(), uid, gid)?; + .resolve_except_last(path.as_bytes(), ctx.uid, ctx.gid)?; let new_name = new_name.ok_or(Error::new(EINVAL))?; // cannot mkdir / let current_time = filesystem::current_time(); @@ -213,8 +213,8 @@ impl SchemeMut for Scheme { crtime: current_time, ctime: current_time, mtime: current_time, - gid, - uid, + gid: ctx.gid, + uid: ctx.uid, ino: new_inode_number, mode, nlink: 2, // parent entry, "." @@ -234,8 +234,8 @@ impl SchemeMut for Scheme { crtime: current_time, ctime: current_time, mtime: current_time, - gid, - uid, + gid: ctx.gid, + uid: ctx.uid, ino: new_inode_number, mode, nlink: 1, @@ -243,7 +243,7 @@ impl SchemeMut for Scheme { open_handles: 1, } }; - let current_perm = current_perm(&new_inode, uid, gid); + let current_perm = current_perm(&new_inode, ctx.uid, ctx.gid); check_permissions(flags, current_perm)?; self.filesystem.files.insert(new_inode_number, new_inode); @@ -263,13 +263,12 @@ impl SchemeMut for Scheme { Handle { inode: new_inode_number, - offset: 0, opened_as_read: flags & O_ACCMODE == O_RDONLY || flags & O_ACCMODE == O_RDWR, opened_as_write: flags & O_ACCMODE == O_WRONLY || flags & O_ACCMODE == O_RDWR, current_perm, } } else { - self.open_existing(path.as_bytes(), flags, uid, gid)? + self.open_existing(path.as_bytes(), flags, ctx.uid, ctx.gid)? }; let fd = self.next_fd; @@ -277,7 +276,10 @@ impl SchemeMut for Scheme { self.handles.insert(fd, handle); - Ok(fd) + Ok(OpenResult::ThisScheme { + number: fd, + flags: NewFdFlags::POSITIONED, + }) } fn rmdir(&mut self, path: &str, uid: u32, gid: u32) -> Result { self.remove_dentry(path.as_bytes(), uid, gid, true) @@ -298,8 +300,11 @@ impl SchemeMut for Scheme { self.handles.insert(fd, handle); Ok(fd) } - fn read(&mut self, fd: usize, buf: &mut [u8]) -> Result { + fn read(&mut self, fd: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result { let handle = self.handles.get_mut(&fd).ok_or(Error::new(EBADF))?; + let Ok(offset) = usize::try_from(offset) else { + return Ok(0); + }; let file = self .filesystem .files @@ -316,15 +321,13 @@ impl SchemeMut for Scheme { return Err(Error::new(EBADFD)); } - if handle.offset >= bytes.len() { + if offset >= bytes.len() { return Ok(0); } - let bytes_to_read = - cmp::min(bytes.len(), buf.len() + handle.offset) - handle.offset; - buf[..bytes_to_read] - .copy_from_slice(&bytes[handle.offset..handle.offset + bytes_to_read]); - handle.offset += bytes_to_read; - Ok(bytes_to_read) + let src = buf.get(..offset).unwrap_or(&[]); + let to_copy = src.len().min(buf.len()); + buf[..to_copy].copy_from_slice(&bytes[offset..][..to_copy]); + Ok(to_copy) } FileData::Directory(ref entries) => { if file.mode & MODE_TYPE != MODE_DIR { @@ -335,7 +338,7 @@ impl SchemeMut for Scheme { return Err(Error::new(EBADF)); } - let mut bytes_to_skip = handle.offset; + let mut bytes_to_skip = offset; let mut bytes_left_to_read = buf.len(); let mut bytes_read = 0; @@ -361,14 +364,16 @@ impl SchemeMut for Scheme { buf[bytes_read + bytes_to_read - 1] = b'\n'; bytes_left_to_read -= bytes_to_read; bytes_read += bytes_to_read; - handle.offset += bytes_read; } Ok(bytes_read) } } } - fn write(&mut self, fd: usize, buf: &[u8]) -> Result { + fn write(&mut self, fd: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result { let handle = self.handles.get_mut(&fd).ok_or(Error::new(EBADF))?; + let Ok(offset) = usize::try_from(offset) else { + return Ok(0); + }; let file = self .filesystem .files @@ -381,21 +386,20 @@ impl SchemeMut for Scheme { } // if there's a seek hole, fill it with 0 and continue writing. - let end_off = handle.offset.checked_add(buf.len()).ok_or(Error::new(EOVERFLOW))?; + let end_off = offset.checked_add(buf.len()).ok_or(Error::new(EOVERFLOW))?; if end_off > bytes.len() { let additional = end_off - bytes.len(); bytes.try_reserve(additional).or(Err(Error::new(ENOMEM)))?; bytes.resize(end_off, 0u8); } - bytes[handle.offset..][..buf.len()].copy_from_slice(buf); - handle.offset = end_off; + bytes[offset..][..buf.len()].copy_from_slice(buf); Ok(buf.len()) } else { Err(Error::new(EISDIR)) } } - fn seek(&mut self, fd: usize, pos: isize, whence: usize) -> Result { + fn fsize(&mut self, fd: usize) -> Result { let handle = self.handles.get_mut(&fd).ok_or(Error::new(EBADF))?; let file = self .filesystem @@ -403,19 +407,10 @@ impl SchemeMut for Scheme { .get_mut(&handle.inode) .ok_or(Error::new(EBADFD))?; - handle.offset = match whence { - SEEK_SET => cmp::max(0, pos), - SEEK_CUR => cmp::max( - 0, - pos + isize::try_from(handle.offset).or(Err(Error::new(EOVERFLOW)))?, - ), - SEEK_END => cmp::max( - 0, - pos + isize::try_from(file.data.size()).or(Err(Error::new(EOVERFLOW)))?, - ), - _ => return Err(Error::new(EINVAL)), - } as usize; - Ok(handle.offset as isize) + file.data + .size() + .try_into() + .map_err(|_| Error::new(EOVERFLOW)) } fn fchmod(&mut self, fd: usize, mode: u16) -> Result { let handle = self.handles.get_mut(&fd).ok_or(Error::new(EBADF))?; @@ -462,7 +457,13 @@ impl SchemeMut for Scheme { } Err(Error::new(ENOSYS)) } - fn mmap_prep(&mut self, fd: usize, _offset: u64, _size: usize, _flags: syscall::MapFlags) -> Result { + fn mmap_prep( + &mut self, + fd: usize, + _offset: u64, + _size: usize, + _flags: syscall::MapFlags, + ) -> Result { if !self.handles.contains_key(&fd) { return Err(Error::new(EBADF)); }