[patch for fs/buffer.c] Re: 2.1.82

Dr. Werner Fink (werner@suse.de)
Thu, 29 Jan 1998 00:18:37 +0100


>
> Hi,
>
> In a struct page, page->buffers->p_this_page is supposed to be a circular
> list. I got an oops because one of the pointers in the list was NULL.
>
> Tim.
> */

Maybe the appended patch may solve/reduce this sort of oops. This one also
contains a simple speed up by a smarter handling of reuse_list ... (s.b. has
told me that xchg in recover_reusable_buffer_heads is expensive for alpha :)
Nevertheless at the end of create_buffers() the schedule() is only necessary
if reuse_list and unused_list is empty (no unused asynch buffer heads).

Werner

---------------------------------------------------------------------------
diff -ur linux-2.1.82/fs/buffer.c linux/fs/buffer.c
--- linux-2.1.82/fs/buffer.c Fri Jan 16 06:01:04 1998
+++ linux/fs/buffer.c Thu Jan 29 00:05:15 1998
@@ -1190,7 +1190,8 @@
{
struct buffer_head * bh;

- recover_reusable_buffer_heads();
+ if (reuse_list)
+ recover_reusable_buffer_heads();
if (nr_unused_buffer_heads > NR_RESERVED) {
bh = unused_list;
unused_list = bh->b_next_free;
@@ -1307,8 +1308,9 @@
*/
add_wait_queue(&buffer_wait, &wait);
current->state = TASK_UNINTERRUPTIBLE;
+ if (!unused_list && !reuse_list)
+ schedule();
recover_reusable_buffer_heads();
- schedule();
remove_wait_queue(&buffer_wait, &wait);
current->state = TASK_RUNNING;
goto try_again;
@@ -1486,14 +1488,16 @@
* and unlock_buffer(). */
} else {
unsigned long flags;
- clear_bit(PG_locked, &page->flags);
- set_bit(PG_uptodate, &page->flags);
- wake_up(&page->wait);
save_flags(flags);
cli();
free_async_buffers(bh);
restore_flags(flags);
+ clear_bit(PG_locked, &page->flags);
+ set_bit(PG_uptodate, &page->flags);
+ wake_up(&page->wait);
after_unlock_page(page);
+ if (waitqueue_active(&buffer_wait))
+ wake_up(&buffer_wait);
}
++current->maj_flt;
return 0;