In some cases, fuse-overlayfs will report the inode number from the lowest layer instead of the upper layer.
In the test case below:
bin/arch and bin/busybox are taken from layer lower1 as it is the uppermost layer having these file.
in the layer lower1, bin/arch is a symlink to busybox
in the layer lower2, bin/arch is a hard link with bin/busybox
fuse-overlayfs uses lower1 layer in merged/ but reports the inode numbers from lower2
as in lower2, arch and busybox are the same inode (they are hard linked), fuse-overlayfs reports the same inode number for merged/bin/arch and merged/bin/busybox despite them being different file type (a symlink and a regular file)
This confuses code that uses the inode number to detect hardlinks.
I've tried to debug it a bit, and found that the issue comes from this:
When readdirplus is called on the bin directory, all entries are correctly read.
But as they are too many files in the directory to be reported in a single readdirplus call, there are another readdir (instead of readdirplus) to retrieve the remaining files.
readdirplus will populate entries correctly, but readdir will not increase node->ino->lookups
When releasedir is called, entries retrieved by readdir are released. This includes arch and busybox files.
When lookup is called, arch and busybox entries are not loaded and do_lookup_file will load them. But the retrieved inode is the one from the lowest layer having the file (lower2 in the test).
Hi,
Description
In some cases, fuse-overlayfs will report the inode number from the lowest layer instead of the upper layer.
In the test case below:
bin/arch
andbin/busybox
are taken from layerlower1
as it is the uppermost layer having these file.lower1
,bin/arch
is a symlink tobusybox
lower2
,bin/arch
is a hard link withbin/busybox
lower1
layer inmerged/
but reports the inode numbers fromlower2
lower2
,arch
andbusybox
are the same inode (they are hard linked), fuse-overlayfs reports the same inode number formerged/bin/arch
andmerged/bin/busybox
despite them being different file type (a symlink and a regular file)This confuses code that uses the inode number to detect hardlinks.
I've discovered this while executing buildkitd's
TestDiffLazyBlobMerge
test with fuse-overlayfs snapshotter.I guess this issue is too specific and won't be fixed, but this can serve as documentation about it.
Test case
Output:
Expected output:
I've tried to debug it a bit, and found that the issue comes from this:
readdirplus
is called on thebin
directory, all entries are correctly read.readdirplus
call, there are anotherreaddir
(instead ofreaddirplus
) to retrieve the remaining files.readdirplus
will populate entries correctly, butreaddir
will not increasenode->ino->lookups
releasedir
is called, entries retrieved byreaddir
are released. This includesarch
andbusybox
files.arch
andbusybox
entries are not loaded anddo_lookup_file
will load them. But the retrieved inode is the one from the lowest layer having the file (lower2
in the test).fuse-overlayfs in debug will print this:
I've added debug logs to find this. Using the code from https://github.com/amurzeau/fuse-overlayfs/tree/debug-bad-inodes, here is the result (fuse-overlayfs is run in debug mode to get its output):