The error classification from lower layers is a poor indicator of
whether an error is recoverable. Always re-dirty the buffer on errors from write requests. The invalidation we used to do for errors not EIO doesn't need to be done for a device that's really gone, since that's done in a different path. Reviewed by: mckusick@, kib@
This commit is contained in:
parent
5ad4c45cb8
commit
6471aad35d
@ -2266,19 +2266,17 @@ brelse(struct buf *bp)
|
||||
bdirty(bp);
|
||||
}
|
||||
if (bp->b_iocmd == BIO_WRITE && (bp->b_ioflags & BIO_ERROR) &&
|
||||
bp->b_error == EIO && !(bp->b_flags & B_INVAL)) {
|
||||
!(bp->b_flags & B_INVAL)) {
|
||||
/*
|
||||
* Failed write, redirty. Must clear BIO_ERROR to prevent
|
||||
* pages from being scrapped. If the error is anything
|
||||
* other than an I/O error (EIO), assume that retrying
|
||||
* is futile.
|
||||
* pages from being scrapped.
|
||||
*/
|
||||
bp->b_ioflags &= ~BIO_ERROR;
|
||||
bdirty(bp);
|
||||
} else if ((bp->b_flags & (B_NOCACHE | B_INVAL)) ||
|
||||
(bp->b_ioflags & BIO_ERROR) || (bp->b_bufsize <= 0)) {
|
||||
/*
|
||||
* Either a failed I/O or we were asked to free or not
|
||||
* Either a failed read I/O or we were asked to free or not
|
||||
* cache the buffer.
|
||||
*/
|
||||
bp->b_flags |= B_INVAL;
|
||||
|
Loading…
Reference in New Issue
Block a user