diff options
author | jeff <jeff@FreeBSD.org> | 2005-06-13 06:26:55 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2005-06-13 06:26:55 +0000 |
commit | 7a825fb4571a4a801e6216d71f9ef2f76fe66ff9 (patch) | |
tree | 990d355df281b698191ba75c236b2e80f313913b /sys | |
parent | 22b5cc07b0583b989f4440150b8b32a38bd232b7 (diff) | |
download | FreeBSD-src-7a825fb4571a4a801e6216d71f9ef2f76fe66ff9.zip FreeBSD-src-7a825fb4571a4a801e6216d71f9ef2f76fe66ff9.tar.gz |
- Don't make vgonel() globally visible, we want to change its prototype
anyway and it's not used outside of vfs_subr.c.
- Change vgonel() to accept a parameter which determines whether or not
we'll put the vnode on the free list when we're done.
- Use the new vgonel() parameter rather than VI_DOOMED to signal our
intentions in vtryrecycle().
- In vgonel() return if VI_DOOMED is already set, this vnode has already
been reclaimed.
Sponsored by: Isilon Systems, Inc.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_subr.c | 55 | ||||
-rw-r--r-- | sys/sys/vnode.h | 1 |
2 files changed, 19 insertions, 37 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index faf8cf30..dd80289 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -97,6 +97,7 @@ static void vfree(struct vnode *); static void vfreehead(struct vnode *); static void vnlru_free(int); static void vdestroy(struct vnode *); +static void vgonel(struct vnode *, int); /* * Enable Giant pushdown based on whether or not the vm is mpsafe in this @@ -790,8 +791,7 @@ vtryrecycle(struct vnode *vp) goto err; } if ((vp->v_iflag & VI_DOOMED) == 0) { - vp->v_iflag |= VI_DOOMED; - vgonel(vp, td); + vgonel(vp, 0); VI_LOCK(vp); } /* @@ -2148,12 +2148,14 @@ loop: } } else VI_LOCK(vp); + KASSERT((vp->v_iflag & VI_DOOMED) == 0, + ("vflush: Found doomed vnode %p on the mount list.", vp)); /* * With v_usecount == 0, all we need to do is clear out the * vnode data structures and we are done. */ if (vp->v_usecount == 0) { - vgonel(vp, td); + vgonel(vp, 1); VOP_UNLOCK(vp, 0, td); MNT_ILOCK(mp); continue; @@ -2166,7 +2168,7 @@ loop: if (flags & FORCECLOSE) { VNASSERT(vp->v_type != VCHR && vp->v_type != VBLK, vp, ("device VNODE %p is FORCECLOSED", vp)); - vgonel(vp, td); + vgonel(vp, 1); VOP_UNLOCK(vp, 0, td); MNT_ILOCK(mp); continue; @@ -2238,7 +2240,7 @@ vrecycle(struct vnode *vp, struct thread *td) ASSERT_VOP_LOCKED(vp, "vrecycle"); VI_LOCK(vp); if (vp->v_usecount == 0 && (vp->v_iflag & VI_DOOMED) == 0) { - vgonel(vp, td); + vgonel(vp, 1); return (1); } VI_UNLOCK(vp); @@ -2252,49 +2254,41 @@ vrecycle(struct vnode *vp, struct thread *td) void vgone(struct vnode *vp) { - struct thread *td = curthread; /* XXX */ - ASSERT_VOP_LOCKED(vp, "vgone"); - - /* - * Don't vgonel if we're already doomed. - */ VI_LOCK(vp); - if (vp->v_iflag & VI_DOOMED) { - VI_UNLOCK(vp); - return; - } - vgonel(vp, td); + vgonel(vp, 1); } /* * vgone, with the vp interlock held. */ void -vgonel(struct vnode *vp, struct thread *td) +vgonel(struct vnode *vp, int shouldfree) { + struct thread *td; int oweinact; int active; - int doomed; CTR1(KTR_VFS, "vgonel: vp %p", vp); ASSERT_VOP_LOCKED(vp, "vgonel"); ASSERT_VI_LOCKED(vp, "vgonel"); /* + * Don't vgonel if we're already doomed. + */ + if (vp->v_iflag & VI_DOOMED) { + VI_UNLOCK(vp); + return; + } + /* * Check to see if the vnode is in use. If so we have to reference it * before we clean it out so that its count cannot fall to zero and * generate a race against ourselves to recycle it. */ if ((active = vp->v_usecount)) v_incr_usecount(vp, 1); - - /* - * See if we're already doomed, if so, this is coming from a - * successful vtryrecycle(); - */ - doomed = (vp->v_iflag & VI_DOOMED); vp->v_iflag |= VI_DOOMED; oweinact = (vp->v_iflag & VI_OWEINACT); + td = curthread; VI_UNLOCK(vp); /* @@ -2345,18 +2339,7 @@ vgonel(struct vnode *vp, struct thread *td) vp->v_op = &dead_vnodeops; vp->v_tag = "none"; vp->v_type = VBAD; - - /* - * If it is on the freelist and not already at the head, - * move it to the head of the list. The test of the - * VDOOMED flag and the reference count of zero is because - * it will be removed from the free list by vnlru_free, - * but will not have its reference count incremented until - * after calling vgone. If the reference count were - * incremented first, vgone would (incorrectly) try to - * close the previous instance of the underlying object. - */ - if (vp->v_holdcnt == 0 && !doomed) + if (vp->v_holdcnt == 0 && shouldfree) vfreehead(vp); VI_UNLOCK(vp); } diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index fce277f..b201f6d 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -599,7 +599,6 @@ void vfs_rm_vnodeops(const void *); int vflush(struct mount *mp, int rootrefs, int flags, struct thread *td); int vget(struct vnode *vp, int lockflag, struct thread *td); void vgone(struct vnode *vp); -void vgonel(struct vnode *vp, struct thread *td); void vhold(struct vnode *); void vholdl(struct vnode *); int vinvalbuf(struct vnode *vp, int save, |