Index: share/man/man9/vref.9 =================================================================== --- share/man/man9/vref.9 +++ share/man/man9/vref.9 @@ -28,17 +28,19 @@ .\" .\" $FreeBSD$ .\" -.Dd July 24, 1996 +.Dd January 14, 2016 .Dt VREF 9 .Os .Sh NAME -.Nm vref +.Nm vref , vrefl .Nd increment the use count for a vnode .Sh SYNOPSIS .In sys/param.h .In sys/vnode.h .Ft void .Fn vref "struct vnode *vp" +.Ft void +.Fn vrefl "struct vnode *vp" .Sh DESCRIPTION Increment the .Va v_usecount @@ -56,7 +58,14 @@ Any code in the system which is using a vnode (e.g.\& during the operation of some algorithm or to store in a data structure) should call -.Fn vref . +.Fn vref +or +.Fn vrefl . +.Pp +.Fn vref +locks the vnode interlock while +.Fn vrefl +expects the interlock to already be held. .Sh SEE ALSO .Xr vget 9 , .Xr vnode 9 , Index: sys/kern/vfs_subr.c =================================================================== --- sys/kern/vfs_subr.c +++ sys/kern/vfs_subr.c @@ -103,7 +103,7 @@ static void syncer_shutdown(void *arg, int howto); static int vtryrecycle(struct vnode *vp); static void v_init_counters(struct vnode *); -static void v_incr_usecount(struct vnode *); +static void v_incr_usecount(struct vnode *, bool); static void v_incr_devcount(struct vnode *); static void v_decr_devcount(struct vnode *); static void vnlru_free(int); @@ -2377,14 +2377,18 @@ * the vnode from the free list if it is presently free. */ static void -v_incr_usecount(struct vnode *vp) +v_incr_usecount(struct vnode *vp, bool locked) { - ASSERT_VI_UNLOCKED(vp, __func__); + if (locked) + ASSERT_VI_LOCKED(vp, __func__); + else + ASSERT_VI_UNLOCKED(vp, __func__); CTR2(KTR_VFS, "%s: vp %p", __func__, vp); if (vp->v_type == VCHR) { - VI_LOCK(vp); + if (!locked) + VI_LOCK(vp); _vhold(vp, true); if (vp->v_iflag & VI_OWEINACT) { VNASSERT(vp->v_usecount == 0, vp, @@ -2393,20 +2397,23 @@ } refcount_acquire(&vp->v_usecount); v_incr_devcount(vp); - VI_UNLOCK(vp); + if (!locked) + VI_LOCK(vp); return; } - _vhold(vp, false); + _vhold(vp, locked); if (vfs_refcount_acquire_if_not_zero(&vp->v_usecount)) { VNASSERT((vp->v_iflag & VI_OWEINACT) == 0, vp, ("vnode with usecount and VI_OWEINACT set")); } else { - VI_LOCK(vp); + if (!locked) + VI_LOCK(vp); if (vp->v_iflag & VI_OWEINACT) vp->v_iflag &= ~VI_OWEINACT; refcount_acquire(&vp->v_usecount); - VI_UNLOCK(vp); + if (!locked) + VI_UNLOCK(vp); } } @@ -2519,8 +2526,14 @@ vref(struct vnode *vp) { - CTR2(KTR_VFS, "%s: vp %p", __func__, vp); - v_incr_usecount(vp); + v_incr_usecount(vp, false); +} + +void +vrefl(struct vnode *vp) +{ + + v_incr_usecount(vp, true); } /* Index: sys/sys/vnode.h =================================================================== --- sys/sys/vnode.h +++ sys/sys/vnode.h @@ -823,6 +823,7 @@ void vput(struct vnode *vp); void vrele(struct vnode *vp); void vref(struct vnode *vp); +void vrefl(struct vnode *vp); int vrefcnt(struct vnode *vp); void v_addpollinfo(struct vnode *vp);