aboutsummaryrefslogtreecommitdiff
path: root/sys/fs
diff options
context:
space:
mode:
authorJeff Roberson <jeff@FreeBSD.org>2005-04-27 09:07:13 +0000
committerJeff Roberson <jeff@FreeBSD.org>2005-04-27 09:07:13 +0000
commit568556d72011ca4ce53f5689ec05018b44519061 (patch)
treebfeb3c4361e45e1c9f3d7a4771ad0bf47aa2d1e3 /sys/fs
parent189dd72df3996ffd02c2bf2e11a7342ce70ca8ff (diff)
downloadsrc-568556d72011ca4ce53f5689ec05018b44519061.tar.gz
src-568556d72011ca4ce53f5689ec05018b44519061.zip
- Fix several locking problems in unionfs_mount so that it will come
closer to passing DEBUG_VFS_LOCKS.
Notes
Notes: svn path=/head/; revision=145586
Diffstat (limited to 'sys/fs')
-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 0f8539b378bd..61c78831990e 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);