summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ffs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-07-11 19:11:40 +0000
committerkib <kib@FreeBSD.org>2015-07-11 19:11:40 +0000
commit969c638bab6fb75c02ed90c0ce3b115fbd437d52 (patch)
treec8dcaece162ce3c76f841f3163e82edd3a597651 /sys/ufs/ffs
parent42ea6b1b275e51f8fbe35033240cd5d41fd5d226 (diff)
downloadFreeBSD-src-969c638bab6fb75c02ed90c0ce3b115fbd437d52.zip
FreeBSD-src-969c638bab6fb75c02ed90c0ce3b115fbd437d52.tar.gz
MFC r284887:
Handle errors from background write of the cylinder group blocks. MFC r284927: Simplify code. Approved by: re (gjb)
Diffstat (limited to 'sys/ufs/ffs')
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c19
1 files changed, 18 insertions, 1 deletions
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);
/*
OpenPOWER on IntegriCloud