Skip to content

Commit 10fab14

Browse files
committed
feat: assert links equal
1 parent 9e7ce54 commit 10fab14

1 file changed

Lines changed: 33 additions & 7 deletions

File tree

src/hardlink/hardlink_list.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,26 @@ pub struct SizeConflictError<Size> {
7373
pub detected: Size,
7474
}
7575

76+
/// Error that occurs when a different [`nlink`][nlink] was detected for the same [`ino`][ino].
77+
///
78+
/// <!-- Should have been `std::os::unix::fs::MetadataExt::ino` but it would error on Windows -->
79+
/// [nlink]: https://doc.rust-lang.org/std/os/unix/fs/trait.MetadataExt.html#tymethod.nlink
80+
/// [ino]: https://doc.rust-lang.org/std/os/unix/fs/trait.MetadataExt.html#tymethod.ino
81+
#[derive(Debug, Display, Error)]
82+
#[display("Number of links of inode {ino} changed from {recorded:?} to {detected:?}")]
83+
pub struct NumberOfLinksConflictError {
84+
pub ino: InodeNumber,
85+
pub recorded: u64,
86+
pub detected: u64,
87+
}
88+
7689
/// Error that occurs when it fails to add an item to [`HardlinkList`].
7790
#[derive(Debug, Display, Error)]
7891
#[display(bound(Size: Debug))]
7992
#[non_exhaustive]
8093
pub enum AddError<Size> {
8194
SizeConflict(SizeConflictError<Size>),
95+
NumberOfLinksConflict(NumberOfLinksConflictError),
8296
}
8397

8498
impl<Size> HardlinkList<Size>
@@ -94,25 +108,37 @@ where
94108
links: u64,
95109
path: &Path,
96110
) -> Result<(), AddError<Size>> {
97-
let mut size_assertion = Ok(());
111+
let mut assertions = Ok(());
98112
self.0
99113
.entry(ino)
100114
.and_modify(|recorded| {
101-
if size == recorded.size {
102-
recorded.paths.add(path.to_path_buf());
103-
} else {
104-
size_assertion = Err(SizeConflictError {
115+
if size != recorded.size {
116+
assertions = Err(AddError::SizeConflict(SizeConflictError {
105117
ino,
106118
recorded: recorded.size,
107119
detected: size,
108-
});
120+
}));
121+
return;
109122
}
123+
124+
if links != recorded.links {
125+
assertions = Err(AddError::NumberOfLinksConflict(
126+
NumberOfLinksConflictError {
127+
ino,
128+
recorded: recorded.links,
129+
detected: links,
130+
},
131+
));
132+
return;
133+
}
134+
135+
recorded.paths.add(path.to_path_buf());
110136
})
111137
.or_insert_with(|| {
112138
let paths = path.to_path_buf().pipe(LinkPathList::single);
113139
Value { size, links, paths }
114140
});
115-
size_assertion.map_err(AddError::SizeConflict)
141+
assertions
116142
}
117143
}
118144

0 commit comments

Comments
 (0)