Skip site navigation (1)Skip section navigation (2)
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>