summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2005-04-27 09:07:13 +0000
committerjeff <jeff@FreeBSD.org>2005-04-27 09:07:13 +0000
commit5ae67dae9ad4621ea416eb2a5e0f2437c375271e (patch)
treebfeb3c4361e45e1c9f3d7a4771ad0bf47aa2d1e3
parentb6552bddeb676bedce3a313041701a955fa1fd6c (diff)
downloadFreeBSD-src-5ae67dae9ad4621ea416eb2a5e0f2437c375271e.zip
FreeBSD-src-5ae67dae9ad4621ea416eb2a5e0f2437c375271e.tar.gz
- Fix several locking problems in unionfs_mount so that it will come
closer to passing DEBUG_VFS_LOCKS.
-rw-r--r--sys/fs/unionfs/union_vfsops.c30
1 files changed, 7 insertions, 23 deletions
diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c
index 0f8539b..61c7883 100644
--- a/sys/fs/unionfs/union_vfsops.c
+++ b/sys/fs/unionfs/union_vfsops.c
@@ -127,37 +127,18 @@ union_mount(mp, td)
* Obtain lower vnode. Vnode is stored in mp->mnt_vnodecovered.
* We need to reference it but not lock it.
*/
-
lowerrootvp = mp->mnt_vnodecovered;
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
- * 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);
-
-#if 0
- if (lowerrootvp->v_op == union_vnodeop_p)
- vn_lock(lowerrootvp, LK_EXCLUSIVE | LK_RETRY, td);
-#endif
if (error)
goto bad;
-
NDFREE(ndp, NDF_ONLY_PNBUF);
upperrootvp = ndp->ni_vp;
- vrele(ndp->ni_dvp);
- ndp->ni_dvp = NULL;
UDEBUG(("mount_root UPPERVP %p locked = %d\n", upperrootvp,
VOP_ISLOCKED(upperrootvp, NULL)));
@@ -208,6 +189,8 @@ union_mount(mp, td)
break;
case UNMNT_BELOW:
+ VOP_UNLOCK(upperrootvp, 0, td);
+ vn_lock(lowerrootvp, LK_RETRY|LK_EXCLUSIVE, td);
um->um_lowervp = upperrootvp;
um->um_uppervp = lowerrootvp;
upperrootvp = NULL;
@@ -244,6 +227,7 @@ union_mount(mp, td)
if (error)
goto bad;
}
+ VOP_UNLOCK(um->um_uppervp, 0, td);
um->um_cred = crhold(td->td_ucred);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
@@ -305,14 +289,14 @@ union_mount(mp, td)
bad:
if (um) {
if (um->um_uppervp)
- vrele(um->um_uppervp);
+ vput(um->um_uppervp);
if (um->um_lowervp)
vrele(um->um_lowervp);
/* XXX other fields */
free(um, M_UNIONFSMNT);
}
if (upperrootvp)
- vrele(upperrootvp);
+ vput(upperrootvp);
if (lowerrootvp)
vrele(lowerrootvp);
return (error);
OpenPOWER on IntegriCloud