From 747e915757b2162d78d0e3184524c7804b47bb60 Mon Sep 17 00:00:00 2001 From: KATO Takenori Date: Sat, 19 Apr 1997 06:04:13 +0000 Subject: [PATCH] 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. --- sys/fs/nullfs/null_vfsops.c | 21 +++++++++++++++++---- sys/fs/unionfs/union_vfsops.c | 18 ++++++++++++++++-- sys/miscfs/nullfs/null_vfsops.c | 21 +++++++++++++++++---- sys/miscfs/union/union_vfsops.c | 18 ++++++++++++++++-- 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c index 10791f8128bf..8f3ca4da70ae 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 13e94f287b6c..98ad2586994f 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 10791f8128bf..8f3ca4da70ae 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 13e94f287b6c..98ad2586994f 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)