From c101162b64c9dfd73ebe0745dd01d5fbdf2879f6 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Fri, 21 Feb 2025 17:09:49 +0100 Subject: [PATCH] Switch to one-way close message for ramfs. --- Cargo.lock | 28 ++++++++++++------ ramfs/Cargo.toml | 4 +-- ramfs/src/filesystem.rs | 3 +- ramfs/src/main.rs | 10 +++++-- ramfs/src/scheme.rs | 64 +++++++++++++++++++++++++++++------------ 5 files changed, 75 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8fba0566c..13e0bc368a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,7 +123,7 @@ version = "0.1.0" dependencies = [ "libredox", "redox-daemon", - "redox-scheme", + "redox-scheme 0.2.4", "redox_syscall", ] @@ -167,7 +167,7 @@ dependencies = [ "indexmap", "libredox", "redox-daemon", - "redox-scheme", + "redox-scheme 0.4.0", "redox_syscall", "slab", ] @@ -197,7 +197,7 @@ dependencies = [ "rand_core", "raw-cpuid", "redox-daemon", - "redox-scheme", + "redox-scheme 0.2.4", "redox_syscall", "sha2", ] @@ -232,10 +232,20 @@ dependencies = [ ] [[package]] -name = "redox_syscall" -version = "0.5.8" +name = "redox-scheme" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "a28d292981c8f3338cb772b6024b08bcc597d0dd81020de17080a9a7b470ebb2" +dependencies = [ + "libredox", + "redox_syscall", +] + +[[package]] +name = "redox_syscall" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" dependencies = [ "bitflags", ] @@ -280,9 +290,9 @@ checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] name = "zerocopy" @@ -311,6 +321,6 @@ version = "0.1.0" dependencies = [ "libredox", "redox-daemon", - "redox-scheme", + "redox-scheme 0.2.4", "redox_syscall", ] diff --git a/ramfs/Cargo.toml b/ramfs/Cargo.toml index b720c682ec..d881534a93 100644 --- a/ramfs/Cargo.toml +++ b/ramfs/Cargo.toml @@ -10,8 +10,8 @@ description = "In-memory filesystem for Redox, which is useful for early logging [dependencies] redox-daemon = "0.1.2" -redox_syscall = "0.5.3" -redox-scheme = "0.2.2" +redox_syscall = "0.5.9" +redox-scheme = "0.4" libredox = "0.1.3" indexmap = "2.5.0" slab = "0.4.9" diff --git a/ramfs/src/filesystem.rs b/ramfs/src/filesystem.rs index 2848b4c7b7..73c9fb4989 100644 --- a/ramfs/src/filesystem.rs +++ b/ramfs/src/filesystem.rs @@ -140,7 +140,8 @@ impl Filesystem { uid: u32, gid: u32, ) -> Result<(usize, Option<&'a str>)> { - let mut parts = path_components_iter(path_bytes.trim_start_matches('/')).collect::>(); + let mut parts = + path_components_iter(path_bytes.trim_start_matches('/')).collect::>(); let last = if parts.len() >= 1 { Some(parts.pop().unwrap()) diff --git a/ramfs/src/main.rs b/ramfs/src/main.rs index b95ec68d9a..e27914822d 100644 --- a/ramfs/src/main.rs +++ b/ramfs/src/main.rs @@ -3,7 +3,7 @@ use std::{env, process}; mod filesystem; mod scheme; -use redox_scheme::{RequestKind, SignalBehavior, V2}; +use redox_scheme::{RequestKind, SignalBehavior}; use self::scheme::Scheme; @@ -11,7 +11,8 @@ 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"); @@ -30,12 +31,15 @@ fn main() { }; match request.kind() { RequestKind::Call(call) => { - let response = call.handle_scheme_mut(&mut scheme); + let response = call.handle_scheme(&mut scheme); socket .write_responses(&[response], SignalBehavior::Restart) .expect("ramfs: failed to write next scheme response"); } + RequestKind::OnClose { id } => { + scheme.on_close(id); + } _ => (), } } diff --git a/ramfs/src/scheme.rs b/ramfs/src/scheme.rs index 0318c009b9..cd0a9b39d4 100644 --- a/ramfs/src/scheme.rs +++ b/ramfs/src/scheme.rs @@ -16,7 +16,7 @@ use syscall::schemev2::NewFdFlags; use syscall::{Error, EventFlags, Result, Stat, StatVfs, TimeSpec, ENOENT}; use syscall::{MODE_DIR, MODE_FILE, MODE_PERM, MODE_TYPE}; -use redox_scheme::{CallerCtx, OpenResult, SchemeMut}; +use redox_scheme::{CallerCtx, OpenResult, Scheme as SchemeTrait}; use crate::filesystem::{self, File, FileData, Filesystem, Inode}; @@ -60,7 +60,9 @@ impl Scheme { return Err(Error::new(ENOTDIR)); }; - let Inode(entry_inode) = dentries.shift_remove(name_to_delete).ok_or(Error::new(ENOENT))?; + let Inode(entry_inode) = dentries + .shift_remove(name_to_delete) + .ok_or(Error::new(ENOENT))?; if let Some(File { data: FileData::Directory(ref data), @@ -149,7 +151,7 @@ impl Scheme { } } -impl SchemeMut for Scheme { +impl SchemeTrait for Scheme { fn xopen(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result { let exists = self.filesystem.resolve(path, 0, 0).is_ok(); if flags & O_CREAT != 0 && flags & O_EXCL != 0 && exists { @@ -163,9 +165,9 @@ impl SchemeMut for Scheme { return Err(Error::new(EINVAL)); } - let (parent_dir_inode, new_name) = - self.filesystem - .resolve_except_last(path, ctx.uid, ctx.gid)?; + let (parent_dir_inode, new_name) = self + .filesystem + .resolve_except_last(path, ctx.uid, ctx.gid)?; let new_name = new_name.ok_or(Error::new(EINVAL))?; // cannot mkdir / let current_time = filesystem::current_time(); @@ -238,7 +240,10 @@ impl SchemeMut for Scheme { } else { self.open_existing(path, flags, ctx.uid, ctx.gid)?.0 }; - Ok(OpenResult::ThisScheme { number: inode, flags: NewFdFlags::POSITIONED }) + Ok(OpenResult::ThisScheme { + number: inode, + flags: NewFdFlags::POSITIONED, + }) } fn rmdir(&mut self, path: &str, uid: u32, gid: u32) -> Result { self.remove_dentry(path, uid, gid, true) @@ -249,7 +254,13 @@ impl SchemeMut for Scheme { fn dup(&mut self, old_inode: usize, _buf: &[u8]) -> Result { Ok(old_inode) } - fn read(&mut self, inode: usize, buf: &mut [u8], offset: u64, fcntl_flags: u32) -> Result { + fn read( + &mut self, + inode: usize, + buf: &mut [u8], + offset: u64, + fcntl_flags: u32, + ) -> Result { let Ok(offset) = usize::try_from(offset) else { return Ok(0); }; @@ -277,7 +288,12 @@ impl SchemeMut for Scheme { FileData::Directory(_) => return Err(Error::new(EISDIR)), } } - fn getdents<'buf>(&mut self, inode: usize, mut buf: DirentBuf<&'buf mut [u8]>, opaque_offset: u64) -> Result> { + fn getdents<'buf>( + &mut self, + inode: usize, + mut buf: DirentBuf<&'buf mut [u8]>, + opaque_offset: u64, + ) -> Result> { let Ok(offset) = usize::try_from(opaque_offset) else { return Ok(buf); }; @@ -369,7 +385,13 @@ impl SchemeMut for Scheme { // TODO? Err(Error::new(ENOSYS)) } - fn mmap_prep(&mut self, _inode: usize, _offset: u64, _size: usize, _flags: syscall::MapFlags) -> Result { + fn mmap_prep( + &mut self, + _inode: usize, + _offset: u64, + _size: usize, + _flags: syscall::MapFlags, + ) -> Result { // TODO Err(Error::new(ENOSYS)) } @@ -393,7 +415,10 @@ impl SchemeMut for Scheme { return Err(Error::new(EBADFD)); }; // TODO: error handling? - let (name, _) = dir.iter().find(|(_name, inode)| inode.0 == current_inode).ok_or(Error::new(ENOENT))?; + let (name, _) = dir + .iter() + .find(|(_name, inode)| inode.0 == current_inode) + .ok_or(Error::new(ENOENT))?; chain.push(&**name); current_inode = current_info.parent.0; @@ -401,7 +426,9 @@ impl SchemeMut for Scheme { } let mut cursor = Cursor::new(buf); - for component in iter::once(self.scheme_name.trim_start_matches('/')).chain(chain.iter().copied().rev()) { + for component in + iter::once(self.scheme_name.trim_start_matches('/')).chain(chain.iter().copied().rev()) + { use std::io::Write; write!(cursor, "/{component}").unwrap(); @@ -524,19 +551,18 @@ impl SchemeMut for Scheme { Ok(0) } - fn close(&mut self, inode: usize) -> Result { - let inode_info = self - .filesystem - .files - .get_mut(&inode) - .ok_or(Error::new(EIO))?; +} +impl Scheme { + pub fn on_close(&mut self, inode: usize) { + let Some(inode_info) = self.filesystem.files.get_mut(&inode) else { + return; + }; inode_info.open_handles -= 1; if inode_info.nlink == 0 && inode_info.open_handles == 0 { self.filesystem.files.remove(&inode); } - Ok(0) } } pub fn current_perm(file: &crate::filesystem::File, uid: u32, gid: u32) -> u8 {