Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Dec 2008 14:07:36 +0200
From:      Kostik Belousov <kostikbel@gmail.com>
To:        Frode Nordahl <frode@nordahl.net>
Cc:        freebsd-stable@freebsd.org
Subject:   Re: FreeBSD 7.1-PRERELEASE-p1, panic: dqget: free dquot isn't
Message-ID:  <20081204120736.GC2038@deviant.kiev.zoral.com.ua>
In-Reply-To: <8A6A8FA5-07A6-4A12-B9AD-6E77E534CED7@nordahl.net>
References:  <3B675385-956D-4A26-8E09-E338DF7D7244@nordahl.net> <20081203173939.GA2401@deviant.kiev.zoral.com.ua> <F88AD2CD-04BA-46E5-93B9-A06558136D31@nordahl.net> <20081203194348.GB2401@deviant.kiev.zoral.com.ua> <8A6A8FA5-07A6-4A12-B9AD-6E77E534CED7@nordahl.net>

next in thread | previous in thread | raw e-mail | index | archive | help

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

On Thu, Dec 04, 2008 at 08:12:45AM +0100, Frode Nordahl wrote:
> On 3. des.. 2008, at 20.43, Kostik Belousov wrote:
>=20
> >On Wed, Dec 03, 2008 at 08:12:22PM +0100, Frode Nordahl wrote:
> >>(moved to freebsd-stable)
> >>
> >>On 3. des.. 2008, at 18.39, Kostik Belousov wrote:
> >>
> >>>>db> where
> >>>>Tracing pid 41111 tid 100199 td 0xffffff0056f1f370
> >>>>kdb_enter_why() at kdb_enter_why+0x3d
> >>>>panic() at panic+0x17b
> >>>>dqget() at dqget+0xaa4
> >>>>getinoquota() at getinoquota+0x5b
> >>>>ufs_access() at ufs_access+0x28c
> >>>>ufs_lookup() at ufs_lookup+0x9fe
> >>>>vfs_cache_lookup() at vfs_cache_lookup+0xf8
> >>>>VOP_LOOKUP_APV() at VOP_LOOKUP_APV+0x40
> >>>>lookup() at lookup+0x531
> >>>>namei() at namei+0x35d
> >>>>kern_rmdir() at kern_rmdir+0xbd
> >>>>syscall() at syscall+0x256
> >>>>Xfast_syscall() at Xfast_syscall+0xab
> >>>
> >>>For the start, I want to see the content of the *dq in the dqget()
> >>>frame.
> >>
> >>
> >>I am unable to get to *dq :-(
> >>
> >>(kgdb) frame 10
> >>#10 0xffffffff806dbc54 in dqget (vp=3D0xffffff011e0767e0, id=3D419444,
> >>   ump=3D0xffffff00038a9000, type=3D0, dqp=3D0xffffff0122e47268)
> >>   at /usr/src/sys/ufs/ufs/ufs_quota.c:1210
> >>1210				panic("dqget: free dquot isn't");
> >If this is repeatable, change panic to
> >	panic("dqget: free dquot isn't %p", dq);
> >
> >and then in kgdb p/x *(struct dquot *)<printed value>
>=20
> Got it!
>=20
> panic: dqget: free dquot isn't dq=3D0xffffff00b3d27000
> (kgdb) p/x *(struct dquot *)0xffffff00b3d27000
> $1 =3D {dq_hash =3D {le_next =3D 0x0, le_prev =3D 0xffffff010b9da700}, =
=20
> dq_freelist =3D {
>     tqe_next =3D 0xffffff0055e2de00, tqe_prev =3D 0xffffffff80b03710}, =
=20
> dq_lock =3D {
>     lock_object =3D {lo_name =3D 0xffffffff8088c21c, lo_type =3D =20
> 0xffffffff8088c21c,
>       lo_flags =3D 0x1030000, lo_witness_data =3D {lod_list =3D {stqe_nex=
t =20
> =3D 0x0},
>         lod_witness =3D 0x0}}, mtx_lock =3D 0x4, mtx_recurse =3D 0x0},
>   dq_flags =3D 0xc, dq_type =3D 0x0, dq_cnt =3D 0x0, dq_id =3D 0x16a37d,
>   dq_ump =3D 0xffffff00038e1600, dq_dqb =3D {dqb_bhardlimit =3D 0x0,
>     dqb_bsoftlimit =3D 0x0, dqb_curblocks =3D 0x0, dqb_ihardlimit =3D 0x0,
>     dqb_isoftlimit =3D 0x0, dqb_curinodes =3D 0x1, dqb_btime =3D 0x493ef2=
b5,
>     dqb_itime =3D 0x493ef2b5}}
>=20
> Let me know if I can provide any more information!
>=20
> Updated the crashinfo archive you got an URL to yesterday if you want =20
> to poke around yourself.

Please, try the patch below, it should fix a race I see. Quite possible,
this is what you tripped over.

On the other hand, dq_id =3D=3D 1483645 looks very suspicious. Do you
actually have such large uid in the system ? Could it be that you have
file on fs owned by such uid ?

diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c
index e5cb956..0c8209a 100644
--- a/sys/ufs/ufs/ufs_quota.c
+++ b/sys/ufs/ufs/ufs_quota.c
@@ -1262,7 +1262,7 @@ dqrele(struct vnode *vp, struct dquot *dq)
 		return;
 	}
 	DQH_UNLOCK();
-
+sync:
 	(void) dqsync(vp, dq);
=20
 	DQH_LOCK();
@@ -1271,6 +1271,18 @@ dqrele(struct vnode *vp, struct dquot *dq)
 		DQH_UNLOCK();
 		return;
 	}
+
+	/*
+	 * The dq may become dirty after it is synced but before it is
+	 * put to the free list. Checking the DQ_MOD there without
+	 * locking dq should be safe since no other references to the
+	 * dq exist.
+	 */
+	if ((dq->dq_flags & DQ_MOD) !=3D 0) {
+		dq->dq_cnt++;
+		DQH_UNLOCK();
+		goto sync;
+	}
 	TAILQ_INSERT_TAIL(&dqfreelist, dq, dq_freelist);
 	DQH_UNLOCK();
 }

--qtZFehHsKgwS5rPz
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (FreeBSD)

iEYEARECAAYFAkk3yAgACgkQC3+MBN1Mb4jZ+ACgq+QZ3rjGVNNqFCXYuAsE4lt7
LpYAoPYyQl+nCrKWLd0myqKa97NXddG5
=foB/
-----END PGP SIGNATURE-----

--qtZFehHsKgwS5rPz--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20081204120736.GC2038>