Subject: kern/4439: incorrect link count of dirs that only exist in upper layer of unionfs
To: None <gnats-bugs@gnats.netbsd.org>
From: Dave Huang <khym@bga.com>
List: netbsd-bugs
Date: 11/06/1997 06:39:54
>Number: 4439
>Category: kern
>Synopsis: incorrect link count of dirs that only exist in upper layer of unionfs
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Nov 6 05:20:04 1997
>Last-Modified:
>Originator: Dave Huang
>Organization:
Name: Dave Huang | Mammal, mammal / their names are called /
INet: khym@bga.com | they raise a paw / the bat, the cat /
FurryMUCK: Dahan | dolphin and dog / koala bear and hog -- TMBG
Dahan: Hani G Y+C 22 Y++ L+++ W- C++ T++ A+ E+ S++ V++ F- Q+++ P+ B+ PA+ PL++
>Release: NetBSD-1.3_ALPHA as of November 5, 1997
>Environment:
System: NetBSD dahan.metonymy.com 1.3_ALPHA NetBSD 1.3_ALPHA (SPIFF) #156: Thu Nov 6 06:24:34 CST 1997 khym@dahan.metonymy.com:/usr/src.local/sys/arch/i386/compile/SPIFF i386
>Description:
The link count of directories that only exist in the upper
layer of a union filesystem is garbage.
union_getattr() in union_vnops.c has the following comment:
/*
* Some programs walk the filesystem hierarchy by counting
* links to directories to avoid stat'ing all the time.
* This means the link count on directories needs to be "correct".
* The only way to do that is to call getattr on both layers
* and fix up the link count. The link count will not necessarily
* be accurate but will be large enough to defeat the tree walkers.
*/
But if the directory doesn't exist in the lower layer, it uses the
contents of an uninitialized structure for the lower layer's link
count.
>How-To-Repeat:
dahan /tmp# pwd
/tmp
dahan /tmp# mkdir top bottom
dahan /tmp# mount -t union /tmp/top /tmp/bottom
dahan /tmp# mkdir bottom/dir
dahan /tmp# ls -l bottom
total 1
drwx------ 4028275317 root wheel 512 Nov 2 04:15 dir/
dahan /tmp# umount /tmp/bottom
dahan /tmp# ls -l top bottom
bottom:
top:
total 1
drwx------ 2 root wheel 512 Nov 2 04:15 dir/
However, Matthias Drochner tried the above and wasn't able to
duplicate the problem on his system... so I dunno what's going on.
I've done a "sup -o", so my sources should be up-to-date.
>Fix:
Make sure va.va_nlink is initialized before trying to use it. Perhaps
something like this:
--- /usr/src/sys/miscfs/union/union_vnops.c Fri Oct 10 07:26:34 1997
+++ union_vnops.c Thu Nov 6 06:24:01 1997
@@ -811,6 +811,8 @@
vp = NULLVP;
}
+ va.va_nlink = 0;
+
if (vp != NULLVP) {
error = VOP_GETATTR(vp, vap, ap->a_cred, ap->a_p);
if (error)
Or maybe initialize it inside this block... *shrug*
} else if (vp->v_type == VDIR) {
vp = un->un_lowervp;
vap = &va;
} else {
>Audit-Trail:
>Unformatted: