From hsu@clinet.fi  Wed Mar  6 16:48:05 1996
Received: from hauki.clinet.fi (root@hauki.clinet.fi [194.100.0.1])
          by freefall.freebsd.org (8.7.3/8.7.3) with ESMTP id QAA15248
          for <FreeBSD-gnats-submit@freebsd.org>; Wed, 6 Mar 1996 16:48:02 -0800 (PST)
Received: from zetor.clinet.fi (root@zetor.clinet.fi [194.100.0.11]) by hauki.clinet.fi (8.7.3/8.6.4) with ESMTP id CAA05924 for <FreeBSD-gnats-submit@freebsd.org>; Thu, 7 Mar 1996 02:47:30 +0200 (EET)
Received: (root@localhost) by zetor.clinet.fi (8.7.3/8.6.4) id CAA01586; Thu, 7 Mar 1996 02:47:30 +0200 (EET)
Message-Id: <199603070047.CAA01586@zetor.clinet.fi>
Date: Thu, 7 Mar 1996 02:47:30 +0200 (EET)
From: Heikki Suonsivu <hsu@clinet.fi>
Reply-To: hsu@clinet.fi
To: FreeBSD-gnats-submit@freebsd.org
Subject: panic: ufs_lock: recursive lock not expected, pid: 27195
X-Send-Pr-Version: 3.2

>Number:         1067
>Category:       kern
>Synopsis:       panic: ufs_lock: recursive lock not expected, pid: 27195
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Mar  6 16:50:02 PST 1996
>Closed-Date:    Wed Nov 18 19:15:38 PST 1998
>Last-Modified:  Wed Nov 18 19:17:47 PST 1998
>Originator:     Heikki Suonsivu
>Release:        FreeBSD 2.2-CURRENT i386
>Organization:
Clinet, Espoo, Finland
>Environment:

	-current

Mar  6 18:46:27 cantina /kernel: FreeBSD 2.2-CURRENT #16: Thu Feb 22 22:38:14 EET 1996
Mar  6 18:46:28 cantina /kernel:     hsu@news.clinet.fi:/usr/current/src/sys/compile/CLINETSERVER
Mar  6 18:46:28 cantina /kernel: CPU: Pentium (132.61-MHz 586-class CPU)
Mar  6 18:46:28 cantina /kernel:   Origin = "GenuineIntel"  Id = 0x52b  Stepping=11
Mar  6 18:46:28 cantina /kernel:   Features=0x1bf<FPU,VME,DE,PSE,TSC,MSR,MCE,CX8>
Mar  6 18:46:28 cantina /kernel: real memory  = 67108864 (65536K bytes)
Mar  6 18:46:28 cantina /kernel: avail memory = 63606784 (62116K bytes)
Mar  6 18:46:28 cantina /kernel: DEVFS: ready for devices
Mar  6 18:46:28 cantina /kernel: Probing for devices on PCI bus 0:
Mar  6 18:46:28 cantina /kernel: chip0 <Intel 82437 (Triton) PCI cache memory controller> rev 2 on pci0:0
Mar  6 18:46:28 cantina /kernel: chip1 <Intel 82371 (Triton) PCI-ISA bridge> rev 2 on pci0:7
Mar  6 18:46:28 cantina /kernel: piix0 <Intel 82371 (Triton) Bus-master IDE controller> rev 2 on pci0:7
Mar  6 18:46:28 cantina /kernel: de0 <Digital DC21040 Ethernet> rev 35 int a irq 10 on pci0:10
Mar  6 18:46:28 cantina /kernel: de0: DC21040 [10Mb/s] pass 2.3 Ethernet address 00:c0:95:ec:56:84
Mar  6 18:46:29 cantina /kernel: de0: enabling Thinwire/AUI port
Mar  6 18:46:29 cantina /kernel: ncr0 <ncr 53c810 scsi> rev 2 int a irq 11 on pci0:12
Mar  6 18:46:29 cantina /kernel: ncr0 waiting for scsi devices to settle
Mar  6 18:46:29 cantina /kernel: (ncr0:0:0): "IBM DPES-31080 S31Q" type 0 fixed SCSI 2
Mar  6 18:46:29 cantina /kernel: sd0(ncr0:0:0): Direct-Access 
Mar  6 18:46:29 cantina /kernel: sd0(ncr0:0:0): FAST SCSI-2 100ns (10 Mb/sec) offset 8.
Mar  6 18:46:29 cantina /kernel: 1034MB (2118144 512 byte sectors)
Mar  6 18:46:29 cantina /kernel: sd0(ncr0:0:0): with 4903 cyls, 4 heads, and an average 108 sectors/track
Mar  6 18:46:29 cantina /kernel: Probing for devices on the ISA bus:
Mar  6 18:46:29 cantina /kernel: vt0 at 0x60-0x6f irq 1 on motherboard
Mar  6 18:46:29 cantina /kernel: vt0: tvga 8900cl, 80/132 col, color, 8 scr, mf2-kbd, [R3.20-b24]
Mar  6 18:46:29 cantina /kernel: ed0 not found at 0x280
Mar  6 18:46:29 cantina /kernel: lpt0 at 0x378-0x37f irq 7 on isa
Mar  6 18:46:29 cantina /kernel: lpt0: Interrupt-driven port
Mar  6 18:46:29 cantina /kernel: lp0: TCP/IP capable interface
Mar  6 18:46:29 cantina /kernel: lpt1 not found at 0xffffffff
Mar  6 18:46:29 cantina /kernel: sio0 at 0x3f8-0x3ff irq 4 on isa
Mar  6 18:46:29 cantina /kernel: sio0: type 16550A
Mar  6 18:46:29 cantina /kernel: sio1 at 0x2f8-0x2ff irq 3 on isa
Mar  6 18:46:29 cantina /kernel: sio1: type 16550A
Mar  6 18:46:29 cantina /kernel: cy0 not found
Mar  6 18:46:29 cantina /kernel: bt0 not found at 0x330
Mar  6 18:46:29 cantina /kernel: aha0 not found at 0x330
Mar  6 18:46:30 cantina /kernel: wdc0 not found at 0x1f0
Mar  6 18:46:30 cantina /kernel: fdc0 at 0x3f0-0x3f7 irq 6 drq 2 on isa
Mar  6 18:46:30 cantina /kernel: fdc0: NEC 72065B
Mar  6 18:46:30 cantina /kernel: fd0: 1.44MB 3.5in
Mar  6 18:46:30 cantina /kernel: matcdc0 not found at 0x230
Mar  6 18:46:30 cantina /kernel: npx0 on motherboard
Mar  6 18:46:30 cantina /kernel: npx0: INT 16 interface
Mar  6 18:46:30 cantina /kernel: changing root device to sd0a
Mar  6 18:46:30 cantina /kernel: devfs ready to run
Mar  6 18:46:31 cantina /kernel: new masks: bio c0000840, tty c003049a, net c003049a
Mar  6 18:46:31 cantina /kernel: WARNING: / was not properly dismounted.

>Description:

	Mounting a directory on itself panics the system.

mount /m/katiska/local /m/katiska/local

Mar  6 18:46:26 cantina /kernel: panic: ufs_lock: recursive lock not expected, pid: 27195
Mar  6 18:46:27 cantina /kernel: 
Mar  6 18:46:27 cantina /kernel: 
Mar  6 18:46:27 cantina /kernel: syncing disks... 21 21 14 8 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 giving up
Mar  6 18:46:27 cantina /kernel: 1: dev:ffffffff, flags:21000014, blkno:1648, lblkno:103
Mar  6 18:46:27 cantina /kernel: 2: dev:ffffffff, flags:21000034, blkno:896, lblkno:56
Mar  6 18:46:27 cantina /kernel: 3: dev:ffffffff, flags:21000034, blkno:448, lblkno:28
Mar  6 18:46:27 cantina /kernel: 4: dev:ffffffff, flags:21000034, blkno:0, lblkno:0
Mar  6 18:46:27 cantina /kernel: 
Mar  6 18:46:27 cantina /kernel: dumping to dev 401, offset 0
Mar  6 18:46:27 cantina /kernel: dump 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 succeeded
Mar  6 18:46:27 cantina /kernel: Automatic reboot in 15 seconds - press a key on the console to abort
Mar  6 18:46:27 cantina /kernel: Rebooting...

ftp://ftp.clinet.fi/pub/FreeBSD/cantina/*.1.gz

>How-To-Repeat:

	mount /m/katiska/local /m/katiska/local

	where /m/katiska/local is a directory (intended mount point,
	"machine:" was missing).

>Fix:
	

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->analyzed 
State-Changed-By: mpp 
State-Changed-When: Sat Mar 9 16:21:26 PST 1996 
State-Changed-Why:  
I changed mount to not allow the caller to panic the machine 
if they do something like "mount /mnt /mnt".  This is a temporary 
workaround until some of Terry's file system rework goes in, 
at which time I can fix the kernel properly and without any kludges. 


Responsible-Changed-From-To: freebsd-bugs->mpp 
Responsible-Changed-By: mpp 
Responsible-Changed-When: Sat Mar 9 16:21:26 PST 1996 
Responsible-Changed-Why:  
State-Changed-From-To: analyzed->suspended 
State-Changed-By: scrappy 
State-Changed-When: Sat Nov 9 21:20:31 PST 1996 
State-Changed-Why:  

Suspended at Originator's request, as it is supposedly awaiting work 
from Terry 

Responsible-Changed-From-To: mpp->freebsd-bugs 
Responsible-Changed-By: steve 
Responsible-Changed-When: Sat Aug 16 16:21:19 PDT 1997 
Responsible-Changed-Why:  
Remove mpp as the responsible person. 

