diff options
author | markj <markj@FreeBSD.org> | 2016-01-18 22:21:46 +0000 |
---|---|---|
committer | markj <markj@FreeBSD.org> | 2016-01-18 22:21:46 +0000 |
commit | 09fb369fc5164b2baaba44740ab7379c43306071 (patch) | |
tree | 93731c648315eadaf2fcf33fef8fe7ef553fd8ce /sys/kern/vfs_subr.c | |
parent | cf792338169fcd15fbb628696c34d234e8781827 (diff) | |
download | FreeBSD-src-09fb369fc5164b2baaba44740ab7379c43306071.zip FreeBSD-src-09fb369fc5164b2baaba44740ab7379c43306071.tar.gz |
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
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r-- | sys/kern/vfs_subr.c | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 5542541..b420c84 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -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. * |