Allow shared-locked vnode to be passed to vunref(9).

When shared-locked vnode is supplied as an argument to vunref(9) and
resulting usecount is 0, set VI_OWEINACT and do not try to upgrade vnode
lock. The later could cause vnode unlock, allowing the vnode to be
reclaimed meantime.

Tested by:	pho
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2010-11-24 12:30:41 +00:00
parent 780636b72a
commit f5eb95b1fc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=215797

View File

@ -2186,7 +2186,7 @@ vputx(struct vnode *vp, int func)
KASSERT(vp != NULL, ("vputx: null vp"));
if (func == VPUTX_VUNREF)
ASSERT_VOP_ELOCKED(vp, "vunref");
ASSERT_VOP_LOCKED(vp, "vunref");
else if (func == VPUTX_VPUT)
ASSERT_VOP_LOCKED(vp, "vput");
else
@ -2224,12 +2224,22 @@ vputx(struct vnode *vp, int func)
* as VI_DOINGINACT to avoid recursion.
*/
vp->v_iflag |= VI_OWEINACT;
if (func == VPUTX_VRELE) {
switch (func) {
case VPUTX_VRELE:
error = vn_lock(vp, LK_EXCLUSIVE | LK_INTERLOCK);
VI_LOCK(vp);
} else if (func == VPUTX_VPUT && VOP_ISLOCKED(vp) != LK_EXCLUSIVE) {
error = VOP_LOCK(vp, LK_UPGRADE | LK_INTERLOCK | LK_NOWAIT);
VI_LOCK(vp);
break;
case VPUTX_VPUT:
if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) {
error = VOP_LOCK(vp, LK_UPGRADE | LK_INTERLOCK |
LK_NOWAIT);
VI_LOCK(vp);
}
break;
case VPUTX_VUNREF:
if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE)
error = EBUSY;
break;
}
if (vp->v_usecount > 0)
vp->v_iflag &= ~VI_OWEINACT;