diff --git a/Cargo.toml b/Cargo.toml index 84333c9..fc54a71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ profiling = ["cpuprofiler"] cpuprofiler = { version = "0.0", optional = true } env_logger = "0.5" failure = "~0.1.2" +fuse = "0.3" getopts = "0.2" log = "0.4" nix = "0.12" @@ -33,10 +34,5 @@ time = "0.1" [build-dependencies] pkg-config = "0.3" -[dependencies.fuse] -# TODO(jmmv): Replace this with 0.4 once released. -git = "https://github.com/zargony/rust-fuse.git" -rev = "bbe450403abd47e719c922f3025edee727ea004b" - [dev-dependencies] tempfile = "3" diff --git a/src/nodes/conv.rs b/src/nodes/conv.rs index a2b5371..2d91820 100644 --- a/src/nodes/conv.rs +++ b/src/nodes/conv.rs @@ -190,6 +190,26 @@ pub fn flags_to_openoptions(flags: u32, allow_writes: bool) -> NodeResult bool { + attr1.ino == attr2.ino + && attr1.kind == attr2.kind + && attr1.nlink == attr2.nlink + && attr1.size == attr2.size + && attr1.blocks == attr2.blocks + && attr1.atime == attr2.atime + && attr1.mtime == attr2.mtime + && attr1.ctime == attr2.ctime + && attr1.crtime == attr2.crtime + && attr1.perm == attr2.perm + && attr1.uid == attr2.uid + && attr1.gid == attr2.gid + && attr1.rdev == attr2.rdev + && attr1.flags == attr2.flags +} + #[cfg(test)] mod tests { use super::*; @@ -293,7 +313,7 @@ mod tests { // modified and may not be queryable, so stub them out. attr.ctime = BAD_TIME; attr.crtime = BAD_TIME; - assert_eq!(&exp_attr, &attr); + assert!(fileattrs_eq(&exp_attr, &attr)); } #[test] @@ -330,7 +350,7 @@ mod tests { // modified and may not be queryable, so stub them out. attr.ctime = BAD_TIME; attr.crtime = BAD_TIME; - assert_eq!(&exp_attr, &attr); + assert!(fileattrs_eq(&exp_attr, &attr)); } #[test] diff --git a/src/nodes/mod.rs b/src/nodes/mod.rs index 35b7caa..2fb82ca 100644 --- a/src/nodes/mod.rs +++ b/src/nodes/mod.rs @@ -227,7 +227,7 @@ pub fn setattr(path: Option<&PathBuf>, attr: &fuse::FileAttr, delta: &AttrDelta) // doing so on a node type basis. Plus, who knows, if the kernel asked us to change the // size of anything other than a file, maybe we have to obey and try to do it. .and(setattr_size(&mut new_attr, path, delta.size)); - if *attr != new_attr { + if !conv::fileattrs_eq(attr, &new_attr) { new_attr.ctime = updated_ctime; } result.and(Ok(new_attr)) diff --git a/src/testutils.rs b/src/testutils.rs index 0a39edd..4548f36 100644 --- a/src/testutils.rs +++ b/src/testutils.rs @@ -16,7 +16,6 @@ use fuse; use nix::{sys, unistd}; -use std::collections::HashMap; use std::fs; use std::os::unix; use std::path::PathBuf; @@ -29,11 +28,13 @@ pub struct AllFileTypes { #[allow(unused)] // Must retain to delay directory deletion. root: TempDir, - /// Collection of test files keyed by their type. + /// Collection of test files. /// - /// Tests should iterate over this map and consume all entries to ensure all possible file types - /// are verified everywhere. Prefer using `match` on the key to achieve this. - pub entries: HashMap, + /// Tests should iterate over this vector and consume all entries to ensure all possible file + /// types are verified everywhere. Prefer using `match` on the key to achieve this. + // TODO(jmmv): This would be better as a HashMap of fuse::FileType to PathBuf, but we cannot do + // so until FileTypes are comparable (which will happen with rust-fuse 0.4). + pub entries: Vec<(fuse::FileType, PathBuf)>, } impl AllFileTypes { @@ -41,41 +42,41 @@ impl AllFileTypes { pub fn new() -> Self { let root = tempdir().unwrap(); - let mut entries: HashMap = HashMap::new(); + let mut entries: Vec<(fuse::FileType, PathBuf)> = vec!(); if unistd::getuid().is_root() { let block_device = root.path().join("block_device"); sys::stat::mknod( &block_device, sys::stat::SFlag::S_IFBLK, sys::stat::Mode::S_IRUSR, 50).unwrap(); - entries.insert(fuse::FileType::BlockDevice, block_device); + entries.push((fuse::FileType::BlockDevice, block_device)); let char_device = root.path().join("char_device"); sys::stat::mknod( &char_device, sys::stat::SFlag::S_IFCHR, sys::stat::Mode::S_IRUSR, 50).unwrap(); - entries.insert(fuse::FileType::CharDevice, char_device); + entries.push((fuse::FileType::CharDevice, char_device)); } else { warn!("Not running as root; cannot create block/char devices"); } let directory = root.path().join("dir"); fs::create_dir(&directory).unwrap(); - entries.insert(fuse::FileType::Directory, directory); + entries.push((fuse::FileType::Directory, directory)); let named_pipe = root.path().join("named_pipe"); unistd::mkfifo(&named_pipe, sys::stat::Mode::S_IRUSR).unwrap(); - entries.insert(fuse::FileType::NamedPipe, named_pipe); + entries.push((fuse::FileType::NamedPipe, named_pipe)); let regular = root.path().join("regular"); drop(fs::File::create(®ular).unwrap()); - entries.insert(fuse::FileType::RegularFile, regular); + entries.push((fuse::FileType::RegularFile, regular)); let socket = root.path().join("socket"); drop(unix::net::UnixListener::bind(&socket).unwrap()); - entries.insert(fuse::FileType::Socket, socket); + entries.push((fuse::FileType::Socket, socket)); let symlink = root.path().join("symlink"); unix::fs::symlink("irrelevant", &symlink).unwrap(); - entries.insert(fuse::FileType::Symlink, symlink); + entries.push((fuse::FileType::Symlink, symlink)); AllFileTypes { root, entries } }