Subject: lib/8688: directory link count hack in fts is bogus
To: None <gnats-bugs@gnats.netbsd.org>
From: Johan Danielsson <joda@pdc.kth.se>
List: netbsd-bugs
Date: 10/26/1999 02:18:41
>Number:         8688
>Category:       lib
>Synopsis:       directory link count hack in fts is bogus
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people (Library Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Oct 26 02:18:00 1999
>Last-Modified:
>Originator:     Johan Danielsson
>Organization:
>Release:        1999-10-25
>Environment:
	<machine, os, target, libraries (multiple lines)>
System: NetBSD blubb.pdc.kth.se 1.4L NetBSD 1.4L (BLUBB) #15: Tue Oct 19 18:13:13 CEST 1999 joda@blubb.pdc.kth.se:/usr/misc/src/netbsd/anoncvs/syssrc/sys/arch/i386/compile/BLUBB i386


>Description:

FTS does the following to figure out if it has to stat a file:

        /*
         * Nlinks is the number of possible entries of type directory in the
         * directory if we're cheating on stat calls, 0 if we're not doing
         * any stat calls at all, -1 if we're doing stats on everything.
         */
        if (type == BNAMES) {
                nlinks = 0;
                nostat = 1;
        } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
                nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
                nostat = 1;
        } else {
                nlinks = -1;
                nostat = 0;
        }

That is, if NOSTAT is set, it will only stat files till it has found
nlinks sub-directories to this directory. But this heuristic is only
valid for local filesystems (actually only known local filesystems).
AFS is an example of a network filesystem that doesn't follow this
convention (mount-points show up as directories, but isn't counted in
the parent directory link count).

>How-To-Repeat:

# df -k .
Filesystem  1K-blocks     Used    Avail Capacity  Mounted on
arla         11096760        0 11096760     0%    /afs
# ls -ld
drwxr-xr-x  3 joda  usr  2048 Oct 26 11:11 .
# ls -l
total 32
drwxr-xr-x   2 joda  usr     2048 Oct 26 11:11 a
drwxr-xr-x  54 joda  wheel  14336 Oct 26 11:11 b
# find .
.
./a
./b

`a' is an empty directory, but `b' is not (as can be seen from the
link count); find should decend into b.

>Fix:

Don't know really. You could do statfs for each file and see if it's a
filesystem with a known behaviour (you only have to do this when
traversing mount points, or following symlinks).
>Audit-Trail:
>Unformatted: