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 [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to