summaryrefslogtreecommitdiffstats
path: root/sys/fs/pseudofs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-09-07 12:10:41 +0000
committerkib <kib@FreeBSD.org>2009-09-07 12:10:41 +0000
commit8aa65727e7b2747938c94ffa03836fc0f95ef1c7 (patch)
treed8d571aba994dee9e43b815d4444ff9ccf753cce /sys/fs/pseudofs
parent30f476628e6f86dfeae10a66497797b701734b2e (diff)
downloadFreeBSD-src-8aa65727e7b2747938c94ffa03836fc0f95ef1c7.zip
FreeBSD-src-8aa65727e7b2747938c94ffa03836fc0f95ef1c7.tar.gz
If a race is detected, pfs_vncache_alloc() may reclaim a vnode that had
never been inserted into the pfs_vncache list. Since pfs_vncache_free() does not anticipate this case, it decrements pfs_vncache_entries unconditionally; if the vnode was not in the list, pfs_vncache_entries will no longer reflect the actual number of list entries. This may cause size of the cache to exceed the configured maximum. It may also trigger a panic during module unload or system shutdown. Do not decrement pfs_vncache_entries for the vnode that was not in the list. Submitted by: tegge Reviewed by: des MFC after: 1 week
Diffstat (limited to 'sys/fs/pseudofs')
-rw-r--r--sys/fs/pseudofs/pseudofs_vncache.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/fs/pseudofs/pseudofs_vncache.c b/sys/fs/pseudofs/pseudofs_vncache.c
index a92a446..035f2c7 100644
--- a/sys/fs/pseudofs/pseudofs_vncache.c
+++ b/sys/fs/pseudofs/pseudofs_vncache.c
@@ -246,11 +246,13 @@ pfs_vncache_free(struct vnode *vp)
KASSERT(pvd != NULL, ("pfs_vncache_free(): no vnode data\n"));
if (pvd->pvd_next)
pvd->pvd_next->pvd_prev = pvd->pvd_prev;
- if (pvd->pvd_prev)
+ if (pvd->pvd_prev) {
pvd->pvd_prev->pvd_next = pvd->pvd_next;
- else if (pfs_vncache == pvd)
+ --pfs_vncache_entries;
+ } else if (pfs_vncache == pvd) {
pfs_vncache = pvd->pvd_next;
- --pfs_vncache_entries;
+ --pfs_vncache_entries;
+ }
mtx_unlock(&pfs_vncache_mutex);
free(pvd, M_PFSVNCACHE);
OpenPOWER on IntegriCloud