From 969c638bab6fb75c02ed90c0ce3b115fbd437d52 Mon Sep 17 00:00:00 2001 From: kib Date: Sat, 11 Jul 2015 19:11:40 +0000 Subject: MFC r284887: Handle errors from background write of the cylinder group blocks. MFC r284927: Simplify code. Approved by: re (gjb) --- sys/ufs/ffs/ffs_vfsops.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'sys/ufs/ffs') diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 53d85bd..26c0286 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -1977,12 +1977,19 @@ ffs_backgroundwritedone(struct buf *bp) BO_LOCK(bufobj); if ((origbp = gbincore(bp->b_bufobj, bp->b_lblkno)) == NULL) panic("backgroundwritedone: lost buffer"); + + /* + * We should mark the cylinder group buffer origbp as + * dirty, to not loose the failed write. + */ + if ((bp->b_ioflags & BIO_ERROR) != 0) + origbp->b_vflags |= BV_BKGRDERR; BO_UNLOCK(bufobj); /* * Process dependencies then return any unfinished ones. */ pbrelvp(bp); - if (!LIST_EMPTY(&bp->b_dep)) + if (!LIST_EMPTY(&bp->b_dep) && (bp->b_ioflags & BIO_ERROR) == 0) buf_complete(bp); #ifdef SOFTUPDATES if (!LIST_EMPTY(&bp->b_dep)) @@ -1994,6 +2001,15 @@ ffs_backgroundwritedone(struct buf *bp) */ bp->b_flags |= B_NOCACHE; bp->b_flags &= ~B_CACHE; + + /* + * Prevent brelse() from trying to keep and re-dirtying bp on + * errors. It causes b_bufobj dereference in + * bdirty()/reassignbuf(), and b_bufobj was cleared in + * pbrelvp() above. + */ + if ((bp->b_ioflags & BIO_ERROR) != 0) + bp->b_flags |= B_INVAL; bufdone(bp); BO_LOCK(bufobj); /* @@ -2055,6 +2071,7 @@ ffs_bufwrite(struct buf *bp) if (bp->b_vflags & BV_BKGRDINPROG) panic("bufwrite: still writing"); } + bp->b_vflags &= ~BV_BKGRDERR; BO_UNLOCK(bp->b_bufobj); /* -- cgit v1.1