MFC r284887:
Handle errors from background write of the cylinder group blocks. MFC r284927: Simplify code. Approved by: re (gjb)
This commit is contained in:
parent
42ea6b1b27
commit
969c638bab
@ -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 @@ getnewbuf_scan(int maxsize, int defrag, int unmapped, int metadata)
|
||||
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));
|
||||
|
||||
|
@ -248,8 +248,9 @@ struct buf {
|
||||
#define BV_SCANNED 0x00000001 /* VOP_FSYNC funcs mark written bufs */
|
||||
#define BV_BKGRDINPROG 0x00000002 /* Background write in progress */
|
||||
#define BV_BKGRDWAIT 0x00000004 /* Background write waiting */
|
||||
#define BV_BKGRDERR 0x00000008 /* Error from background write */
|
||||
|
||||
#define PRINT_BUF_VFLAGS "\20\3bkgrdwait\2bkgrdinprog\1scanned"
|
||||
#define PRINT_BUF_VFLAGS "\20\4bkgrderr\3bkgrdwait\2bkgrdinprog\1scanned"
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user