Subject: Re: union mount/null mount problem
To: Eric Haszlakiewicz <erh@jodi.nimenees.com>
From: Bill Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 11/03/2004 12:41:04
--4zI0WCX1RcnW9Hbu
Content-Type: multipart/mixed; boundary="5QAgd0e35j3NYeGe"
Content-Disposition: inline


--5QAgd0e35j3NYeGe
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Nov 02, 2004 at 10:48:48AM -0600, Eric Haszlakiewicz wrote:
>=20
> 	I have a couple mount points that would be created by commands
> similar to these:
>=20
> mount_null /foo /mnt
> mount_union -b /bar /mnt
>=20
> Recently, I rebooted the machine that was setup this way and got a
> panic: "insmntque into dying filesystem".
> (insmntque, getnewvnode, union_allocvp, union_root, union_unmount)
> That was with sources from around Oct 14.
>=20
> I updated to sources as of Oct 26, and the problem was "fixed".
>=20
> Was this just luck, or does anyone remember actually fixing something
> that might have solved this problem?

I think it's just luck. I haven't had time to work on this, but the=20
problem is the union unmount code. For some reason I do not understand, it=
=20
insists on accessing the root vnode on the file system. If that node isn't=
=20
in cache, then we attempt to allocate it, which generates this panic.

There already is a PR for this. You need to have the root of the union
file system get reclaimed to see the bug. Something like a find in all the=
=20
other file systems on the box probably would do it.

Please try the attached patch.

Take care,

Bill

--5QAgd0e35j3NYeGe
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="union.diff"
Content-Transfer-Encoding: quoted-printable

--- union_vfsops.c.orig	Wed Nov  3 12:20:36 2004
+++ union_vfsops.c	Wed Nov  3 12:21:06 2004
@@ -339,7 +339,6 @@
 	struct proc *p;
 {
 	struct union_mount *um =3D MOUNTTOUNIONMOUNT(mp);
-	struct vnode *um_rootvp;
 	int error;
 	int freeing;
=20
@@ -347,9 +346,6 @@
 	printf("union_unmount(mp =3D %p)\n", mp);
 #endif
=20
-	if ((error =3D union_root(mp, &um_rootvp)) !=3D 0)
-		return (error);
-
 	/*
 	 * Keep flushing vnodes from the mount list.
 	 * This is needed because of the un_pvp held
@@ -359,7 +355,7 @@
 	 * (d) times, where (d) is the maximum tree depth
 	 * in the filesystem.
 	 */
-	for (freeing =3D 0; vflush(mp, um_rootvp, 0) !=3D 0;) {
+	for (freeing =3D 0; vflush(mp, NULLVP, 0) !=3D 0;) {
 		struct vnode *vp;
 		int n;
=20
@@ -382,18 +378,9 @@
 	 */
=20
 	if (mntflags & MNT_FORCE)
-		vflush(mp, um_rootvp, FORCECLOSE);
+		vflush(mp, NULLVP, FORCECLOSE);
 =09
=20
-	/* At this point the root vnode should have a single reference */
-	if (um_rootvp->v_usecount > 1) {
-		vput(um_rootvp);
-		return (EBUSY);
-	}
-
-#ifdef UNION_DIAGNOSTIC
-	vprint("union root", um_rootvp);
-#endif	=20
 	/*
 	 * Discard references to upper and lower target vnodes.
 	 */
@@ -401,14 +388,6 @@
 		vrele(um->um_lowervp);
 	vrele(um->um_uppervp);
 	crfree(um->um_cred);
-	/*
-	 * Release reference on underlying root vnode
-	 */
-	vput(um_rootvp);
-	/*
-	 * And blow it away for future re-use
-	 */
-	vgone(um_rootvp);
 	/*
 	 * Finally, throw away the union_mount structure
 	 */

--5QAgd0e35j3NYeGe--

--4zI0WCX1RcnW9Hbu
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (NetBSD)

iD4DBQFBiUJgWz+3JHUci9cRAhACAJiah+pLYtAkpvFOhUX/DOHMMcj1AJ9bEn5u
6fXHJFudtxVU0TBSDXBvVQ==
=E2I4
-----END PGP SIGNATURE-----

--4zI0WCX1RcnW9Hbu--