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:
parent
43834dfd27
commit
d909b5635d
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user