From b82462f0081a350485e15d373e6c0db663abaeb1 Mon Sep 17 00:00:00 2001 From: jeff Date: Tue, 29 Mar 2005 10:02:48 +0000 Subject: - Dont clear OWEINACT in vbusy(), we still owe an inactive call if someone vhold()s us. - Avoid an extra mutex acquire and release in the common case of vgonel() by checking for OWEINACT at the start of the function. - Fix the case where we set OWEINACT in vput(). LK_EXCLUPGRADE drops our shared lock if it fails. Sponsored by: Isilon Systems, Inc. --- sys/kern/vfs_subr.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'sys') diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 69929c2..97165dc 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1905,6 +1905,7 @@ vput(vp) struct vnode *vp; { struct thread *td = curthread; /* XXX */ + int error; KASSERT(vp != NULL, ("vput: null vp")); ASSERT_VOP_LOCKED(vp, "vput"); @@ -1912,6 +1913,7 @@ vput(vp) /* Skip this v_writecount check if we're going to panic below. */ VNASSERT(vp->v_writecount < vp->v_usecount || vp->v_usecount < 1, vp, ("vput: missed vn_close")); + error = 0; if (vp->v_usecount > 1 || ((vp->v_iflag & VI_DOINGINACT) && vp->v_usecount == 1)) { @@ -1927,10 +1929,15 @@ vput(vp) panic("vput: negative ref cnt"); } v_incr_usecount(vp, -1); - if (VOP_ISLOCKED(vp, td) != LK_EXCLUSIVE && - VOP_LOCK(vp, LK_EXCLUPGRADE, td) != 0) - vp->v_iflag |= VI_OWEINACT; - else + vp->v_iflag |= VI_OWEINACT; + if (VOP_ISLOCKED(vp, td) != LK_EXCLUSIVE) { + error = VOP_LOCK(vp, LK_EXCLUPGRADE|LK_INTERLOCK, td); + VI_LOCK(vp); + } + /* + * OWEINACT may be cleared while we're sleeping in EXCLUPGRADE. + */ + if (!error && vp->v_iflag & VI_OWEINACT) vinactive(vp, td); VOP_UNLOCK(vp, 0, td); if (VSHOULDFREE(vp)) @@ -2205,6 +2212,7 @@ vgone(struct vnode *vp) void vgonel(struct vnode *vp, struct thread *td) { + int oweinact; int active; int doomed; @@ -2226,6 +2234,7 @@ vgonel(struct vnode *vp, struct thread *td) doomed = (vp->v_iflag & VI_DOOMED); vp->v_iflag |= VI_DOOMED; vp->v_vxthread = curthread; + oweinact = (vp->v_iflag & VI_OWEINACT); VI_UNLOCK(vp); /* @@ -2241,17 +2250,13 @@ vgonel(struct vnode *vp, struct thread *td) * If purging an active vnode, it must be closed and * deactivated before being reclaimed. */ - if (active) { + if (active) VOP_CLOSE(vp, FNONBLOCK, NOCRED, td); + if (oweinact || active) { VI_LOCK(vp); if ((vp->v_iflag & VI_DOINGINACT) == 0) vinactive(vp, td); VI_UNLOCK(vp); - } else { - VI_LOCK(vp); - if (vp->v_iflag & VI_OWEINACT) - vinactive(vp, td); - VI_UNLOCK(vp); } /* * Reclaim the vnode. @@ -2744,7 +2749,7 @@ vbusy(struct vnode *vp) freevnodes--; mtx_unlock(&vnode_free_list_mtx); - vp->v_iflag &= ~(VI_FREE|VI_AGE|VI_OWEINACT); + vp->v_iflag &= ~(VI_FREE|VI_AGE); } /* -- cgit v1.1