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--