Implement fail-closed ignored workspace routing

This commit is contained in:
ms2k 2026-07-16 13:03:04 +09:00
commit 95104fa4e7

View file

@ -0,0 +1,163 @@
diff --git a/src/lib.rs b/src/lib.rs
index 063f9a0..5b91dae 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -40,6 +40,7 @@ pub use crate::ll::flags::fattr_flags::FattrFlags;
pub use crate::ll::flags::fopen_flags::FopenFlags;
pub use crate::ll::flags::init_flags::InitFlags;
pub use crate::ll::flags::ioctl_flags::IoctlFlags;
+pub use crate::ll::flags::lock_flags::LockFlags;
pub use crate::ll::flags::poll_flags::PollFlags;
pub use crate::ll::flags::write_flags::WriteFlags;
pub use crate::ll::fuse_abi::consts;
@@ -867,11 +868,12 @@ pub trait Filesystem {
end: u64,
typ: i32,
pid: u32,
+ flags: LockFlags,
reply: ReplyLock,
) {
warn!(
"[Not Implemented] getlk(ino: {ino:#x?}, fh: {fh}, lock_owner: {lock_owner}, \
- start: {start}, end: {end}, typ: {typ}, pid: {pid})"
+ start: {start}, end: {end}, typ: {typ}, pid: {pid}, flags: {flags:?})"
);
reply.error(Errno::ENOSYS);
}
@@ -894,11 +896,12 @@ pub trait Filesystem {
typ: i32,
pid: u32,
sleep: bool,
+ flags: LockFlags,
reply: ReplyEmpty,
) {
warn!(
"[Not Implemented] setlk(ino: {ino:#x?}, fh: {fh}, lock_owner: {lock_owner}, \
- start: {start}, end: {end}, typ: {typ}, pid: {pid}, sleep: {sleep})"
+ start: {start}, end: {end}, typ: {typ}, pid: {pid}, sleep: {sleep}, flags: {flags:?})"
);
reply.error(Errno::ENOSYS);
}
diff --git a/src/ll/flags/lock_flags.rs b/src/ll/flags/lock_flags.rs
new file mode 100644
index 0000000..6f797d4
--- /dev/null
+++ b/src/ll/flags/lock_flags.rs
@@ -0,0 +1,10 @@
+use bitflags::bitflags;
+
+bitflags! {
+ /// Flags describing a FUSE file-lock request.
+ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+ pub struct LockFlags: u32 {
+ /// The request is a BSD `flock` rather than a POSIX record lock.
+ const FUSE_LK_FLOCK = 1 << 0;
+ }
+}
diff --git a/src/ll/flags/mod.rs b/src/ll/flags/mod.rs
index d9fbf92..54e4dc0 100644
--- a/src/ll/flags/mod.rs
+++ b/src/ll/flags/mod.rs
@@ -8,6 +8,7 @@ pub(crate) mod getattr_flags;
pub(crate) mod getattr_flags;
pub(crate) mod init_flags;
pub(crate) mod ioctl_flags;
+pub(crate) mod lock_flags;
pub(crate) mod poll_flags;
pub(crate) mod read_flags;
pub(crate) mod release_flags;
diff --git a/src/ll/request.rs b/src/ll/request.rs
index f572cc2..da80ff8 100644
--- a/src/ll/request.rs
+++ b/src/ll/request.rs
@@ -264,6 +264,7 @@ mod operation {
use crate::ll::flags::fsync_flags::FsyncFlags;
use crate::ll::flags::getattr_flags::GetattrFlags;
use crate::ll::flags::init_flags::InitFlags;
+ use crate::ll::flags::lock_flags::LockFlags;
use crate::ll::flags::read_flags::ReadFlags;
use crate::ll::flags::release_flags::ReleaseFlags;
use crate::ll::request::FileHandle;
@@ -1170,6 +1171,9 @@ mod operation {
pub(crate) fn lock_owner(&self) -> LockOwner {
LockOwner(self.arg.owner)
}
+ pub(crate) fn lock_flags(&self) -> LockFlags {
+ LockFlags::from_bits_retain(self.arg.lk_flags)
+ }
}
/// Acquire, modify or release a POSIX file lock.
@@ -1200,6 +1204,9 @@ mod operation {
pub(crate) fn lock_owner(&self) -> LockOwner {
LockOwner(self.arg.owner)
}
+ pub(crate) fn lock_flags(&self) -> LockFlags {
+ LockFlags::from_bits_retain(self.arg.lk_flags)
+ }
/// If true, block until the lock can be acquired (SETLKW).
/// If false, return immediately if the lock cannot be acquired (SETLK).
pub(crate) fn sleep(&self) -> bool {
@@ -2219,6 +2226,8 @@ mod tests {
mod tests {
use std::ffi::OsStr;
+ use crate::LockFlags;
+ use crate::ll::fuse_abi::{consts, fuse_opcode};
use crate::ll::request::*;
use crate::ll::test::AlignedData;
@@ -2314,6 +2323,33 @@ mod tests {
}
}
+ #[test]
+ fn lock_request_preserves_kind_flags() {
+ let mut bytes = AlignedData([0_u8; 88]);
+ bytes[0..4].copy_from_slice(&88_u32.to_ne_bytes());
+ bytes[4..8].copy_from_slice(&(fuse_opcode::FUSE_GETLK as u32).to_ne_bytes());
+ bytes[40..48].copy_from_slice(&11_u64.to_ne_bytes());
+ bytes[48..56].copy_from_slice(&22_u64.to_ne_bytes());
+ bytes[56..64].copy_from_slice(&3_u64.to_ne_bytes());
+ bytes[64..72].copy_from_slice(&8_u64.to_ne_bytes());
+ bytes[72..76].copy_from_slice(&libc::F_WRLCK.to_ne_bytes());
+ bytes[76..80].copy_from_slice(&44_u32.to_ne_bytes());
+ bytes[80..84].copy_from_slice(&consts::FUSE_LK_FLOCK.to_ne_bytes());
+
+ match AnyRequest::try_from(&bytes[..])
+ .unwrap()
+ .operation()
+ .unwrap()
+ {
+ Operation::GetLk(lock) => {
+ assert_eq!(lock.file_handle(), FileHandle(11));
+ assert_eq!(lock.lock_owner(), LockOwner(22));
+ assert_eq!(lock.lock_flags(), LockFlags::FUSE_LK_FLOCK);
+ }
+ _ => panic!("unexpected request operation"),
+ }
+ }
+
#[test]
fn mknod() {
let req = AnyRequest::try_from(&MKNOD_REQUEST[..]).unwrap();
diff --git a/src/request.rs b/src/request.rs
index 82cddf5..6bb5566 100644
--- a/src/request.rs
+++ b/src/request.rs
@@ -395,6 +395,7 @@ impl AnyRequest<'_> {
x.lock().range.1,
x.lock().typ,
x.lock().pid,
+ x.lock_flags(),
self.reply(),
);
}
@@ -409,6 +410,7 @@ impl AnyRequest<'_> {
x.lock().typ,
x.lock().pid,
x.sleep(),
+ x.lock_flags(),
self.reply(),
);
}