summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2005-03-14 09:25:19 +0000
committerjeff <jeff@FreeBSD.org>2005-03-14 09:25:19 +0000
commit3fcb9112fb1915c98e275295e779c38aa7a0b32a (patch)
tree041dcebf7b2395ea0b4fe4cc8d7d94cafcae0642 /sys
parent41fb0028e9c567d939d26775ff018fa6d249aaff (diff)
downloadFreeBSD-src-3fcb9112fb1915c98e275295e779c38aa7a0b32a.zip
FreeBSD-src-3fcb9112fb1915c98e275295e779c38aa7a0b32a.tar.gz
- Increment the holdcnt once for each usecount reference. This allows us
to use only the holdcnt to determine whether a vnode may be recycled, simplifying the V* macros as well as vtryrecycle(), etc. Sponsored by: Isilon Systems, Inc.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_subr.c7
-rw-r--r--sys/sys/vnode.h14
2 files changed, 9 insertions, 12 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 97a52e4..8d0d6c2 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -745,7 +745,7 @@ vtryrecycle(struct vnode *vp)
* If someone ref'd the vnode while we were cleaning, we have to
* free it once the last ref is dropped.
*/
- if (vp->v_usecount || vp->v_holdcnt)
+ if (vp->v_holdcnt)
error = EBUSY;
VI_UNLOCK(vp);
done:
@@ -1781,6 +1781,7 @@ v_incr_usecount(struct vnode *vp, int delta)
{
vp->v_usecount += delta;
+ vp->v_holdcnt += delta;
if (vp->v_type == VCHR && vp->v_rdev != NULL) {
dev_lock();
vp->v_rdev->si_usecount += delta;
@@ -2018,7 +2019,7 @@ vdropl(struct vnode *vp)
{
if (vp->v_holdcnt <= 0)
- panic("vdrop: holdcnt");
+ panic("vdrop: holdcnt %d", vp->v_holdcnt);
vp->v_holdcnt--;
if (VSHOULDFREE(vp))
vfree(vp);
@@ -2326,7 +2327,7 @@ vgonel(struct vnode *vp, struct thread *td)
* incremented first, vgone would (incorrectly) try to
* close the previous instance of the underlying object.
*/
- if (vp->v_usecount == 0 && vp->v_holdcnt == 0 && !doomed) {
+ if (vp->v_holdcnt == 0 && !doomed) {
mtx_lock(&vnode_free_list_mtx);
if (vp->v_iflag & VI_FREE) {
TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 19bf36c..b99a766 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -159,7 +159,7 @@ struct vnode {
const char *filename; /* Source file doing locking */
int line; /* Line number doing locking */
#endif
- int v_holdcnt; /* i page & buffer references */
+ int v_holdcnt; /* i prevents recycling. */
int v_usecount; /* i ref count of users */
struct thread *v_vxthread; /* i thread running vgone. */
u_long v_iflag; /* i vnode flags (see below) */
@@ -387,20 +387,16 @@ extern void (*lease_updatetime)(int deltat);
/* Requires interlock. */
#define VCANRECYCLE(vp) \
- (((vp)->v_iflag & VI_FREE) && \
- !(vp)->v_holdcnt && !(vp)->v_usecount)
+ (((vp)->v_iflag & VI_FREE) && !(vp)->v_holdcnt)
/* Requires interlock. */
#define VSHOULDFREE(vp) \
- (!((vp)->v_iflag & VI_FREE) && \
- !(vp)->v_holdcnt && !(vp)->v_usecount && \
- (!(vp)->v_object || \
- !(vp)->v_object->resident_page_count))
+ (!((vp)->v_iflag & VI_FREE) && !(vp)->v_holdcnt && \
+ (!(vp)->v_object || !(vp)->v_object->resident_page_count))
/* Requires interlock. */
#define VSHOULDBUSY(vp) \
- (((vp)->v_iflag & VI_FREE) && \
- ((vp)->v_holdcnt || (vp)->v_usecount))
+ (((vp)->v_iflag & VI_FREE) && (vp)->v_holdcnt)
#define VI_LOCK(vp) mtx_lock(&(vp)->v_interlock)
#define VI_TRYLOCK(vp) mtx_trylock(&(vp)->v_interlock)
OpenPOWER on IntegriCloud