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 >_at__at_ -682,8 +682,16 _at__at_ 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 != 0) { >+ /* getblk does truncation, if needed */ >+ bp = getblk(vp, -1 - lbn, osize, 0, 0, >+ GB_NOCREAT); >+ if (bp != NULL) { >+ bp->b_xflags |= BX_ALTDATA; >+ brelse(bp); >+ } > return (error); >+ } > bp->b_xflags |= BX_ALTDATA; > if (DOINGSOFTDEP(vp)) > softdep_setup_allocext(ip, lbn, >_at__at_ -699,8 +707,17 _at__at_ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, > error = ffs_alloc(ip, lbn, > ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]), > nsize, flags, cred, &newb); >- if (error) >+ if (error != 0) { >+ bp = getblk(vp, -1 - lbn, nsize, 0, 0, >+ GB_NOCREAT); >+ if (bp != NULL) { >+ bp->b_xflags |= BX_ALTDATA; >+ bp->b_flags |= B_RELBUF | B_INVAL; >+ bp->b_flags &= ~B_ASYNC; >+ brelse(bp); >+ } > return (error); >+ } > bp = getblk(vp, -1 - lbn, nsize, 0, 0, gbflags); > bp->b_blkno = fsbtodb(fs, newb); > bp->b_xflags |= BX_ALTDATA; I don't think this patch helped. I still get printf()s with b_xflags == 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 == 0 for all these files. They don't store any data, but if an application does a truncate(2) with length > 0, the di_size does get set non-zero. It is when one of these files hits the ffs_truncate() with the extended attribute buffer on it, that the panic() happens. (Most of them have di_size == 0 and return from the function in the code block that starts with "if (ip->I_size == length)" at around line#299, before the panic() check.) rickReceived on Sun Aug 12 2018 - 10:26:00 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:17 UTC