From a59e7fca9b8e7c379474d771b554bd43c6ae6cfd Mon Sep 17 00:00:00 2001 From: Ibuki Omatsu Date: Thu, 18 Dec 2025 01:45:39 +0000 Subject: [PATCH] refactor: Replace unlink and rmdir with unlinkat. --- Cargo.lock | 14 +++--- Cargo.toml | 8 ++-- src/mount/redox/scheme.rs | 92 +++++++++++++++------------------------ 3 files changed, 46 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc58df6d01..03aef4b344 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -341,9 +341,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" dependencies = [ "bitflags", "libc", @@ -482,9 +482,9 @@ checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717" [[package]] name = "redox-scheme" -version = "0.7.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4da6a0251965958189cdfd5ebb66f99754db4aa165394300aa2b958525d94b64" +checksum = "2cea2668a5932f878a4298a1d7f8950249bbbb77120fb263da252c589152f5ea" dependencies = [ "libredox", "redox_syscall", @@ -492,9 +492,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.18" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5" dependencies = [ "bitflags", ] @@ -507,7 +507,7 @@ checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb" [[package]] name = "redoxfs" -version = "0.8.3" +version = "0.8.4" dependencies = [ "aes", "argon2", diff --git a/Cargo.toml b/Cargo.toml index 48ee49d0cf..1329216543 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "redoxfs" description = "The Redox Filesystem" repository = "https://gitlab.redox-os.org/redox-os/redoxfs" -version = "0.8.3" +version = "0.8.4" license-file = "LICENSE" readme = "README.md" authors = ["Jeremy Soller "] @@ -56,7 +56,7 @@ log = { version = "0.4.14", default-features = false, optional = true } lz4_flex = { version = "0.11", default-features = false, features = ["checked-decode"] } parse-size = { version = "1", optional = true } range-tree = { version = "0.1", optional = true } -redox_syscall = "0.5.15" +redox_syscall = "0.6.0" seahash = { version = "4.1.0", default-features = false } termion = { version = "4", optional = true } uuid = { version = "1.4", default-features = false } @@ -85,9 +85,9 @@ std = [ fuser = { version = "0.14", optional = true } [target.'cfg(target_os = "redox")'.dependencies] -libredox = { version = "0.1.6", features = ["call"], optional = true } +libredox = { version = "0.1.11", features = ["call"], optional = true } redox-path = "0.3.0" -redox-scheme = { version = "0.7.0", optional = true } +redox-scheme = { version = "0.8.3", optional = true } [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] } diff --git a/src/mount/redox/scheme.rs b/src/mount/redox/scheme.rs index 2226c55df5..fb13f47f04 100644 --- a/src/mount/redox/scheme.rs +++ b/src/mount/redox/scheme.rs @@ -432,59 +432,21 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> { self.open_internal(dir_node_ptr, path, flags, ctx) } - fn rmdir(&mut self, url: &str, ctx: &CallerCtx) -> Result<()> { + fn unlinkat(&mut self, dirfd: usize, url: &str, flags: usize, ctx: &CallerCtx) -> Result<()> { let path = url.trim_matches('/'); let uid = ctx.uid; let gid = ctx.gid; - // println!("Rmdir '{}'", path); + let start_ptr = self.files.get(&dirfd).ok_or(Error::new(EBADF))?.node_ptr(); + // println!("Unlinkat '{}' flags: {:X}", path, flags);+ let scheme_name = &self.scheme_name; - self.fs.tx(|tx| { - let mut nodes = Vec::new(); - let Some((child, child_name)) = - Self::path_nodes(scheme_name, tx, TreePtr::root(), path, uid, gid, &mut nodes)? - else { - return Err(Error::new(ENOENT)); - }; - - let Some((parent, _parent_name)) = nodes.last() else { - return Err(Error::new(EPERM)); - }; - - if !parent.data().permission(uid, gid, Node::MODE_WRITE) { - // println!("dir not writable {:o}", parent.1.mode); - return Err(Error::new(EACCES)); - } - - if child.data().is_dir() { - if !child.data().permission(uid, gid, Node::MODE_WRITE) { - // println!("dir not writable {:o}", parent.1.mode); - return Err(Error::new(EACCES)); - } - - tx.remove_node(parent.ptr(), &child_name, Node::MODE_DIR) - .and(Ok(())) - } else { - Err(Error::new(ENOTDIR)) - } - }) - } - - fn unlink(&mut self, url: &str, ctx: &CallerCtx) -> Result<()> { - let path = url.trim_matches('/'); - let uid = ctx.uid; - let gid = ctx.gid; - - // println!("Unlink '{}'", path); - - let scheme_name = &self.scheme_name; let unlink_result = self.fs.tx(|tx| { let mut nodes = Vec::new(); let Some((child, child_name)) = - Self::path_nodes(scheme_name, tx, TreePtr::root(), path, uid, gid, &mut nodes)? + Self::path_nodes(scheme_name, tx, start_ptr, path, uid, gid, &mut nodes)? else { return Err(Error::new(ENOENT)); }; @@ -498,21 +460,35 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> { return Err(Error::new(EACCES)); } - if !child.data().is_dir() { - if child.data().uid() != uid && uid != 0 { - // println!("file not owned by current user {}", parent.1.uid); - return Err(Error::new(EACCES)); - } - - if child.data().is_symlink() { - tx.remove_node(parent.ptr(), &child_name, Node::MODE_SYMLINK) - } else if child.data().is_sock() { - tx.remove_node(parent.ptr(), &child_name, Node::MODE_SOCK) + // Check AT_REMOVEDIR + if flags & syscall::AT_REMOVEDIR == syscall::AT_REMOVEDIR { + // --- rmdir --- + if child.data().is_dir() { + if !child.data().permission(uid, gid, Node::MODE_WRITE) { + return Err(Error::new(EACCES)); + } + tx.remove_node(parent.ptr(), &child_name, Node::MODE_DIR) } else { - tx.remove_node(parent.ptr(), &child_name, Node::MODE_FILE) + Err(Error::new(ENOTDIR)) } } else { - Err(Error::new(EISDIR)) + // --- unlink --- + if !child.data().is_dir() { + if child.data().uid() != uid && uid != 0 { + // println!("file not owned by current user {}", parent.1.uid); + return Err(Error::new(EACCES)); + } + + if child.data().is_symlink() { + tx.remove_node(parent.ptr(), &child_name, Node::MODE_SYMLINK) + } else if child.data().is_sock() { + tx.remove_node(parent.ptr(), &child_name, Node::MODE_SOCK) + } else { + tx.remove_node(parent.ptr(), &child_name, Node::MODE_FILE) + } + } else { + Err(Error::new(EISDIR)) + } } }); @@ -952,9 +928,11 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> { .ok_or(Error::new(EBADF))?; let mut new_fd = usize::MAX; - if let Err(e) = - sendfd_request.obtain_fd(&self.socket, FobtainFdFlags::empty(), Err(&mut new_fd)) - { + if let Err(e) = sendfd_request.obtain_fd( + &self.socket, + FobtainFdFlags::empty(), + std::slice::from_mut(&mut new_fd), + ) { return Err(e); }