- 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.
This commit is contained in:
Jeff Roberson 2005-03-14 09:25:19 +00:00
parent 7747c03884
commit 8045557f2b
2 changed files with 9 additions and 12 deletions

View File

@ -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);

View File

@ -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)