From: Tor Egge <Tor.Egge@idi.ntnu.no>
To: freebsd-gnats-submit@FreeBSD.ORG
Cc:  Subject: re: kern/1067: panic: ufs_lock: recursive lock not expected, pid: 27195
Date: Sat, 14 Feb 1998 01:42:10 +0100

 By introducing a new vnode flag, the assignment of v_mountedhere can
 be delayed until the file system specific mount code has been
 successfully executed. This means that the exclusive lock on the vnode
 to be covered can be temporarily released by the generic mount code,
 and namei() operations in {ffs,msdosfs,cd9660,nullfs,union,umap}_mount 
 can complete without panics due to unexpected recursive locks.
 
 The mount() system call should by default disallow mounts over
 existing mount points. An explicit mount option (SunOS 5.5.1 uses `-O')
 should be specified in order to allow mount over an existing mount point.
 
 Then	
 	mount /dev/fd0 /
 would give 
 	/dev/fd0 on /: Device busy
 
 while
 	mount /mnt /mnt
 would give
 	/mnt on /mnt: Block device required
 
 and 
 	mount -O /dev/fd0 /
 would succeed, mounting the floppy as the new root file system.
 
 Suggested fix for 3.0-CURRENT:
 
 Index: sys/sys/vnode.h
 ===================================================================
 RCS file: /home/ncvs/src/sys/sys/vnode.h,v
 retrieving revision 1.66
 diff -u -r1.66 vnode.h
 --- vnode.h	1998/01/24 02:01:31	1.66
 +++ vnode.h	1998/02/10 18:53:07
 @@ -155,6 +155,7 @@
  #define	VDOOMED		0x40000	/* This vnode is being recycled */
  #define	VFREE		0x80000	/* This vnode is on the freelist */
  #define	VTBFREE		0x100000	/* This vnode is no the to be freelist */
 +#define	VMOUNT		0x200000	/* Mount in progress */
  
  /*
   * Vnode attributes.  A field value of VNOVAL represents a field whose value
 Index: sys/sys/mount.h
 ===================================================================
 RCS file: /home/ncvs/src/sys/sys/mount.h,v
 retrieving revision 1.54
 diff -u -r1.54 mount.h
 --- mount.h	1998/02/05 17:27:42	1.54
 +++ mount.h	1998/02/14 00:00:59
 @@ -211,7 +211,9 @@
  #define	MNT_DELEXPORT	0x00020000	/* delete export host lists */
  #define	MNT_RELOAD	0x00040000	/* reload filesystem data */
  #define	MNT_FORCE	0x00080000	/* force unmount or readonly change */
 -#define MNT_CMDFLAGS	(MNT_UPDATE|MNT_DELEXPORT|MNT_RELOAD|MNT_FORCE)
 +#define	MNT_OVERLAY	0x00200000	/* Allow mount over mount point */
 +#define MNT_CMDFLAGS	(MNT_UPDATE	| MNT_DELEXPORT	| MNT_RELOAD	| \
 +			 MNT_FORCE	| MNT_OVERLAY )
  /*
   * Internal filesystem control flags stored in mnt_kern_flag.
   *
 Index: sys/kern/vfs_syscalls.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
 retrieving revision 1.92
 diff -u -r1.92 vfs_syscalls.c
 --- vfs_syscalls.c	1998/02/08 01:41:33	1.92
 +++ vfs_syscalls.c	1998/02/13 23:18:59
 @@ -233,10 +233,24 @@
  		vput(vp);
  		return (ENODEV);
  	}
 -	if (vp->v_mountedhere != NULL) {
 +	if ((SCARG(uap, flags) & MNT_OVERLAY) == 0) {
 +		simple_lock(&vp->v_interlock);
 +		if ((vp->v_flag & VROOT) != 0) {
 +			simple_unlock(&vp->v_interlock);
 +			vput(vp);
 +			return EBUSY;
 +		}
 +		simple_unlock(&vp->v_interlock);
 +	}
 +	simple_lock(&vp->v_interlock);
 +	if ((vp->v_flag & VMOUNT) != 0 ||
 +	    vp->v_mountedhere != NULL) {
 +		simple_unlock(&vp->v_interlock);
  		vput(vp);
  		return (EBUSY);
  	}
 +	vp->v_flag |= VMOUNT;
 +	simple_unlock(&vp->v_interlock);
  
  	/*
  	 * Allocate and initialize the filesystem.
 @@ -252,9 +266,9 @@
  	mp->mnt_stat.f_type = vfsp->vfc_typenum;
  	mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
  	strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
 -	vp->v_mountedhere = mp;
  	mp->mnt_vnodecovered = vp;
  	mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
 +	VOP_UNLOCK(vp, 0, p);
  update:
  	/*
  	 * Set the mount level flags.
 @@ -286,11 +300,16 @@
  		vfs_unbusy(mp, p);
  		return (error);
  	}
 +	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  	/*
  	 * Put the new filesystem on the mount list after root.
  	 */
  	cache_purge(vp);
  	if (!error) {
 +		simple_lock(&vp->v_interlock);
 +		vp->v_flag &= ~VMOUNT;
 +		vp->v_mountedhere = mp;
 +		simple_unlock(&vp->v_interlock);
  		simple_lock(&mountlist_slock);
  		CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
  		simple_unlock(&mountlist_slock);
 @@ -300,7 +319,9 @@
  		if (error = VFS_START(mp, 0, p))
  			vrele(vp);
  	} else {
 -		mp->mnt_vnodecovered->v_mountedhere = (struct mount *)0;
 +		simple_lock(&vp->v_interlock);
 +		vp->v_flag &= ~VMOUNT;
 +		simple_unlock(&vp->v_interlock);
  		mp->mnt_vfc->vfc_refcount--;
  		vfs_unbusy(mp, p);
  		free((caddr_t)mp, M_MOUNT);
 Index: sbin/mount/mntopts.h
 ===================================================================
 RCS file: /home/ncvs/src/sbin/mount/mntopts.h,v
 retrieving revision 1.12
 diff -u -r1.12 mntopts.h
 --- mntopts.h	1997/11/13 00:28:48	1.12
 +++ mntopts.h	1998/02/14 00:02:31
 @@ -61,6 +61,7 @@
  #define MOPT_UPDATE		{ "update",	0, MNT_UPDATE, 0 }
  #define MOPT_RO			{ "ro",		0, MNT_RDONLY, 0 }
  #define MOPT_RW			{ "rw",		1, MNT_RDONLY, 0 }
 +#define MOPT_OVERLAY		{ "overlay",	0, MNT_OVERLAY, 0 }
  
  /* This is parsed by mount(8), but is ignored by specific mount_*(8)s. */
  #define MOPT_AUTO		{ "auto",	0, 0, 0 }
 @@ -83,7 +84,8 @@
  	MOPT_RDONLY,							\
  	MOPT_UNION,							\
  	MOPT_NOCLUSTERR,						\
 -	MOPT_NOCLUSTERW
 +	MOPT_NOCLUSTERW,						\
 +	MOPT_OVERLAY
  
  void getmntopts __P((const char *, const struct mntopt *, int *, int *));
  extern int getmnt_silent;
 Index: sbin/mount/mount.8
 ===================================================================
 RCS file: /home/ncvs/src/sbin/mount/mount.8,v
 retrieving revision 1.21
 diff -u -r1.21 mount.8
 --- mount.8	1997/12/01 00:44:16	1.21
 +++ mount.8	1998/02/14 00:08:01
 @@ -40,13 +40,13 @@
  .Nd mount file systems
  .Sh SYNOPSIS
  .Nm mount
 -.Op Fl adfpruvw
 +.Op Fl Oadfpruvw
  .Op Fl t Ar ufs | lfs | external_type
  .Nm mount
 -.Op Fl dfpruvw
 +.Op Fl Odfpruvw
  .Ar special | node
  .Nm mount
 -.Op Fl dfpruvw
 +.Op Fl Odfpruvw
  .Op Fl o Ar options
  .Op Fl t Ar ufs | lfs | external_type
  .Ar special node
 @@ -75,6 +75,10 @@
  .Pp
  The options are as follows:
  .Bl -tag -width indent
 +.It Fl O
 +Allows mount on top of existing mount points. Without this option,
 +attempting to mount a file system over an existing mount point will
 +result in the error "Device busy".
  .It Fl a
  All the filesystems described in
  .Xr fstab 5
 Index: sbin/mount/mount.c
 ===================================================================
 RCS file: /home/ncvs/src/sbin/mount/mount.c,v
 retrieving revision 1.21
 diff -u -r1.21 mount.c
 --- mount.c	1997/11/13 00:28:49	1.21
 +++ mount.c	1998/02/14 00:05:52
 @@ -129,8 +129,11 @@
  	options = NULL;
  	vfslist = NULL;
  	vfstype = "ufs";
 -	while ((ch = getopt(argc, argv, "adfo:prwt:uv")) != -1)
 +	while ((ch = getopt(argc, argv, "Oadfo:prwt:uv")) != -1)
  		switch (ch) {
 +		case 'O':
 +			init_flags |= MNT_OVERLAY;
 +			break;
  		case 'a':
  			all = 1;
  			break;
 @@ -375,12 +378,15 @@
  	}
  	optbuf = catopt(strdup(mntopts), options);
  
 -	if (strcmp(name, "/") == 0)
 +	if ((strcmp(name, "/") == 0) &&
 +	    (flags & MNT_OVERLAY) == 0) 
  		flags |= MNT_UPDATE;
  	if (flags & MNT_FORCE)
  		optbuf = catopt(optbuf, "force");
  	if (flags & MNT_RDONLY)
  		optbuf = catopt(optbuf, "ro");
 +	if (flags & MNT_OVERLAY)
 +		optbuf = catopt(optbuf, "overlay");
  	/*
  	 * XXX
  	 * The mount_mfs (newfs) command uses -o to select the

From: Tor Egge <Tor.Egge@idi.ntnu.no>
To: freebsd-gnats-submit@FreeBSD.ORG
Cc:  Subject: re: kern/1067: panic: ufs_lock: recursive lock not expected, pid: 27195
Date: Sat, 14 Feb 1998 03:12:05 +0100

 I wrote:
 > Then	
 > 	mount /dev/fd0 /
 > would give 
 > 	/dev/fd0 on /: Device busy
 
 Incorrect.
 
 The mount command (not the system call) handles "/" specially, and adds
 an implicit MNT_UPDATE option, thus the result is normally
 	/dev/fd0 on /: Specified device does not match mounted device.
 with or without the suggested fix.
 
 - Tor Egge
State-Changed-From-To: suspended->closed 
State-Changed-By: jkoshy 
State-Changed-When: Wed Nov 18 19:15:38 PST 1998 
State-Changed-Why:  
Was fixed by tegge in rev 1.106 of "src/sys/kern/vfs_syscalls.c". 
>Unformatted:
