[patch] WRITEA and lost dirty flag (fs-corruption)

Andrea Arcangeli (andrea@suse.de)
Mon, 9 Aug 1999 01:04:59 +0200 (CEST)


As you Linus discovered last month, the WRITEA operations forget to
restore the BH_Dirty bit while giving up due out of request-slots (and
doing that it will almost sure trigger bad fs corruption).

So here it is the fix against 2.3.13-pre8:

--- tmp/drivers/block/ll_rw_blk.c.~1~ Mon Aug 9 00:49:51 1999
+++ tmp/drivers/block/ll_rw_blk.c Mon Aug 9 00:54:30 1999
@@ -565,7 +565,7 @@
/* if no request available: if rw_ahead, forget it; otherwise try again blocking.. */
if (!req) {
if (rw_ahead)
- goto end_io;
+ goto failed_ahead;
req = __get_request_wait(max_req, bh->b_rdev);
}

@@ -583,6 +583,16 @@
add_request(major+blk_dev,req);
return;

+failed_ahead:
+ switch (rw)
+ {
+ case WRITE:
+ /* nobody can write to a buffer while it's locked */
+ if (test_and_set_bit(BH_Dirty, &bh->b_state))
+ BUG();
+ refile_buffer(bh);
+ break;
+ }
end_io:
bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
}

Long ago I also noticed that the pagein/pageout stats (the one in vmstat
bi/bo fields) was accounting a failed (due out of request slots)
operation as a real write/read operation. This looks a bug to me so here
it is the fix incremental with the previous patch:

--- tmp/drivers/block/ll_rw_blk.c Mon Aug 9 00:57:05 1999
+++ tmp/drivers/block/ll_rw_blk.c1 Mon Aug 9 00:56:51 1999
@@ -586,11 +586,15 @@
failed_ahead:
switch (rw)
{
+ case READ:
+ kstat.pgpgin--;
+ break;
case WRITE:
/* nobody can write to a buffer while it's locked */
if (test_and_set_bit(BH_Dirty, &bh->b_state))
BUG();
refile_buffer(bh);
+ kstat.pgpgout--;
break;
}
end_io:

Andrea

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/