vtryget: try to get an initial reference to a vnode without taking its
interlock. Only works if v_usecount is already non-zero, which is nearly always true for busy files like libc.so or ld_elf.so.
This commit is contained in:
parent
e437f08c73
commit
457a3f8942
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vfs_subr.c,v 1.348 2008/06/02 22:56:09 ad Exp $ */
|
||||
/* $NetBSD: vfs_subr.c,v 1.349 2008/06/03 14:54:12 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -87,7 +87,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.348 2008/06/02 22:56:09 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.349 2008/06/03 14:54:12 ad Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_compat_netbsd.h"
|
||||
|
@ -712,6 +712,36 @@ getdevvp(dev_t dev, vnode_t **vpp, enum vtype type)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to gain a reference to a vnode, without acquiring its interlock.
|
||||
* The caller must hold a lock that will prevent the vnode from being
|
||||
* recycled or freed.
|
||||
*/
|
||||
bool
|
||||
vtryget(vnode_t *vp)
|
||||
{
|
||||
u_int use, next;
|
||||
|
||||
/*
|
||||
* If the vnode is being freed, don't make life any harder
|
||||
* for vclean() by adding another reference without waiting.
|
||||
* This is not strictly necessary, but we'll do it anyway.
|
||||
*/
|
||||
if (__predict_false((vp->v_iflag & (VI_XLOCK | VI_FREEING)) != 0)) {
|
||||
return false;
|
||||
}
|
||||
for (use = vp->v_usecount;; use = next) {
|
||||
if (use == 0) {
|
||||
/* Need interlock held if first reference. */
|
||||
return false;
|
||||
}
|
||||
next = atomic_cas_uint(&vp->v_usecount, use, use + 1);
|
||||
if (__predict_true(next == use)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Grab a particular vnode from the free list, increment its
|
||||
* reference count and lock it. If the vnode lock bit is set the
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vnode.h,v 1.194 2008/06/02 16:25:34 ad Exp $ */
|
||||
/* $NetBSD: vnode.h,v 1.195 2008/06/03 14:54:12 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -595,6 +595,7 @@ int vfinddev(dev_t, enum vtype, struct vnode **);
|
|||
int vflush(struct mount *, struct vnode *, int);
|
||||
void vflushbuf(struct vnode *, int);
|
||||
int vget(struct vnode *, int);
|
||||
bool vtryget(struct vnode *);
|
||||
void vgone(struct vnode *);
|
||||
void vgonel(struct vnode *, struct lwp *);
|
||||
int vinvalbuf(struct vnode *, int, kauth_cred_t, struct lwp *, bool, int);
|
||||
|
|
Loading…
Reference in New Issue