summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_subr.c
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2002-08-22 06:51:06 +0000
committerjeff <jeff@FreeBSD.org>2002-08-22 06:51:06 +0000
commit1e39ba86206301d7f569b3f402577d596d55faa0 (patch)
tree457bfe56464a26c696b32591e533f083202323b4 /sys/kern/vfs_subr.c
parent3781c72cd943aa2aa6c12249440949c0e220a0e7 (diff)
downloadFreeBSD-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.c26
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.
OpenPOWER on IntegriCloud