diff options
author | kib <kib@FreeBSD.org> | 2013-12-27 17:09:59 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2013-12-27 17:09:59 +0000 |
commit | 91d0c7d581e8f40e7a30b5b9043569b0684a0ba8 (patch) | |
tree | 7fd8f0e6c5eb75c71106c9d2afece4d6004c8655 /sys/kern | |
parent | a21b7ae470741bfcd7757981ee0979d77fee3ca7 (diff) | |
download | FreeBSD-src-91d0c7d581e8f40e7a30b5b9043569b0684a0ba8.zip FreeBSD-src-91d0c7d581e8f40e7a30b5b9043569b0684a0ba8.tar.gz |
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
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_cache.c | 14 |
1 files changed, 10 insertions, 4 deletions
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) |