On Mon, Jun 20, 2005 at 09:31:26PM +0530, Suparna Bhattacharya wrote: > Here is a little bit of background on the motivation behind this set of > patches to update AIO for filtered wakeups: > > (a) Since the introduction of filtered wakeups support and > the wait_bit_queue infrastructure in mainline, it is no longer > sufficient to just embed a wait queue entry in the kiocb > for AIO operations involving filtered wakeups. > (b) Given that filesystem reads/writes use filtered wakeups underlying > wait_on_page_bit, fixing this becomes a pre-req for buffered > filesystem AIO. > (c) The wait_bit_queue infrastructure actually enables a cleaner > implementation of filesystem AIO because it already provides > for an action routine intended to allow both blocking and > non-blocking or asynchronous behaviour. > >> Updated to apply to 2.6.12-rc6. Add a wait queue parameter to the action routine called by __wait_on_bit to allow it to determine whether to block or not. Signed-off-by: Suparna Bhattacharya Signed-off-by: Benjamin LaHaise diff -purN --exclude=description 60_pipe_aio/fs/buffer.c 71_wait_on_bit/fs/buffer.c --- 60_pipe_aio/fs/buffer.c 2005-08-04 15:55:50.000000000 -0400 +++ 71_wait_on_bit/fs/buffer.c 2005-08-08 17:15:51.000000000 -0400 @@ -53,7 +53,7 @@ init_buffer(struct buffer_head *bh, bh_e bh->b_private = private; } -static int sync_buffer(void *word) +static int sync_buffer(void *word, wait_queue_t *wait) { struct block_device *bd; struct buffer_head *bh diff -purN --exclude=description 60_pipe_aio/fs/inode.c 71_wait_on_bit/fs/inode.c --- 60_pipe_aio/fs/inode.c 2005-08-04 15:55:51.000000000 -0400 +++ 71_wait_on_bit/fs/inode.c 2005-08-08 17:15:51.000000000 -0400 @@ -1279,7 +1279,7 @@ void remove_dquot_ref(struct super_block #endif -int inode_wait(void *word) +int inode_wait(void *word, wait_queue_t *wait) { schedule(); return 0; diff -purN --exclude=description 60_pipe_aio/include/linux/wait.h 71_wait_on_bit/include/linux/wait.h --- 60_pipe_aio/include/linux/wait.h 2005-08-04 15:56:07.000000000 -0400 +++ 71_wait_on_bit/include/linux/wait.h 2005-08-08 17:15:51.000000000 -0400 @@ -140,11 +140,15 @@ void FASTCALL(__wake_up(wait_queue_head_ extern void FASTCALL(__wake_up_locked(wait_queue_head_t *q, unsigned int mode)); extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr)); void FASTCALL(__wake_up_bit(wait_queue_head_t *, void *, int)); -int FASTCALL(__wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned)); -int FASTCALL(__wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned)); +int FASTCALL(__wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, + int (*)(void *, wait_queue_t *), unsigned)); +int FASTCALL(__wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, + int (*)(void *, wait_queue_t *), unsigned)); void FASTCALL(wake_up_bit(void *, int)); -int FASTCALL(out_of_line_wait_on_bit(void *, int, int (*)(void *), unsigned)); -int FASTCALL(out_of_line_wait_on_bit_lock(void *, int, int (*)(void *), unsigned)); +int FASTCALL(out_of_line_wait_on_bit(void *, int, int (*)(void *, + wait_queue_t *), unsigned)); +int FASTCALL(out_of_line_wait_on_bit_lock(void *, int, int (*)(void *, + wait_queue_t *), unsigned)); wait_queue_head_t *FASTCALL(bit_waitqueue(void *, int)); #define wake_up(x) __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1, NULL) @@ -422,7 +426,8 @@ int wake_bit_function(wait_queue_t *wait * but has no intention of setting it. */ static inline int wait_on_bit(void *word, int bit, - int (*action)(void *), unsigned mode) + int (*action)(void *, wait_queue_t *), + unsigned mode) { if (!test_bit(bit, word)) return 0; @@ -446,7 +451,8 @@ static inline int wait_on_bit(void *word * clear with the intention of setting it, and when done, clearing it. */ static inline int wait_on_bit_lock(void *word, int bit, - int (*action)(void *), unsigned mode) + int (*action)(void *, wait_queue_t *), + unsigned mode) { if (!test_and_set_bit(bit, word)) return 0; diff -purN --exclude=description 60_pipe_aio/include/linux/writeback.h 71_wait_on_bit/include/linux/writeback.h --- 60_pipe_aio/include/linux/writeback.h 2005-08-04 15:56:07.000000000 -0400 +++ 71_wait_on_bit/include/linux/writeback.h 2005-08-08 17:15:51.000000000 -0400 @@ -70,7 +70,7 @@ struct writeback_control { */ void writeback_inodes(struct writeback_control *wbc); void wake_up_inode(struct inode *inode); -int inode_wait(void *); +int inode_wait(void *, wait_queue_t *); void sync_inodes_sb(struct super_block *, int wait); void sync_inodes(int wait); diff -purN --exclude=description 60_pipe_aio/kernel/wait.c 71_wait_on_bit/kernel/wait.c --- 60_pipe_aio/kernel/wait.c 2004-12-24 16:35:27.000000000 -0500 +++ 71_wait_on_bit/kernel/wait.c 2005-08-08 17:15:51.000000000 -0400 @@ -152,14 +152,14 @@ EXPORT_SYMBOL(wake_bit_function); */ int __sched fastcall __wait_on_bit(wait_queue_head_t *wq, struct wait_bit_queue *q, - int (*action)(void *), unsigned mode) + int (*action)(void *, wait_queue_t *), unsigned mode) { int ret = 0; do { prepare_to_wait(wq, &q->wait, mode); if (test_bit(q->key.bit_nr, q->key.flags)) - ret = (*action)(q->key.flags); + ret = (*action)(q->key.flags, &q->wait); } while (test_bit(q->key.bit_nr, q->key.flags) && !ret); finish_wait(wq, &q->wait); return ret; @@ -167,7 +167,8 @@ __wait_on_bit(wait_queue_head_t *wq, str EXPORT_SYMBOL(__wait_on_bit); int __sched fastcall out_of_line_wait_on_bit(void *word, int bit, - int (*action)(void *), unsigned mode) + int (*action)(void *, wait_queue_t *), + unsigned mode) { wait_queue_head_t *wq = bit_waitqueue(word, bit); DEFINE_WAIT_BIT(wait, word, bit); @@ -178,14 +179,14 @@ EXPORT_SYMBOL(out_of_line_wait_on_bit); int __sched fastcall __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, - int (*action)(void *), unsigned mode) + int (*action)(void *, wait_queue_t *), unsigned mode) { int ret = 0; do { prepare_to_wait_exclusive(wq, &q->wait, mode); if (test_bit(q->key.bit_nr, q->key.flags)) { - if ((ret = (*action)(q->key.flags))) + if ((ret = (*action)(q->key.flags, &q->wait))) break; } } while (test_and_set_bit(q->key.bit_nr, q->key.flags)); @@ -195,7 +196,8 @@ __wait_on_bit_lock(wait_queue_head_t *wq EXPORT_SYMBOL(__wait_on_bit_lock); int __sched fastcall out_of_line_wait_on_bit_lock(void *word, int bit, - int (*action)(void *), unsigned mode) + int (*action)(void *, wait_queue_t *wait), + unsigned mode) { wait_queue_head_t *wq = bit_waitqueue(word, bit); DEFINE_WAIT_BIT(wait, word, bit); diff -purN --exclude=description 60_pipe_aio/mm/filemap.c 71_wait_on_bit/mm/filemap.c --- 60_pipe_aio/mm/filemap.c 2005-08-08 17:15:32.000000000 -0400 +++ 71_wait_on_bit/mm/filemap.c 2005-08-08 17:15:51.000000000 -0400 @@ -126,7 +126,7 @@ void remove_from_page_cache(struct page write_unlock_irq(&mapping->tree_lock); } -static int sync_page(void *word) +static int sync_page(void *word, wait_queue_t *wait) { struct address_space *mapping; struct page *page;