From: William Lee Irwin III Now, make bh's use the new wakeup primitive also. This has the bugfix vs. the prior version that autoremoved waitqueue wakeup functions are made to match autoremove API usage in __wait_event_filtered(). --- 25-akpm/fs/buffer.c | 8 ++++---- 25-akpm/fs/jbd/transaction.c | 2 +- 25-akpm/include/linux/wait.h | 25 +++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 7 deletions(-) diff -puN fs/buffer.c~filtered-buffer_head-wakeups fs/buffer.c --- 25/fs/buffer.c~filtered-buffer_head-wakeups 2004-05-04 23:56:32.433720120 -0700 +++ 25-akpm/fs/buffer.c 2004-05-04 23:56:32.446718144 -0700 @@ -74,7 +74,7 @@ void wake_up_buffer(struct buffer_head * smp_mb(); if (waitqueue_active(wq)) - wake_up_all(wq); + wake_up_filtered(wq, bh); } EXPORT_SYMBOL(wake_up_buffer); @@ -93,10 +93,10 @@ void fastcall unlock_buffer(struct buffe void __wait_on_buffer(struct buffer_head * bh) { wait_queue_head_t *wqh = bh_waitq_head(bh); - DEFINE_WAIT(wait); + DEFINE_FILTERED_WAIT(wait, bh); do { - prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE); + prepare_to_wait(wqh, &wait.wait, TASK_UNINTERRUPTIBLE); if (buffer_locked(bh)) { struct block_device *bd; smp_mb(); @@ -106,7 +106,7 @@ void __wait_on_buffer(struct buffer_head io_schedule(); } } while (buffer_locked(bh)); - finish_wait(wqh, &wait); + finish_wait(wqh, &wait.wait); } static void diff -puN fs/jbd/transaction.c~filtered-buffer_head-wakeups fs/jbd/transaction.c --- 25/fs/jbd/transaction.c~filtered-buffer_head-wakeups 2004-05-04 23:56:32.435719816 -0700 +++ 25-akpm/fs/jbd/transaction.c 2004-05-04 23:56:32.447717992 -0700 @@ -638,7 +638,7 @@ repeat: jbd_unlock_bh_state(bh); /* commit wakes up all shadow buffers after IO */ wqh = bh_waitq_head(jh2bh(jh)); - wait_event(*wqh, (jh->b_jlist != BJ_Shadow)); + wait_event_filtered(*wqh, jh2bh(jh), (jh->b_jlist != BJ_Shadow)); goto repeat; } diff -puN include/linux/wait.h~filtered-buffer_head-wakeups include/linux/wait.h --- 25/include/linux/wait.h~filtered-buffer_head-wakeups 2004-05-04 23:56:32.438719360 -0700 +++ 25-akpm/include/linux/wait.h 2004-05-04 23:56:32.448717840 -0700 @@ -146,7 +146,6 @@ do { \ break; \ __wait_event(wq, condition); \ } while (0) - #define __wait_event_interruptible(wq, condition, ret) \ do { \ wait_queue_t __wait; \ @@ -273,7 +272,29 @@ int autoremove_wake_function(wait_queue_ .task_list = LIST_HEAD_INIT(name.wait.task_list),\ }, \ } - + +#define __wait_event_filtered(wq, key, condition) \ +do { \ + DEFINE_FILTERED_WAIT(__wait, key); \ + wait_queue_head_t *__wqh = &(wq); \ + wait_queue_t *__wqe = &__wait.wait; \ + \ + for (;;) { \ + prepare_to_wait(__wqh, __wqe, TASK_UNINTERRUPTIBLE); \ + if (condition) \ + break; \ + schedule(); \ + } \ + finish_wait(__wqh, __wqe); \ +} while (0) + + +#define wait_event_filtered(wq, key, condition) \ +do { \ + if (!(condition)) \ + __wait_event_filtered(wq, key, condition); \ +} while (0) + #endif /* __KERNEL__ */ #endif _