refactor: Replace unlink and rmdir with unlinkat.

This commit is contained in:
Ibuki Omatsu
2025-12-18 01:45:39 +00:00
committed by Jeremy Soller
parent c0777c08ac
commit a59e7fca9b
3 changed files with 46 additions and 68 deletions
Generated
+7 -7
View File
@@ -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",
+4 -4
View File
@@ -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 <jackpot51@gmail.com>"]
@@ -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)'] }
+35 -57
View File
@@ -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);
}