- Fix several locking problems in unionfs_mount so that it will come

closer to passing DEBUG_VFS_LOCKS.
This commit is contained in:
Jeff Roberson 2005-04-27 09:07:13 +00:00
parent 189dd72df3
commit 568556d720

View File

@ -127,37 +127,18 @@ union_mount(mp, td)
* Obtain lower vnode. Vnode is stored in mp->mnt_vnodecovered. * Obtain lower vnode. Vnode is stored in mp->mnt_vnodecovered.
* We need to reference it but not lock it. * We need to reference it but not lock it.
*/ */
lowerrootvp = mp->mnt_vnodecovered; lowerrootvp = mp->mnt_vnodecovered;
VREF(lowerrootvp); VREF(lowerrootvp);
#if 0
/*
* Unlock lower node to avoid deadlock.
*/
if (lowerrootvp->v_op == union_vnodeop_p)
VOP_UNLOCK(lowerrootvp, 0, td);
#endif
/* /*
* Obtain upper vnode by calling namei() on the path. The * Obtain upper vnode by calling namei() on the path. The
* upperrootvp will be turned referenced but not locked. * upperrootvp will be turned referenced and locked.
*/ */
NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT, UIO_SYSSPACE, target, td); NDINIT(ndp, LOOKUP, FOLLOW|LOCKLEAF, UIO_SYSSPACE, target, td);
error = namei(ndp); error = namei(ndp);
#if 0
if (lowerrootvp->v_op == union_vnodeop_p)
vn_lock(lowerrootvp, LK_EXCLUSIVE | LK_RETRY, td);
#endif
if (error) if (error)
goto bad; goto bad;
NDFREE(ndp, NDF_ONLY_PNBUF); NDFREE(ndp, NDF_ONLY_PNBUF);
upperrootvp = ndp->ni_vp; upperrootvp = ndp->ni_vp;
vrele(ndp->ni_dvp);
ndp->ni_dvp = NULL;
UDEBUG(("mount_root UPPERVP %p locked = %d\n", upperrootvp, UDEBUG(("mount_root UPPERVP %p locked = %d\n", upperrootvp,
VOP_ISLOCKED(upperrootvp, NULL))); VOP_ISLOCKED(upperrootvp, NULL)));
@ -208,6 +189,8 @@ union_mount(mp, td)
break; break;
case UNMNT_BELOW: case UNMNT_BELOW:
VOP_UNLOCK(upperrootvp, 0, td);
vn_lock(lowerrootvp, LK_RETRY|LK_EXCLUSIVE, td);
um->um_lowervp = upperrootvp; um->um_lowervp = upperrootvp;
um->um_uppervp = lowerrootvp; um->um_uppervp = lowerrootvp;
upperrootvp = NULL; upperrootvp = NULL;
@ -244,6 +227,7 @@ union_mount(mp, td)
if (error) if (error)
goto bad; goto bad;
} }
VOP_UNLOCK(um->um_uppervp, 0, td);
um->um_cred = crhold(td->td_ucred); um->um_cred = crhold(td->td_ucred);
FILEDESC_LOCK_FAST(td->td_proc->p_fd); FILEDESC_LOCK_FAST(td->td_proc->p_fd);
@ -305,14 +289,14 @@ union_mount(mp, td)
bad: bad:
if (um) { if (um) {
if (um->um_uppervp) if (um->um_uppervp)
vrele(um->um_uppervp); vput(um->um_uppervp);
if (um->um_lowervp) if (um->um_lowervp)
vrele(um->um_lowervp); vrele(um->um_lowervp);
/* XXX other fields */ /* XXX other fields */
free(um, M_UNIONFSMNT); free(um, M_UNIONFSMNT);
} }
if (upperrootvp) if (upperrootvp)
vrele(upperrootvp); vput(upperrootvp);
if (lowerrootvp) if (lowerrootvp)
vrele(lowerrootvp); vrele(lowerrootvp);
return (error); return (error);