- 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:
parent
7747c03884
commit
8045557f2b
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user