diff options
author | rwatson <rwatson@FreeBSD.org> | 2000-01-29 15:22:58 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2000-01-29 15:22:58 +0000 |
commit | 2aada2e69400d618896432bd5e82e5c77dc71330 (patch) | |
tree | c1b8259c56294c740ca8081eeb6338bcf3cc6057 /sys/kern/vfs_export.c | |
parent | d7e5eb3faac173e7d9640e098621746b86213739 (diff) | |
download | FreeBSD-src-2aada2e69400d618896432bd5e82e5c77dc71330.zip FreeBSD-src-2aada2e69400d618896432bd5e82e5c77dc71330.tar.gz |
This patch fixes a locking bug that can result in deadlock if
the codepath is followed.
From the PR:
vclean calls vrele leading to deadlock (if usecount > 0)
vclean() calls vrele() if v_usecount of the node was higher than one.
But before calling it, it sets the VXLOCK flag, which will make
vn_lock called from vrele dead-lock.
PR: kern/15117
Submitted by: Assar Westerlund <assar@stacken.kth.se>
Reviewed by: rwatson
Obtained from: NetBSD
Diffstat (limited to 'sys/kern/vfs_export.c')
-rw-r--r-- | sys/kern/vfs_export.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 97d6251..e0ef113 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -1701,8 +1701,23 @@ vclean(vp, flags, p) if (VOP_RECLAIM(vp, p)) panic("vclean: cannot reclaim"); - if (active) - vrele(vp); + if (active) { + /* + * Inline copy of vrele() since VOP_INACTIVE + * has already been called. + */ + simple_lock(&vp->v_interlock); + if (--vp->v_usecount <= 0) { +#ifdef DIAGNOSTIC + if (vp->v_usecount < 0 || vp->v_writecount != 0) { + vprint("vclean: bad ref count", vp); + panic("vclean: ref cnt"); + } +#endif + vfree(vp); + } + simple_unlock(&vp->v_interlock); + } cache_purge(vp); if (vp->v_vnlock) { |