- Assert that the lowervp is locked in null_hashget().

- Simplify the logic dealing with recycled vnodes in null_hashget() and
   null_hashins().  Since we hold the lower node locked in both cases
   the null node can not be undergoing recycling unless reclaim somehow
   called null_nodeget().  The logic that was in place was not safe and
   was essentially dead code.

MFC After:	1 week
This commit is contained in:
jeff 2006-02-22 06:15:12 +00:00
parent c925b62ee4
commit 79ca2be05c

View File

@ -107,6 +107,9 @@ null_hashget(mp, lowervp)
struct null_node_hashhead *hd;
struct null_node *a;
struct vnode *vp;
int error;
ASSERT_VOP_LOCKED(lowervp, "null_hashget");
/*
* Find hash base, and then search the (two-way) linked
@ -115,31 +118,27 @@ null_hashget(mp, lowervp)
* reference count (but NOT the lower vnode's VREF counter).
*/
hd = NULL_NHASH(lowervp);
loop:
mtx_lock(&null_hashmtx);
LIST_FOREACH(a, hd, null_hash) {
if (a->null_lowervp == lowervp && NULLTOV(a)->v_mount == mp) {
vp = NULLTOV(a);
VI_LOCK(vp);
/*
* If the nullfs node is being recycled we have
* to wait until it finishes prior to scanning
* again.
*/
mtx_unlock(&null_hashmtx);
if ((vp->v_iflag & VI_DOOMED) != 0) {
/* Wait for recycling to finish. */
VOP_LOCK(vp, LK_EXCLUSIVE|LK_INTERLOCK, td);
VOP_UNLOCK(vp, 0, td);
goto loop;
}
/*
* We need to clear the OWEINACT flag here as this
* may lead vget() to try to lock our vnode which
* is already locked via lowervp.
*/
vp->v_iflag &= ~VI_OWEINACT;
vget(vp, LK_INTERLOCK, td);
error = vget(vp, LK_INTERLOCK, td);
/*
* Since we have the lower node locked the nullfs
* node can not be in the process of recycling. If
* it had been recycled before we grabed the lower
* lock it would not have been found on the hash.
*/
if (error)
panic("null_hashget: vget error %d", error);
return (vp);
}
}
@ -160,28 +159,24 @@ null_hashins(mp, xp)
struct null_node_hashhead *hd;
struct null_node *oxp;
struct vnode *ovp;
int error;
hd = NULL_NHASH(xp->null_lowervp);
loop:
mtx_lock(&null_hashmtx);
LIST_FOREACH(oxp, hd, null_hash) {
if (oxp->null_lowervp == xp->null_lowervp &&
NULLTOV(oxp)->v_mount == mp) {
/*
* See null_hashget for a description of this
* operation.
*/
ovp = NULLTOV(oxp);
VI_LOCK(ovp);
/*
* If the nullfs node is being recycled we have
* to wait until it finishes prior to scanning
* again.
*/
mtx_unlock(&null_hashmtx);
if ((ovp->v_iflag & VI_DOOMED) != 0) {
VOP_LOCK(ovp, LK_EXCLUSIVE|LK_INTERLOCK, td);
VOP_UNLOCK(ovp, 0, td);
goto loop;
}
ovp->v_iflag &= ~VI_OWEINACT; /* see hashget comment */
vget(ovp, LK_INTERLOCK, td);
ovp->v_iflag &= ~VI_OWEINACT;
error = vget(ovp, LK_INTERLOCK, td);
if (error)
panic("null_hashins: vget error %d", error);
return (ovp);
}
}