patch-2.0.33 linux/fs/buffer.c
Next file: linux/fs/exec.c
Previous file: linux/drivers/scsi/aic7xxx_seq.h
Back to the patch index
Back to the overall index
- Lines: 55
- Date:
Wed Dec 10 18:09:44 1997
- Orig file:
v2.0.32/linux/fs/buffer.c
- Orig date:
Tue Dec 2 13:52:32 1997
diff -u --recursive --new-file v2.0.32/linux/fs/buffer.c linux/fs/buffer.c
@@ -601,6 +601,8 @@
nr_unused_buffer_heads++;
bh->b_next_free = unused_list;
unused_list = bh;
+ if (!waitqueue_active(&buffer_wait))
+ return;
wake_up(&buffer_wait);
}
@@ -983,6 +985,7 @@
static void get_more_buffer_heads(void)
{
+ struct wait_queue wait = { current, NULL };
struct buffer_head * bh;
while (!unused_list) {
@@ -1011,11 +1014,18 @@
* finishing IO..
*/
run_task_queue(&tq_disk);
- sleep_on(&buffer_wait);
+
/*
- * After we wake up, check for released async buffer heads.
+ * Set our state for sleeping, then check again for buffer heads.
+ * This ensures we won't miss a wake_up from an interrupt.
*/
+ add_wait_queue(&buffer_wait, &wait);
+ current->state = TASK_UNINTERRUPTIBLE;
+ if (!unused_list && !reuse_list)
+ schedule();
recover_reusable_buffer_heads();
+ remove_wait_queue(&buffer_wait, &wait);
+ current->state = TASK_RUNNING;
}
}
@@ -1192,13 +1202,13 @@
* 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);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov