From 479f0913311ce5d853acdbabb21ce4a3edee915c Mon Sep 17 00:00:00 2001 From: Richard Lawrence Date: Sat, 6 Sep 2025 16:56:00 -0500 Subject: [PATCH 1/3] Revised Init unit test. Fixed a bug where the unit test for `Init` in `ll::request` would fail for certain abi versions (e.g., `abi-7-36`). --- src/ll/request.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/ll/request.rs b/src/ll/request.rs index b560a29f..3808ef0d 100644 --- a/src/ll/request.rs +++ b/src/ll/request.rs @@ -2175,8 +2175,9 @@ mod tests { use super::*; use std::ffi::OsStr; - #[cfg(target_endian = "big")] + #[cfg(all(target_endian = "big", not(feature = "abi-7-36")))] const INIT_REQUEST: AlignedData<[u8; 56]> = AlignedData([ + // decimal 56 == hex 0x38 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1a, // len, opcode 0xde, 0xad, 0xbe, 0xef, 0xba, 0xad, 0xd0, 0x0d, // unique 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, // nodeid @@ -2186,8 +2187,9 @@ mod tests { 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // max_readahead, flags ]); - #[cfg(target_endian = "little")] + #[cfg(all(target_endian = "little", not(feature = "abi-7-36")))] const INIT_REQUEST: AlignedData<[u8; 56]> = AlignedData([ + // decimal 56 == hex 0x38 0x38, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, // len, opcode 0x0d, 0xf0, 0xad, 0xba, 0xef, 0xbe, 0xad, 0xde, // unique 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, // nodeid @@ -2197,6 +2199,40 @@ mod tests { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // max_readahead, flags ]); + #[cfg(all(target_endian = "big", feature = "abi-7-36"))] + const INIT_REQUEST: AlignedData<[u8; 104]> = AlignedData([ + // decimal 104 == hex 0x68 + 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x1a, // len, opcode + 0xde, 0xad, 0xbe, 0xef, 0xba, 0xad, 0xd0, 0x0d, // unique + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, // nodeid + 0xc0, 0x01, 0xd0, 0x0d, 0xc0, 0x01, 0xca, 0xfe, // uid, gid + 0xc0, 0xde, 0xba, 0x5e, 0x00, 0x00, 0x00, 0x00, // pid, padding + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, // major, minor + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // max_readahead, flags + 0x00, 0x00, 0x00, 0x00, // flags2 //TODO: nonzero data + 0x00, 0x00, 0x00, 0x00, // eleven unused fields + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]); + + #[cfg(all(target_endian = "little", feature = "abi-7-36"))] + const INIT_REQUEST: AlignedData<[u8; 104]> = AlignedData([ + // decimal 104 == hex 0x68 + 0x68, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, // len, opcode + 0x0d, 0xf0, 0xad, 0xba, 0xef, 0xbe, 0xad, 0xde, // unique + 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, // nodeid + 0x0d, 0xd0, 0x01, 0xc0, 0xfe, 0xca, 0x01, 0xc0, // uid, gid + 0x5e, 0xba, 0xde, 0xc0, 0x00, 0x00, 0x00, 0x00, // pid, padding + 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // major, minor + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // max_readahead, flags + 0x00, 0x00, 0x00, 0x00, // flags2 //TODO: nonzero data + 0x00, 0x00, 0x00, 0x00, // eleven unused fields + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]); + #[cfg(target_endian = "big")] const MKNOD_REQUEST: AlignedData<[u8; 56]> = [ 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x08, // len, opcode @@ -2231,7 +2267,10 @@ mod tests { #[test] fn short_read() { match AnyRequest::try_from(&INIT_REQUEST[..48]) { + #[cfg(not(feature = "abi-7-36"))] Err(RequestError::ShortRead(48, 56)) => (), + #[cfg(feature = "abi-7-36")] + Err(RequestError::ShortRead(48, 104)) => (), _ => panic!("Unexpected request parsing result"), } } @@ -2239,7 +2278,10 @@ mod tests { #[test] fn init() { let req = AnyRequest::try_from(&INIT_REQUEST[..]).unwrap(); + #[cfg(not(feature = "abi-7-36"))] assert_eq!(req.header.len, 56); + #[cfg(feature = "abi-7-36")] + assert_eq!(req.header.len, 104); assert_eq!(req.header.opcode, 26); assert_eq!(req.unique(), RequestId(0xdead_beef_baad_f00d)); assert_eq!(req.nodeid(), INodeNo(0x1122_3344_5566_7788)); From bd0d7b794ab5cec713252d34481d6b0798af9498 Mon Sep 17 00:00:00 2001 From: Richard Lawrence Date: Sat, 6 Sep 2025 16:58:38 -0500 Subject: [PATCH 2/3] Cross-platform documentation. Fixed a bug where the documentation was missing from the `NO_XATTR` constant on a non-linux OS. Using a macro to prevent duplication. --- src/ll/mod.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ll/mod.rs b/src/ll/mod.rs index 14057640..6545288b 100644 --- a/src/ll/mod.rs +++ b/src/ll/mod.rs @@ -35,6 +35,10 @@ macro_rules! errno { }; } +macro_rules! no_xattr_doc { + () => {"Use this as an error return from getxattr/removexattr to indicate that the xattr doesn't exist. This resolves to the appropriate platform-specific error code."} +} + /// Represents an error code to be returned to the caller #[derive(Debug)] pub struct Errno(pub NonZeroI32); @@ -213,14 +217,14 @@ impl Errno { /// No data available #[cfg(target_os = "linux")] pub const ENODATA: Errno = errno!(libc::ENODATA); + #[doc = no_xattr_doc!()] + #[cfg(target_os = "linux")] + pub const NO_XATTR: Errno = Self::ENODATA; + /// Attribute not found #[cfg(not(target_os = "linux"))] pub const ENOATTR: Errno = errno!(libc::ENOATTR); - - /// Use this as an error return from getxattr/removexattr to indicate that the xattr doesn't - /// exist. This resolves to the appropriate platform specific error code. - #[cfg(target_os = "linux")] - pub const NO_XATTR: Errno = Self::ENODATA; + #[doc = no_xattr_doc!()] #[cfg(not(target_os = "linux"))] pub const NO_XATTR: Errno = Self::ENOATTR; From 0ed062a3e53331d7aeefd66e834eacd71fd0c135 Mon Sep 17 00:00:00 2001 From: Richard Lawrence Date: Sat, 6 Sep 2025 16:59:46 -0500 Subject: [PATCH 3/3] Big literal. Clippy says it's better to write long constants with underscore separators: [https://rust-lang.github.io/rust-clippy/rust-1.51.0/index.html#unreadable_literal] --- examples/passthrough.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/passthrough.rs b/examples/passthrough.rs index 299c0060..bd865c3c 100644 --- a/examples/passthrough.rs +++ b/examples/passthrough.rs @@ -112,7 +112,7 @@ impl PassthroughFs { let passthrough_file_attr = FileAttr { ino: 2, - size: 123456, + size: 123_456, blocks: 1, atime: UNIX_EPOCH, // 1970-01-01 00:00:00 mtime: UNIX_EPOCH,