Add vrefl(), a locked variant of vref(9).

This API has no in-tree consumers at the moment but is useful to at least
one out-of-tree consumer, and naturally complements existing vnode refcount
functions (vholdl(9), vdropl(9)).

Obtained from:	kib (sys/ portion)
Sponsored by:	EMC / Isilon Storage Division
Differential Revision:	https://reviews.freebsd.org/D4947
Differential Revision:	https://reviews.freebsd.org/D4953
This commit is contained in:
markj 2016-01-18 22:21:46 +00:00
parent cf79233816
commit 09fb369fc5
3 changed files with 41 additions and 22 deletions

View File

@ -28,17 +28,19 @@
.\"
.\" $FreeBSD$
.\"
.Dd July 24, 1996
.Dd January 18, 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 @@ no longer being used and can be safely recycled for a different file.
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 ,

View File

@ -104,6 +104,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_locked(struct vnode *);
static void v_incr_devcount(struct vnode *);
static void v_decr_devcount(struct vnode *);
static void vnlru_free(int);
@ -2371,6 +2372,20 @@ v_init_counters(struct vnode *vp)
refcount_init(&vp->v_usecount, 1);
}
static void
v_incr_usecount_locked(struct vnode *vp)
{
ASSERT_VI_LOCKED(vp, __func__);
if ((vp->v_iflag & VI_OWEINACT) != 0) {
VNASSERT(vp->v_usecount == 0, vp,
("vnode with usecount and VI_OWEINACT set"));
vp->v_iflag &= ~VI_OWEINACT;
}
refcount_acquire(&vp->v_usecount);
v_incr_devcount(vp);
}
/*
* Increment the use and hold counts on the vnode, taking care to reference
* the driver's usecount if this is a chardev. The _vhold() will remove
@ -2383,29 +2398,13 @@ v_incr_usecount(struct vnode *vp)
ASSERT_VI_UNLOCKED(vp, __func__);
CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
if (vp->v_type == VCHR) {
VI_LOCK(vp);
_vhold(vp, true);
if (vp->v_iflag & VI_OWEINACT) {
VNASSERT(vp->v_usecount == 0, vp,
("vnode with usecount and VI_OWEINACT set"));
vp->v_iflag &= ~VI_OWEINACT;
}
refcount_acquire(&vp->v_usecount);
v_incr_devcount(vp);
VI_UNLOCK(vp);
return;
}
_vhold(vp, false);
if (vfs_refcount_acquire_if_not_zero(&vp->v_usecount)) {
if (vp->v_type != VCHR &&
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 (vp->v_iflag & VI_OWEINACT)
vp->v_iflag &= ~VI_OWEINACT;
refcount_acquire(&vp->v_usecount);
v_incr_usecount_locked(vp);
VI_UNLOCK(vp);
}
}
@ -2520,9 +2519,19 @@ vref(struct vnode *vp)
{
CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
_vhold(vp, false);
v_incr_usecount(vp);
}
void
vrefl(struct vnode *vp)
{
CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
_vhold(vp, true);
v_incr_usecount_locked(vp);
}
/*
* Return reference count of a vnode.
*

View File

@ -823,6 +823,7 @@ void vop_rename_fail(struct vop_rename_args *ap);
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);