Subject: kern/3003: Multiple union mount causes dead lock.
To: None <gnats-bugs@gnats.netbsd.org>
From: =?ISO-2022-JP?B?Ik1JTk9VUkEgTWFrb3RvIC8gGyRCTCcxOhsoQiAbJEI/PxsoQiI=?= <minoura@kw.netlaputa.or.jp>
List: netbsd-bugs
Date: 12/07/1996 19:24:33
>Number: 3003
>Category: kern
>Synopsis: Multiple union mount causes dead lock.
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Dec 7 06:35:00 1996
>Last-Modified:
>Originator: Naofumi HONDA / MINOURA Makoto
>Organization:
NetBSD/pc98 Core Team
>Release: Nov. 30, '96
>Environment:
System: NetBSD daisy 1.2B NetBSD 1.2B (DAISY) #1: Sun Dec 1 00:32:28 JST 1996 root@daisy:/usr/src/sys/arch/i386/compile/DAISY i386
>Description:
Multiple unionfs mount causes deadlock.
Because namei called from union_mount waits for the target
unlocked, which never happens.
>How-To-Repeat:
Perform same union fs mount repeatedly:-
# mount -t union /usr/obj /usr/src
# mount -t union /usr/obj /usr/src
>Fix:
A quick hack written by Naofumi HONDA originally for NetBSD/pc98.
*** /sys/miscfs/union/union_vfsops.c.ORIG Tue Oct 15 01:41:27 1996
--- /sys/miscfs/union/union_vfsops.c Sat Nov 30 19:31:25 1996
***************
*** 117,135 ****
lowerrootvp = mp->mnt_vnodecovered;
VREF(lowerrootvp);
/*
* Find upper node.
*/
NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT,
UIO_USERSPACE, args.target, p);
! if ((error = namei(ndp)) != 0)
goto bad;
upperrootvp = ndp->ni_vp;
vrele(ndp->ni_dvp);
ndp->ni_dvp = NULL;
if (upperrootvp->v_type != VDIR) {
error = EINVAL;
goto bad;
--- 117,156 ----
lowerrootvp = mp->mnt_vnodecovered;
VREF(lowerrootvp);
+ if (lowerrootvp->v_op == union_vnodeop_p)
+ VOP_UNLOCK(lowerrootvp);
+
/*
* Find upper node.
*/
NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT,
UIO_USERSPACE, args.target, p);
! if ((error = namei(ndp)) != 0) {
! if (lowerrootvp->v_op == union_vnodeop_p)
! VOP_LOCK(lowerrootvp);
goto bad;
+ }
upperrootvp = ndp->ni_vp;
vrele(ndp->ni_dvp);
ndp->ni_dvp = NULL;
+ /* XXX:
+ * Avoid hang up.
+ * mount -tunion /usr/src.skel /usr/src
+ * mount -tunion /usr/src.skel /usr/src again.
+ * However this method is quite illegal!! Do NOT blame me!
+ */
+ if (lowerrootvp->v_op == union_vnodeop_p) {
+ VOP_LOCK(lowerrootvp);
+ if (upperrootvp == VTOUNION(lowerrootvp)->un_uppervp) {
+ /* duplicated union... */
+ error = EBUSY;
+ goto bad;
+ }
+ }
+
if (upperrootvp->v_type != VDIR) {
error = EINVAL;
goto bad;
>Audit-Trail:
>Unformatted: