diff options
author | jeff <jeff@FreeBSD.org> | 2002-08-22 06:51:06 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2002-08-22 06:51:06 +0000 |
commit | 1e39ba86206301d7f569b3f402577d596d55faa0 (patch) | |
tree | 457bfe56464a26c696b32591e533f083202323b4 /sys/kern/vfs_subr.c | |
parent | 3781c72cd943aa2aa6c12249440949c0e220a0e7 (diff) | |
download | FreeBSD-src-1e39ba86206301d7f569b3f402577d596d55faa0.zip FreeBSD-src-1e39ba86206301d7f569b3f402577d596d55faa0.tar.gz |
- Fix interlock handling in vn_lock(). Previously, vn_lock() could return
with interlock held in error conditions when the caller did not specify
LK_INTERLOCK.
- Add several comments to vn_lock() describing the rational behind the code
flow since it was not immediately obvious.
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r-- | sys/kern/vfs_subr.c | 26 |
1 files changed, 9 insertions, 17 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 2fe2d00..96f902a 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -931,17 +931,6 @@ getnewvnode(tag, mp, vops, vpp) splx(s); -#if 0 - mp_fixme("This code does not lock access to numvnodes && freevnodes."); - vnodeallocs++; - if (vnodeallocs % vnoderecycleperiod == 0 && - freevnodes < vnoderecycleminfreevn && - vnoderecyclemintotalvn < numvnodes) { - /* Recycle vnodes. */ - cache_purgeleafdirs(vnoderecyclenumber); - } -#endif - return (0); } @@ -2183,12 +2172,12 @@ loop: nvp = TAILQ_NEXT(vp, v_nmntvnodes); mtx_unlock(&mntvnode_mtx); - VI_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); /* * Skip over a vnodes marked VV_SYSTEM. */ if ((flags & SKIPSYSTEM) && (vp->v_vflag & VV_SYSTEM)) { - VI_UNLOCK(vp); + VOP_UNLOCK(vp, 0, td); mtx_lock(&mntvnode_mtx); continue; } @@ -2197,17 +2186,20 @@ loop: * files (even if open only for reading) and regular file * vnodes open for writing. */ - mp_fixme("Getattr called with interlock held!"); + error = VOP_GETATTR(vp, &vattr, td->td_ucred, td); + VI_LOCK(vp); + if ((flags & WRITECLOSE) && (vp->v_type == VNON || - (VOP_GETATTR(vp, &vattr, td->td_ucred, td) == 0 && - vattr.va_nlink > 0)) && + (error == 0 && vattr.va_nlink > 0)) && (vp->v_writecount == 0 || vp->v_type != VREG)) { - mtx_unlock(&vp->v_interlock); + VOP_UNLOCK(vp, LK_INTERLOCK, td); mtx_lock(&mntvnode_mtx); continue; } + VOP_UNLOCK(vp, 0, td); + /* * With v_usecount == 0, all we need to do is clear out the * vnode data structures and we are done. |