namecache: numneg > 0 but ncneg is empty

Konstantin Belousov kostikbel at gmail.com
Thu Dec 19 07:03:56 UTC 2013


On Wed, Dec 18, 2013 at 11:17:59AM +0200, Andriy Gapon wrote:
> 
> I've been running a test that exercises vfs, fs and namecache code quite a lot
> and I have run into the following panic:
> 
> #2  0xffffffff808e9b43 in panic (fmt=<value optimized out>) at
> /usr/src/sys/kern/kern_shutdown.c:637
> #3  0xffffffff80ce57dd in trap_fatal (frame=0xc, eva=18446744071578770679) at
> /usr/src/sys/amd64/amd64/trap.c:879
> #4  0xffffffff80ce58a6 in trap_pfault (frame=0xffffff9de1875260, usermode=0) at
> /usr/src/sys/amd64/amd64/trap.c:700
> #5  0xffffffff80ce60d7 in trap (frame=0xffffff9de1875260) at
> /usr/src/sys/amd64/amd64/trap.c:463
> #6  0xffffffff80cce853 in calltrap () at /usr/src/sys/amd64/amd64/exception.S:232
> #7  0xffffffff8097b46d in cache_zap (ncp=0x0) at /usr/src/sys/kern/vfs_cache.c:417
> #8  0xffffffff8097c22f in cache_enter_time (dvp=0xfffffe031c7215f8,
> vp=0xfffffe0a684f05f8, cnp=0xffffff9de1875858, tsp=0x0, dtsp=0x0) at
> /usr/src/sys/kern/vfs_cache.c:902
> #9  0xffffffff81b9b26c in zfs_lookup (dvp=0xfffffe031c7215f8,
> nm=0xffffff9de1875460 "5", vpp=0xffffff9de1875830, cnp=0xffffff9de1875858,
> nameiop=1, cr=0xfffffe0a8f937800, td=0xfffffe04a80c2490, flags=0)
>     at
> /usr/src/sys/modules/zfs/../../cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c:1555
> #10 0xffffffff81b9b338 in zfs_freebsd_lookup (ap=0xffffff9de18755d0) at
> /usr/src/sys/modules/zfs/../../cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c:5946
> #11 0xffffffff80d8f403 in VOP_CACHEDLOOKUP_APV (vop=0xffffffff81c26ee0,
> a=0xffffff9de18755d0) at vnode_if.c:193
> #12 0xffffffff8097cef3 in vfs_cache_lookup (ap=<value optimized out>) at
> vnode_if.h:80
> #13 0xffffffff80d8f623 in VOP_LOOKUP_APV (vop=0xffffffff81c26ee0,
> a=0xffffff9de18756b0) at vnode_if.c:126
> #14 0xffffffff80984bed in lookup (ndp=0xffffff9de18757f0) at vnode_if.h:54
> #15 0xffffffff80985a43 in namei (ndp=0xffffff9de18757f0) at
> /usr/src/sys/kern/vfs_lookup.c:294
> #16 0xffffffff809981a2 in kern_mkdirat (td=0xfffffe04a80c2490, fd=-100,
> path=0x801c19110 <Address 0x801c19110 out of bounds>, segflg=UIO_USERSPACE,
> mode=511) at /usr/src/sys/kern/vfs_syscalls.c:3830
> #17 0xffffffff809983f6 in kern_mkdir (td=<value optimized out>, path=<value
> optimized out>, segflg=<value optimized out>, mode=<value optimized out>) at
> /usr/src/sys/kern/vfs_syscalls.c:3810
> #18 0xffffffff80998414 in sys_mkdir (td=<value optimized out>, uap=<value
> optimized out>) at /usr/src/sys/kern/vfs_syscalls.c:3789
> 
> (kgdb) fr 8
> #8  0xffffffff8097c22f in cache_enter_time (dvp=0xfffffe031c7215f8,
> vp=0xfffffe0a684f05f8, cnp=0xffffff9de1875858, tsp=0x0, dtsp=0x0) at
> /usr/src/sys/kern/vfs_cache.c:902
> 902                     cache_zap(ncp);
> (kgdb) list
> 897                     zap = 1;
> 898             }
> 899             if (hold)
> 900                     vhold(dvp);
> 901             if (zap)
> 902                     cache_zap(ncp);
> 903             CACHE_WUNLOCK();
> 904     }
> 905
> 906     /*
> (kgdb) i loc
> ncp = (struct namecache *) 0x0
> n2 = (struct namecache *) 0xffffffff8178a740
> ncpp = (struct nchashhead *) 0xffffff8ccde4e9b0
> hash = <value optimized out>
> flag = 0
> hold = 1
> zap = 1
> len = <value optimized out>
> 
> (kgdb) p numneg
> $4 = 437
> (kgdb) p ncp
> $7 = (struct namecache *) 0x0
> (kgdb) p ncneg
> $8 = {tqh_first = 0x0, tqh_last = 0xffffffff8178a710}
> 
> 
> I am not sure that there is a bug in namecache, but if there is one, then the
> only suspicious place I could find is ".." handling in cache_enter_time().
> 

Do you mean that numneg accounting is wrong for the case when the
existing ncp retargeted for dd ? This is the only issue I see there, but
it looks as the real case for the failure.

Testcase would be lot of lookups down the long directory hierarchy, and
than walking back through the ".." entries.  Even if the thing does not
panic, the resulting length of the ncneg tailq should be strictly less
than the numneg.

diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index d46ba3d..33f5cce 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -748,16 +748,20 @@ cache_enter_time(dvp, vp, cnp, tsp, dtsp)
 			    ncp->nc_flag & NCF_ISDOTDOT) {
 				KASSERT(ncp->nc_dvp == dvp,
 				    ("wrong isdotdot parent"));
-				if (ncp->nc_vp != NULL)
+				if (ncp->nc_vp != NULL) {
 					TAILQ_REMOVE(&ncp->nc_vp->v_cache_dst,
 					    ncp, nc_dst);
-				else
+				} else {
 					TAILQ_REMOVE(&ncneg, ncp, nc_dst);
-				if (vp != NULL)
+					numneg--;
+				}
+				if (vp != NULL) {
 					TAILQ_INSERT_HEAD(&vp->v_cache_dst,
 					    ncp, nc_dst);
-				else
+				} else {
 					TAILQ_INSERT_TAIL(&ncneg, ncp, nc_dst);
+					numneg++;
+				}
 				ncp->nc_vp = vp;
 				CACHE_WUNLOCK();
 				return;
@@ -893,6 +897,8 @@ cache_enter_time(dvp, vp, cnp, tsp, dtsp)
 	}
 	if (numneg * ncnegfactor > numcache) {
 		ncp = TAILQ_FIRST(&ncneg);
+		KASSERT(ncp->nc_vp == NULL, ("ncp %p vp %p on ncneg",
+		    ncp, ncp->nc_vp));
 		zap = 1;
 	}
 	if (hold)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 834 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-fs/attachments/20131219/5729830b/attachment.sig>


More information about the freebsd-fs mailing list