diff options
author | kato <kato@FreeBSD.org> | 1997-04-19 06:04:13 +0000 |
---|---|---|
committer | kato <kato@FreeBSD.org> | 1997-04-19 06:04:13 +0000 |
commit | 47e567e3df0f8ce73fc3fcffe9410b8ddbf6ea66 (patch) | |
tree | 1465ef8a781a2f54f6be61af6d13d4e7692e8895 /sys/fs/unionfs/union_vfsops.c | |
parent | 5678742cc6736e572768d3cff00c1190bfe666fc (diff) | |
download | FreeBSD-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.
Diffstat (limited to 'sys/fs/unionfs/union_vfsops.c')
-rw-r--r-- | sys/fs/unionfs/union_vfsops.c | 18 |
1 files changed, 16 insertions, 2 deletions
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) |