summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>1997-04-19 06:04:13 +0000
committerkato <kato@FreeBSD.org>1997-04-19 06:04:13 +0000
commit47e567e3df0f8ce73fc3fcffe9410b8ddbf6ea66 (patch)
tree1465ef8a781a2f54f6be61af6d13d4e7692e8895
parent5678742cc6736e572768d3cff00c1190bfe666fc (diff)
downloadFreeBSD-src-47e567e3df0f8ce73fc3fcffe9410b8ddbf6ea66.zip
FreeBSD-src-47e567e3df0f8ce73fc3fcffe9410b8ddbf6ea66.tar.gz
Avoid `lock against myself' panic by following operation:
# mount -t union (or null) dir1 dir2 # mount -t union (or null) dir2 dir1 The function namei in union_mount calls union_root. The upper vnode has been already locked and vn_lock in union_root causes above panic. Add printf's included in `#ifdef DIAGNOSTIC' for EDEADLK cases.
-rw-r--r--sys/fs/nullfs/null_vfsops.c21
-rw-r--r--sys/fs/unionfs/union_vfsops.c18
-rw-r--r--sys/miscfs/nullfs/null_vfsops.c21
-rw-r--r--sys/miscfs/union/union_vfsops.c18
4 files changed, 66 insertions, 12 deletions
diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c
index 10791f8..8f3ca4d 100644
--- a/sys/fs/nullfs/null_vfsops.c
+++ b/sys/fs/nullfs/null_vfsops.c
@@ -36,7 +36,7 @@
* @(#)null_vfsops.c 8.2 (Berkeley) 1/21/94
*
* @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92
- * $Id: null_vfsops.c,v 1.15 1997/04/17 11:17:29 kato Exp $
+ * $Id: null_vfsops.c,v 1.16 1997/04/17 11:24:57 kato Exp $
*/
/*
@@ -149,8 +149,10 @@ nullfs_mount(mp, path, data, ndp, p)
* Check multi null mount to avoid `lock against myself' panic.
*/
if (lowerrootvp == VTONULL(mp->mnt_vnodecovered)->null_lowervp) {
- error = EDEADLK;
- return (error);
+#ifdef DIAGNOSTIC
+ printf("nullfs_mount: multi null mount?\n");
+#endif
+ return (EDEADLK);
}
xmp = (struct null_mount *) malloc(sizeof(struct null_mount),
@@ -293,7 +295,18 @@ nullfs_root(mp, vpp)
*/
vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
VREF(vp);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ if (VOP_ISLOCKED(vp)) {
+ /*
+ * XXX
+ * Should we check type of node?
+ */
+#ifdef DIAGNOSTIC
+ printf("nullfs_root: multi null mount?\n");
+#endif
+ vrele(vp);
+ return (EDEADLK);
+ } else
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
*vpp = vp;
return 0;
}
diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c
index 13e94f2..98ad258 100644
--- a/sys/fs/unionfs/union_vfsops.c
+++ b/sys/fs/unionfs/union_vfsops.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)union_vfsops.c 8.20 (Berkeley) 5/20/95
- * $Id: union_vfsops.c,v 1.14 1997/02/22 09:40:41 peter Exp $
+ * $Id: union_vfsops.c,v 1.15 1997/04/14 10:52:25 kato Exp $
*/
/*
@@ -161,6 +161,9 @@ union_mount(mp, path, data, ndp, p)
* Check multi union mount to avoid `lock myself again' panic.
*/
if (upperrootvp == VTOUNION(lowerrootvp)->un_uppervp) {
+#ifdef DIAGNOSTIC
+ printf("union_mount: multi union mount?\n");
+#endif
error = EDEADLK;
goto bad;
}
@@ -408,7 +411,18 @@ union_root(mp, vpp)
VOP_ISLOCKED(um->um_uppervp)) {
loselock = 1;
} else {
- vn_lock(um->um_uppervp, LK_EXCLUSIVE | LK_RETRY, p);
+ if (VOP_ISLOCKED(um->um_uppervp)) {
+ /*
+ * XXX
+ * Should we check type of node?
+ */
+#ifdef DIAGNOSTIC
+ printf("union_root: multi union mount?");
+#endif
+ vrele(um->um_uppervp);
+ return EDEADLK;
+ } else
+ vn_lock(um->um_uppervp, LK_EXCLUSIVE | LK_RETRY, p);
loselock = 0;
}
if (um->um_lowervp)
diff --git a/sys/miscfs/nullfs/null_vfsops.c b/sys/miscfs/nullfs/null_vfsops.c
index 10791f8..8f3ca4d 100644
--- a/sys/miscfs/nullfs/null_vfsops.c
+++ b/sys/miscfs/nullfs/null_vfsops.c
@@ -36,7 +36,7 @@
* @(#)null_vfsops.c 8.2 (Berkeley) 1/21/94
*
* @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92
- * $Id: null_vfsops.c,v 1.15 1997/04/17 11:17:29 kato Exp $
+ * $Id: null_vfsops.c,v 1.16 1997/04/17 11:24:57 kato Exp $
*/
/*
@@ -149,8 +149,10 @@ nullfs_mount(mp, path, data, ndp, p)
* Check multi null mount to avoid `lock against myself' panic.
*/
if (lowerrootvp == VTONULL(mp->mnt_vnodecovered)->null_lowervp) {
- error = EDEADLK;
- return (error);
+#ifdef DIAGNOSTIC
+ printf("nullfs_mount: multi null mount?\n");
+#endif
+ return (EDEADLK);
}
xmp = (struct null_mount *) malloc(sizeof(struct null_mount),
@@ -293,7 +295,18 @@ nullfs_root(mp, vpp)
*/
vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
VREF(vp);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ if (VOP_ISLOCKED(vp)) {
+ /*
+ * XXX
+ * Should we check type of node?
+ */
+#ifdef DIAGNOSTIC
+ printf("nullfs_root: multi null mount?\n");
+#endif
+ vrele(vp);
+ return (EDEADLK);
+ } else
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
*vpp = vp;
return 0;
}
diff --git a/sys/miscfs/union/union_vfsops.c b/sys/miscfs/union/union_vfsops.c
index 13e94f2..98ad258 100644
--- a/sys/miscfs/union/union_vfsops.c
+++ b/sys/miscfs/union/union_vfsops.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)union_vfsops.c 8.20 (Berkeley) 5/20/95
- * $Id: union_vfsops.c,v 1.14 1997/02/22 09:40:41 peter Exp $
+ * $Id: union_vfsops.c,v 1.15 1997/04/14 10:52:25 kato Exp $
*/
/*
@@ -161,6 +161,9 @@ union_mount(mp, path, data, ndp, p)
* Check multi union mount to avoid `lock myself again' panic.
*/
if (upperrootvp == VTOUNION(lowerrootvp)->un_uppervp) {
+#ifdef DIAGNOSTIC
+ printf("union_mount: multi union mount?\n");
+#endif
error = EDEADLK;
goto bad;
}
@@ -408,7 +411,18 @@ union_root(mp, vpp)
VOP_ISLOCKED(um->um_uppervp)) {
loselock = 1;
} else {
- vn_lock(um->um_uppervp, LK_EXCLUSIVE | LK_RETRY, p);
+ if (VOP_ISLOCKED(um->um_uppervp)) {
+ /*
+ * XXX
+ * Should we check type of node?
+ */
+#ifdef DIAGNOSTIC
+ printf("union_root: multi union mount?");
+#endif
+ vrele(um->um_uppervp);
+ return EDEADLK;
+ } else
+ vn_lock(um->um_uppervp, LK_EXCLUSIVE | LK_RETRY, p);
loselock = 0;
}
if (um->um_lowervp)
OpenPOWER on IntegriCloud