Fix bug in brelse() regarding redirtying buffers on B_ERROR. brelse()

improperly ignored the B_INVAL flag when acting on the B_ERROR.
    If both B_INVAL and B_ERROR are set the buffer is typically out of the
    underlying device's block range and must be destroyed.  If only B_ERROR
    is set (for a write), a write error occured and operation remains as it
    was before:  the buffer must be redirtied to avoid corrupting the
    filesystem state.

Reviewed by:	David Greenman <dg@root.com>
Submitted by:	Tor.Egge@fast.no
This commit is contained in:
Matthew Dillon 1999-09-20 16:19:24 +00:00
parent 43834dfd27
commit d909b5635d

View File

@ -861,11 +861,13 @@ brelse(struct buf * bp)
if (bp->b_flags & B_LOCKED)
bp->b_flags &= ~B_ERROR;
if ((bp->b_flags & (B_READ | B_ERROR)) == B_ERROR) {
if ((bp->b_flags & (B_READ | B_ERROR | B_INVAL)) == B_ERROR) {
/*
* Failed write, redirty. Must clear B_ERROR to prevent
* pages from being scrapped. Note: B_INVAL is ignored
* here but will presumably be dealt with later.
* pages from being scrapped. If B_INVAL is set then
* this case is not run and the next case is run to
* destroy the buffer. B_INVAL can occur if the buffer
* is outside the range supported by the underlying device.
*/
bp->b_flags &= ~B_ERROR;
bdirty(bp);