Index: null_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/fs/nullfs/null_vnops.c,v retrieving revision 1.88 diff -u -r1.88 null_vnops.c --- null_vnops.c 2 Sep 2005 15:49:55 -0000 1.88 +++ null_vnops.c 15 Sep 2005 17:20:25 -0000 @@ -180,6 +180,7 @@ #include #include #include +#include #include @@ -545,6 +546,30 @@ */ vholdl(lvp); error = VOP_LOCK(lvp, flags, td); + + /* + * We might have slept to get the lock and someone might have + * clean our vnode already, switching vnode lock from one in + * lowervp to v_lock in our own vnode structure. Handle this + * case by reacquiring correct lock in requested mode. + */ + if (VTONULL(vp) == NULL && error == 0) { + ap->a_flags &= ~(LK_TYPE_MASK | LK_INTERLOCK); + switch (flags & LK_TYPE_MASK) { + case LK_SHARED: + ap->a_flags |= LK_SHARED; + break; + case LK_UPGRADE: + case LK_EXCLUSIVE: + ap->a_flags |= LK_EXCLUSIVE; + break; + default: + panic("Unsupported lock request %d\n", + ap->a_flags); + } + VOP_LOCK(lvp, LK_RELEASE, td); + error = vop_stdlock(ap); + } vdrop(lvp); } else error = vop_stdlock(ap); @@ -633,14 +658,13 @@ */ VI_LOCK(vp); vp->v_data = NULL; - VI_UNLOCK(vp); + vnlock = vp->v_vnlock; + vp->v_vnlock = &vp->v_lock; + lockmgr(vp->v_vnlock, LK_EXCLUSIVE|LK_INTERLOCK, VI_MTX(vp), curthread); if (lowervp) null_hashrem(xp); vp->v_object = NULL; - vnlock = vp->v_vnlock; - vp->v_vnlock = &vp->v_lock; - lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL, curthread); if (lowervp) { vput(lowervp); } else