Danny wrote:
Yup... keep meaning to get to this one.
I don't think the error ever occurs since we never hit the bug.
> 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
--
Russell Cattelan
--
Digital Elves inc. -- Currently on loan to SGI
Linux XFS core developer.
|