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>