Skip to content

Commit 0dcf186

Browse files
fs: track all files as potential hardlinks
While pairing with Timothée we discovered that the examples don't work on his system because the `cfsctl create-image` on the inside of the container build fails to detect all hardlinks. The difference is that his podman storage driver is using fuse-overlayfs, which doesn't always accurately report `st_nlink`. The behaviour is odd: when observing the hardlink via the first filename it will report a given `(st_dev, st_ino)` with `st_nlink` of 1 but when inspecting it via the second filename it will report the same `(st_dev, st_ino)` but with `st_nlink` of 2 this time. Let's just be "less clever" and store all non-directory inodes in our hashtable as potential hardlinks. See containers/fuse-overlayfs#435 Signed-off-by: Allison Karlitskaya <[email protected]> Co-Authored-By: Timothée Ravier <[email protected]>
1 parent 78f37ea commit 0dcf186

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

src/fs.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -237,15 +237,16 @@ impl FilesystemReader<'_> {
237237

238238
let (buf, stat) = FilesystemReader::stat(&fd, ifmt)?;
239239

240-
if let Some(leafref) = self.inodes.get(&(buf.st_dev, buf.st_ino)) {
240+
// NB: We could check `st_nlink > 1` to find out if we should track a file as a potential
241+
// hardlink or not, but some filesystems (like fuse-overlayfs) can report this incorrectly.
242+
// Track all files. https://github.com/containers/fuse-overlayfs/issues/435
243+
let key = (buf.st_dev, buf.st_ino);
244+
if let Some(leafref) = self.inodes.get(&key) {
241245
Ok(Rc::clone(leafref))
242246
} else {
243247
let content = self.read_leaf_content(fd, buf)?;
244248
let leaf = Rc::new(Leaf { stat, content });
245-
if buf.st_nlink > 1 {
246-
self.inodes
247-
.insert((buf.st_dev, buf.st_ino), Rc::clone(&leaf));
248-
}
249+
self.inodes.insert(key, Rc::clone(&leaf));
249250
Ok(leaf)
250251
}
251252
}

0 commit comments

Comments
 (0)