summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_bio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r--sys/kern/vfs_bio.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 63f9a34..f306b5a 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1566,6 +1566,12 @@ brelse(struct buf *bp)
return;
}
+ if ((bp->b_vflags & (BV_BKGRDINPROG | BV_BKGRDERR)) == BV_BKGRDERR) {
+ BO_LOCK(bp->b_bufobj);
+ bp->b_vflags &= ~BV_BKGRDERR;
+ BO_UNLOCK(bp->b_bufobj);
+ bdirty(bp);
+ }
if (bp->b_iocmd == BIO_WRITE && (bp->b_ioflags & BIO_ERROR) &&
bp->b_error == EIO && !(bp->b_flags & B_INVAL)) {
/*
@@ -1822,7 +1828,11 @@ bqrelse(struct buf *bp)
}
/* buffers with stale but valid contents */
- if (bp->b_flags & B_DELWRI) {
+ if ((bp->b_flags & B_DELWRI) != 0 || (bp->b_vflags & (BV_BKGRDINPROG |
+ BV_BKGRDERR)) == BV_BKGRDERR) {
+ BO_LOCK(bp->b_bufobj);
+ bp->b_vflags &= ~BV_BKGRDERR;
+ BO_UNLOCK(bp->b_bufobj);
qindex = QUEUE_DIRTY;
} else {
if ((bp->b_flags & B_DELWRI) == 0 &&
@@ -2341,6 +2351,16 @@ restart:
continue;
}
+ /*
+ * Requeue the background write buffer with error.
+ */
+ if ((bp->b_vflags & BV_BKGRDERR) != 0) {
+ bremfreel(bp);
+ mtx_unlock(&bqclean);
+ bqrelse(bp);
+ continue;
+ }
+
KASSERT(bp->b_qindex == qindex,
("getnewbuf: inconsistent queue %d bp %p", qindex, bp));
OpenPOWER on IntegriCloud