Index: sys/ufs/ffs/ffs_vfsops.c =================================================================== --- sys/ufs/ffs/ffs_vfsops.c +++ sys/ufs/ffs/ffs_vfsops.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -1979,6 +1980,17 @@ if ((origbp = gbincore(bp->b_bufobj, bp->b_lblkno)) == NULL) panic("backgroundwritedone: lost buffer"); BO_UNLOCK(bufobj); + + KFAIL_POINT_CODE(DEBUG_FP, ffs_backgroundwritedone_error, + if ((int)bp->b_vp == RETURN_VALUE && + (bp->b_ioflags & BIO_ERROR) == 0) { + printf("%s: Erroring IO bp=%p bo=%p\n", __func__, bp, + bufobj); + bp->b_ioflags |= BIO_ERROR; + bp->b_error = EIO; + } + ); + /* * Process dependencies then return any unfinished ones. */ @@ -1995,6 +2007,13 @@ */ bp->b_flags |= B_NOCACHE; bp->b_flags &= ~B_CACHE; + /* + * Prevent brelse() from re-dirtying bp on errors. It causes b_bufobj + * dereference in bdirty/reassignbuf, and bufobj was cleared in pbrelvp + * above. + */ + if ((bp->b_ioflags & BIO_ERROR) != 0) + bp->b_flags |= B_INVAL; bufdone(bp); BO_LOCK(bufobj); /*