diff options
author | Thomas Hurst <tom@hur.st> | 2020-06-30 15:16:31 +0000 |
---|---|---|
committer | Sebastian Thiel <sebastian.thiel@icloud.com> | 2020-07-01 14:21:07 +0800 |
commit | c37ee449f32ed3af0fc222f669ae3f40859d8a39 (patch) | |
tree | 179d59f8c662a564e6af1d1a3a574ffded1ca259 | |
parent | 0ee7e06589baace8fd453e67ac78db5ca3e1553d (diff) |
Fix inode filtering with multiple devices
Inodes are only unique per device, so include device in the lookup.
Also replace a conditional with an additional pattern match, makes it a
bit tidier I think.
-rw-r--r-- | src/inodefilter.rs | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/src/inodefilter.rs b/src/inodefilter.rs index 7182044..ec72d4a 100644 --- a/src/inodefilter.rs +++ b/src/inodefilter.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; #[derive(Debug, Default, Clone)] pub struct InodeFilter { - inner: HashMap<u64, u64>, + inner: HashMap<(u64, u64), u64>, } impl InodeFilter { @@ -10,15 +10,19 @@ impl InodeFilter { pub fn add(&mut self, metadata: &std::fs::Metadata) -> bool { use std::os::unix::fs::MetadataExt; - self.add_inode(metadata.ino(), metadata.nlink()) + self.add_dev_inode((metadata.dev(), metadata.ino()), metadata.nlink()) } #[cfg(windows)] pub fn add(&mut self, metadata: &std::fs::Metadata) -> bool { use std::os::windows::fs::MetadataExt; - if let (Some(inode), Some(nlinks)) = (metadata.file_index(), metadata.number_of_links()) { - self.add_inode(inode, nlinks as u64) + if let (Some(dev), Some(inode), Some(nlinks)) = ( + metadata.volume_serial_number(), + metadata.file_index(), + metadata.number_of_links(), + ) { + self.add_dev_inode((dev as u64, inode), nlinks as u64) } else { true } @@ -29,23 +33,22 @@ impl InodeFilter { true } - pub fn add_inode(&mut self, inode: u64, nlinks: u64) -> bool { + pub fn add_dev_inode(&mut self, dev_inode: (u64, u64), nlinks: u64) -> bool { if nlinks <= 1 { return true; } - match self.inner.get_mut(&inode) { + match self.inner.get_mut(&dev_inode) { + Some(1) => { + self.inner.remove(&dev_inode); + false + } Some(count) => { *count -= 1; - - if *count == 0 { - self.inner.remove(&inode); - } - false } None => { - self.inner.insert(inode, nlinks - 1); + self.inner.insert(dev_inode, nlinks - 1); true } } @@ -60,14 +63,16 @@ mod tests { fn it_filters_inodes() { let mut inodes = InodeFilter::default(); - assert!(inodes.add_inode(1, 2)); - assert!(!inodes.add_inode(1, 2)); + assert!(inodes.add_dev_inode((1, 1), 2)); + assert!(inodes.add_dev_inode((2, 1), 2)); + assert!(!inodes.add_dev_inode((1, 1), 2)); + assert!(!inodes.add_dev_inode((2, 1), 2)); - assert!(inodes.add_inode(1, 3)); - assert!(!inodes.add_inode(1, 3)); - assert!(!inodes.add_inode(1, 3)); + assert!(inodes.add_dev_inode((1, 1), 3)); + assert!(!inodes.add_dev_inode((1, 1), 3)); + assert!(!inodes.add_dev_inode((1, 1), 3)); - assert!(inodes.add_inode(1, 1)); - assert!(inodes.add_inode(1, 1)); + assert!(inodes.add_dev_inode((1, 1), 1)); + assert!(inodes.add_dev_inode((1, 1), 1)); } } |