[Bug 262293] sysutils/archivemount gives errors after mounting the 13.0 release tarballs

From: <bugzilla-noreply_at_freebsd.org>
Date: Thu, 03 Mar 2022 08:29:06 UTC

--- Comment #1 from Bill Blake <billblake2018@gmail.com> ---
In an attempt to further isolate the bug, I tried using a different package,
fuse-zip, with a zipped up /usr/ports.  And--got the same bug.  No, the problem
isn't in fuse itself, it's two separate bugs, one in fuse-zip and one in
archivemount.  In both cases, the link count for directories (and for
archivemount at least, files), is computed incorrectly.  For archivemount the
link count is always returned as zero.  For fuse-zip, the "link count" is
actually the number of entries in the directory.

Either way, the incorrect link count confuses the directory traversal code of
fts.c because it uses that count to optimize away unnecessary stat calls.  And
this ultimately led du to generate the error messages that I saw.  It also
breaks find but, apparently, not diff -r.  Be that as it may, this is a serious
bug and needs some sort of repair.  (Ditto for the bug in fuse-zip, though
that's for a different PR.)

And here is an awful hack to fix the bug.  THIS IS NOT A CORRECT FIX.  First,
it always sets the link count to 1 for non-directories.  Second, it is probably
unnecessarily inefficient.  But it suffices to set the link count for
directories correctly, which makes du and find work.  This patches

@@ -1545,6 +1545,20 @@
        stbuf->st_blocks  = (stbuf->st_size + 511) / 512;
        stbuf->st_blksize = 4096;

+       if (S_ISDIR(stbuf->st_mode)) {
+               stbuf->st_nlink = 2;
+               NODE *child, *tmp;
+               HASH_ITER(hh, node->child, child, tmp) {
+                       const struct stat *chbuf =
+                       if (S_ISDIR(chbuf->st_mode)) {
+                               ++stbuf->st_nlink;
+                       }
+               }
+       } else {
+               stbuf->st_nlink = 1;
+       }

You are receiving this mail because:
You are the assignee for the bug.