Date: Sun, 12 Aug 2018 12:25:58 +0000 From: Rick Macklem <rmacklem@uoguelph.ca> To: Konstantin Belousov <kostikbel@gmail.com> Cc: "freebsd-current@FreeBSD.org" <freebsd-current@FreeBSD.org>, "peter@holm.cc" <peter@holm.cc> Subject: Re: ffs_truncate3 panics Message-ID: <YTOPR0101MB1820997D02892275A0FE8055DD3A0@YTOPR0101MB1820.CANPRD01.PROD.OUTLOOK.COM> In-Reply-To: <20180811123755.GD2113@kib.kiev.ua> References: <YTOPR0101MB18206289DDED97BE9DD38D14DD270@YTOPR0101MB1820.CANPRD01.PROD.OUTLOOK.COM> <20180807131445.GC1884@kib.kiev.ua> <YTOPR0101MB18207C97903D3058A15091FFDD260@YTOPR0101MB1820.CANPRD01.PROD.OUTLOOK.COM> <20180808221647.GH1884@kib.kiev.ua> <YTOPR0101MB18205CDE34ABCC2345C3F172DD250@YTOPR0101MB1820.CANPRD01.PROD.OUTLOOK.COM> <20180809111004.GK1884@kib.kiev.ua> <YTOPR0101MB182067FF6F908E0B2EBAE3D1DD250@YTOPR0101MB1820.CANPRD01.PROD.OUTLOOK.COM> <20180810172941.GA2113@kib.kiev.ua> <YTOPR0101MB18203F316E929C7AF7576BF0DD3B0@YTOPR0101MB1820.CANPRD01.PROD.OUTLOOK.COM>, <20180811123755.GD2113@kib.kiev.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
Konstantin Belousov wrote:
[stuff snipped]
>Problem with this buffer is that BX_ALTDATA bit is not set.
>This is the reason why vinvalbuf(V_ALT) skips it.
[more stuff snipped]
>The vnode is exclusively locked. Other thread must not be able to
>instantiate a buffer under us.
That's what I thought, but I wasn't sure that UFS never did anything to the=
buffers
without the vnode lock.
[more stuff snipped]
>This is the patch that I posted long time ago. It is obviously related
>to missed BX_ALTDATA. Can you add this patch to your kernel ?
>
>diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c
>index 552c295753d..6d89a229ea7 100644
>--- a/sys/ufs/ffs/ffs_balloc.c
>+++ b/sys/ufs/ffs/ffs_balloc.c
>@@ -682,8 +682,16 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, =
int size,
> ffs_blkpref_ufs2(ip, lbn, (int)lbn,
> &dp->di_extb[0]), osize, nsize, flags,
> cred, &bp);
>- if (error)
>+ if (error !=3D 0) {
>+ /* getblk does truncation, if need=
ed */
>+ bp =3D getblk(vp, -1 - lbn, osize,=
0, 0,
>+ GB_NOCREAT);
>+ if (bp !=3D NULL) {
>+ bp->b_xflags |=3D BX_ALTDA=
TA;
>+ brelse(bp);
>+ }
> return (error);
>+ }
> bp->b_xflags |=3D BX_ALTDATA;
> if (DOINGSOFTDEP(vp))
> softdep_setup_allocext(ip, lbn,
>@@ -699,8 +707,17 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, =
int size,
> error =3D ffs_alloc(ip, lbn,
> ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_ext=
b[0]),
> nsize, flags, cred, &newb);
>- if (error)
>+ if (error !=3D 0) {
>+ bp =3D getblk(vp, -1 - lbn, nsize, 0, 0,
>+ GB_NOCREAT);
>+ if (bp !=3D NULL) {
>+ bp->b_xflags |=3D BX_ALTDATA;
>+ bp->b_flags |=3D B_RELBUF | B_INVA=
L;
>+ bp->b_flags &=3D ~B_ASYNC;
>+ brelse(bp);
>+ }
> return (error);
>+ }
> bp =3D getblk(vp, -1 - lbn, nsize, 0, 0, gbflags);
> bp->b_blkno =3D fsbtodb(fs, newb);
> bp->b_xflags |=3D BX_ALTDATA;
I don't think this patch helped. I still get printf()s with b_xflags =3D=3D=
clear with it
applied. I haven't gotten one that would cause the panic yet, but it didn't
make the BX_ALTDATA flag get set.
However, I have narrowed down how the ones that cause a panic() occur.
Turns out I was wrong when I said di_size =3D=3D 0 for all these files.
They don't store any data, but if an application does a truncate(2) with le=
ngth > 0,
the di_size does get set non-zero.
It is when one of these files hits the ffs_truncate() with the extended att=
ribute
buffer on it, that the panic() happens.
(Most of them have di_size =3D=3D 0 and return from the function in the cod=
e block
that starts with "if (ip->I_size =3D=3D length)" at around line#299, befor=
e the panic()
check.)
rick
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?YTOPR0101MB1820997D02892275A0FE8055DD3A0>
