All,
A small patch follows. _pagebuf_page_io allocates buffer_heads, but on
any error loops through them, calling 'buffer_IO_error()' on each. This
is wrong, since buffer_IO_error calls 'refile_buffer()' which deletes
the bh from one list, and places it on another. Since these bhs were
never part of the internal lists, the next/prev pointers are NULL,
thereby corrupting the [to] list.
The attached patch performs the same steps as 'buffer_IO_error()', but
without the 'refile_buffer()' call.
Enjoy!
==========================================================================
--- linux.sgi/fs/pagebuf/page_buf.c Wed Feb 14 09:34:15 2001
+++ linux.hacked/fs/pagebuf/page_buf.c Wed Feb 21 09:17:54 2001
@@ -455,7 +455,6 @@
struct page **pages)
{
loff_t next_buffer_offset;
- loff_t next_desired_offset;
unsigned long page_count;
int rval;
struct kiobuf *kp;
@@ -1319,6 +1318,7 @@
int cnt,itr;
pagesync_t *psync;
struct buffer_head *bh;
+ struct buffer_head **bhp;
off_t blk_offset;
size_t blk_length;
int err=0;
@@ -1424,8 +1424,9 @@
return err;
error:
/* If we ever do get here then clean up what we already did */
- for (itr=0; itr < cnt; itr++) {
- buffer_IO_error(psync->bh[itr]);
+ for (bhp = psync->bh; bhp < psync->bh + cnt; ++bhp) {
+ atomic_set_buffer_clean (*bhp);
+ (*bhp)->b_end_io (*bhp, 0);
}
return err;
}
==============================================================================
--
"Men occasionally stumble over the truth, but most of them pick
themselves up and hurry off as if nothing had happened."
-- Winston Churchill
Danny
|