mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-29 19:43:41 +00:00
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.
This commit is contained in:
parent
e747d90dbf
commit
747e915757
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=25016
@ -36,7 +36,7 @@
|
|||||||
* @(#)null_vfsops.c 8.2 (Berkeley) 1/21/94
|
* @(#)null_vfsops.c 8.2 (Berkeley) 1/21/94
|
||||||
*
|
*
|
||||||
* @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92
|
* @(#)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.
|
* Check multi null mount to avoid `lock against myself' panic.
|
||||||
*/
|
*/
|
||||||
if (lowerrootvp == VTONULL(mp->mnt_vnodecovered)->null_lowervp) {
|
if (lowerrootvp == VTONULL(mp->mnt_vnodecovered)->null_lowervp) {
|
||||||
error = EDEADLK;
|
#ifdef DIAGNOSTIC
|
||||||
return (error);
|
printf("nullfs_mount: multi null mount?\n");
|
||||||
|
#endif
|
||||||
|
return (EDEADLK);
|
||||||
}
|
}
|
||||||
|
|
||||||
xmp = (struct null_mount *) malloc(sizeof(struct null_mount),
|
xmp = (struct null_mount *) malloc(sizeof(struct null_mount),
|
||||||
@ -293,7 +295,18 @@ nullfs_root(mp, vpp)
|
|||||||
*/
|
*/
|
||||||
vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
|
vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
|
||||||
VREF(vp);
|
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;
|
*vpp = vp;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* @(#)union_vfsops.c 8.20 (Berkeley) 5/20/95
|
* @(#)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.
|
* Check multi union mount to avoid `lock myself again' panic.
|
||||||
*/
|
*/
|
||||||
if (upperrootvp == VTOUNION(lowerrootvp)->un_uppervp) {
|
if (upperrootvp == VTOUNION(lowerrootvp)->un_uppervp) {
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
printf("union_mount: multi union mount?\n");
|
||||||
|
#endif
|
||||||
error = EDEADLK;
|
error = EDEADLK;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -408,7 +411,18 @@ union_root(mp, vpp)
|
|||||||
VOP_ISLOCKED(um->um_uppervp)) {
|
VOP_ISLOCKED(um->um_uppervp)) {
|
||||||
loselock = 1;
|
loselock = 1;
|
||||||
} else {
|
} 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;
|
loselock = 0;
|
||||||
}
|
}
|
||||||
if (um->um_lowervp)
|
if (um->um_lowervp)
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
* @(#)null_vfsops.c 8.2 (Berkeley) 1/21/94
|
* @(#)null_vfsops.c 8.2 (Berkeley) 1/21/94
|
||||||
*
|
*
|
||||||
* @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92
|
* @(#)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.
|
* Check multi null mount to avoid `lock against myself' panic.
|
||||||
*/
|
*/
|
||||||
if (lowerrootvp == VTONULL(mp->mnt_vnodecovered)->null_lowervp) {
|
if (lowerrootvp == VTONULL(mp->mnt_vnodecovered)->null_lowervp) {
|
||||||
error = EDEADLK;
|
#ifdef DIAGNOSTIC
|
||||||
return (error);
|
printf("nullfs_mount: multi null mount?\n");
|
||||||
|
#endif
|
||||||
|
return (EDEADLK);
|
||||||
}
|
}
|
||||||
|
|
||||||
xmp = (struct null_mount *) malloc(sizeof(struct null_mount),
|
xmp = (struct null_mount *) malloc(sizeof(struct null_mount),
|
||||||
@ -293,7 +295,18 @@ nullfs_root(mp, vpp)
|
|||||||
*/
|
*/
|
||||||
vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
|
vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
|
||||||
VREF(vp);
|
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;
|
*vpp = vp;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* @(#)union_vfsops.c 8.20 (Berkeley) 5/20/95
|
* @(#)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.
|
* Check multi union mount to avoid `lock myself again' panic.
|
||||||
*/
|
*/
|
||||||
if (upperrootvp == VTOUNION(lowerrootvp)->un_uppervp) {
|
if (upperrootvp == VTOUNION(lowerrootvp)->un_uppervp) {
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
printf("union_mount: multi union mount?\n");
|
||||||
|
#endif
|
||||||
error = EDEADLK;
|
error = EDEADLK;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -408,7 +411,18 @@ union_root(mp, vpp)
|
|||||||
VOP_ISLOCKED(um->um_uppervp)) {
|
VOP_ISLOCKED(um->um_uppervp)) {
|
||||||
loselock = 1;
|
loselock = 1;
|
||||||
} else {
|
} 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;
|
loselock = 0;
|
||||||
}
|
}
|
||||||
if (um->um_lowervp)
|
if (um->um_lowervp)
|
||||||
|
Loading…
Reference in New Issue
Block a user