diff options
author | kib <kib@FreeBSD.org> | 2009-09-07 12:10:41 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-09-07 12:10:41 +0000 |
commit | 8aa65727e7b2747938c94ffa03836fc0f95ef1c7 (patch) | |
tree | d8d571aba994dee9e43b815d4444ff9ccf753cce /sys/fs/pseudofs | |
parent | 30f476628e6f86dfeae10a66497797b701734b2e (diff) | |
download | FreeBSD-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.c | 8 |
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); |