From d909b5635d25e0f8f1c8470e40dc0d4df32a4520 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 20 Sep 1999 16:19:24 +0000 Subject: [PATCH] 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 Submitted by: Tor.Egge@fast.no --- sys/kern/vfs_bio.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 2f8f85a53b30..9de72003c2ba 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -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);