From 9c12e63100699032250716f19a5916ea09be2ded Mon Sep 17 00:00:00 2001 From: Jeff Roberson Date: Wed, 22 Feb 2006 06:15:12 +0000 Subject: [PATCH] - 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 --- sys/fs/nullfs/null_subr.c | 47 +++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/sys/fs/nullfs/null_subr.c b/sys/fs/nullfs/null_subr.c index a5a45eac988..5dc7c634ca7 100644 --- a/sys/fs/nullfs/null_subr.c +++ b/sys/fs/nullfs/null_subr.c @@ -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); } }