From 91d0c7d581e8f40e7a30b5b9043569b0684a0ba8 Mon Sep 17 00:00:00 2001 From: kib Date: Fri, 27 Dec 2013 17:09:59 +0000 Subject: [PATCH] Fix accounting for the negative cache entries when reusing v_cache_dd. Having ncneg diverge with the actual length of the ncneg tailq causes NULL dereference. Add assertion that an entry taken from ncneg queue is indeed negative. Reported by and discussed with: avg Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/kern/vfs_cache.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index d46ba3dbdb4a..33f5cce65c52 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)