Messages in this thread Patch in this message | | | Date | Mon, 19 Feb 2001 22:51:36 -0200 (BRST) | From | Marcelo Tosatti <> | Subject | Re: [PATCH] exclusive wakeup for lock_buffer |
| |
On Mon, 19 Feb 2001, Linus Torvalds wrote:
> > > On Mon, 19 Feb 2001, Marcelo Tosatti wrote: > > > > The following patch makes lock_buffer() use the exclusive wakeup scheme > > added in 2.3. > > Ugh, This is horrible. > > You should NOT have one function that does two completely different things > depending on a flag. That way lies madness and bad coding habits. > > Just do two different functions - make one be "__wait_on_buffer()", and > the other be "__lock_buffer()". See how the page functions work. > > Linus
Ok.
--- linux/include/linux/locks.h.orig Mon Feb 19 23:16:50 2001 +++ linux/include/linux/locks.h Mon Feb 19 23:21:48 2001 @@ -13,6 +13,7 @@ * lock buffers. */ extern void __wait_on_buffer(struct buffer_head *); +extern void __lock_buffer(struct buffer_head *); extern inline void wait_on_buffer(struct buffer_head * bh) { @@ -22,8 +23,8 @@ extern inline void lock_buffer(struct buffer_head * bh) { - while (test_and_set_bit(BH_Lock, &bh->b_state)) - __wait_on_buffer(bh); + if (test_and_set_bit(BH_Lock, &bh->b_state)) + __lock_on_buffer(bh); } extern inline void unlock_buffer(struct buffer_head *bh) --- linux/fs/buffer.c.orig Mon Feb 19 23:09:31 2001 +++ linux/fs/buffer.c Mon Feb 19 23:31:25 2001 @@ -161,6 +161,30 @@ atomic_dec(&bh->b_count); } +void __lock_on_buffer(struct buffer_head * bh) +{ + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); + + atomic_inc(&bh->b_count); + add_wait_queue_exclusive(&bh->b_wait, &wait); + for(;;) { + set_task_state(tsk, TASK_UNINTERRUPTIBLE); + if (test_bit(BH_Lock, &bh->b_state)) { + run_task_queue(&tq_disk); + schedule(); + continue; + } + + if (!test_and_set_bit(BH_Lock, &bh->b_state)) + break; + } + tsk->state = TASK_RUNNING; + remove_wait_queue(&bh->b_wait, &wait); + atomic_dec(&bh->b_count); +} + + /* Call sync_buffers with wait!=0 to ensure that the call does not * return until all buffer writes have completed. Sync() may return * before the writes have finished; fsync() may not. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |