From: NeilBrown Date: Sat, 2 Oct 2010 02:41:00 +0000 (+1000) Subject: Use wait_on_bit / wake_bit to get more wait_queues X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=6397bc6942c9e9d7dcd11ab7c203e6dee9750d85;p=LaFS.git Use wait_on_bit / wake_bit to get more wait_queues ... rather than having just one wait queue for all IO. Signed-off-by: NeilBrown --- diff --git a/index.c b/index.c index d1c4097..5fa3037 100644 --- a/index.c +++ b/index.c @@ -867,8 +867,6 @@ static void set_lru(struct block *b) } spin_unlock(&fs->lock); - /* allow lafs_iolock_block-empty to complete */ - lafs_io_wake(b); } void lafs_refile(struct block *b, int dec) diff --git a/io.c b/io.c index ca0e350..260e926 100644 --- a/io.c +++ b/io.c @@ -185,30 +185,22 @@ lafs_super_wait(struct fs *fs) return 0; /* FIXME should be an error flag */ } -static DECLARE_WAIT_QUEUE_HEAD(block_wait); /* need more of these later FIXME */ - -void lafs_io_wake(struct block *b) +static int sched(void *flags) { - wake_up(&block_wait); + io_schedule(); + return 0; } void _lafs_iolock_block(struct block *b) { - if (test_and_set_bit(B_IOLock, &b->flags)) { - DEFINE_WAIT(wq); + while (test_and_set_bit(B_IOLock, &b->flags)) { #ifdef DEBUG_IOLOCK printk("iolock wait for %s:%d: %s\n", b->iolock_file, b->iolock_line, strblk(b)); #endif - for (;;) { - prepare_to_wait(&block_wait, &wq, TASK_UNINTERRUPTIBLE); - - if (!test_and_set_bit(B_IOLock, &b->flags)) - break; - schedule(); - } - finish_wait(&block_wait, &wq); + wait_on_bit(&b->flags, B_IOLock, + sched, TASK_UNINTERRUPTIBLE); } } @@ -241,7 +233,7 @@ lafs_iounlock_block(struct block *b) else lafs_iocheck_block(dblk(b), 1); - lafs_io_wake(b); + wake_up_bit(&b->flags, B_IOLock); if (test_bit(B_Async, &b->flags)) lafs_wake_thread(fs_from_inode(b->inode)); } @@ -254,7 +246,7 @@ void lafs_writeback_done(struct block *b) if (test_bit(B_Index, &b->flags)) { clear_bit(B_Writeback, &b->flags); - lafs_io_wake(b); + wake_up_bit(&b->flags, B_Writeback); if (test_bit(B_Async, &b->flags)) lafs_wake_thread(fs_from_inode(b->inode)); } else @@ -325,28 +317,29 @@ void lafs_iocheck_writeback(struct datablock *db, int unlock) if (havewrite) end_page_writeback(page); if (unlock) { - lafs_io_wake(&db->b); + wake_up_bit(&db->b.flags, B_Writeback); if (test_bit(B_Async, &db->b.flags)) lafs_wake_thread(fs_from_inode(db->b.inode)); } } +static int sched_valid(void *flags) +{ + if (test_bit(B_Valid, flags)) + return -EINTR; + + schedule(); + return 0; +} + int __must_check lafs_wait_block(struct block *b) { if (test_bit(B_IOLock, &b->flags) && - !test_bit(B_Valid, &b->flags)) { - DEFINE_WAIT(wq); - for (;;) { - prepare_to_wait(&block_wait, &wq, TASK_UNINTERRUPTIBLE); - if (test_bit(B_IOLock, &b->flags) && - !test_bit(B_Valid, &b->flags)) - schedule(); - else - break; - } - finish_wait(&block_wait, &wq); - } + !test_bit(B_Valid, &b->flags)) + wait_on_bit(&b->flags, B_IOLock, + sched_valid, TASK_UNINTERRUPTIBLE); + return test_bit(B_Valid, &b->flags) ? 0 : -EIO; } @@ -372,21 +365,14 @@ lafs_wait_block_async(struct block *b) static void wait_writeback(struct block *b) { if (test_bit(B_Writeback, &b->flags)) { - DEFINE_WAIT(wq); #ifdef DEBUG_IOLOCK printk("writeback wait for %s:%d: %s\n", b->iolock_file, b->iolock_line, strblk(b)); #endif lafs_trigger_flush(b); - for (;;) { - prepare_to_wait(&block_wait, &wq, TASK_UNINTERRUPTIBLE); - if (test_bit(B_Writeback, &b->flags)) - schedule(); - else - break; - } - finish_wait(&block_wait, &wq); + wait_on_bit(&b->flags, B_Writeback, + sched, TASK_UNINTERRUPTIBLE); } } diff --git a/lafs.h b/lafs.h index 66a58d8..30f9424 100644 --- a/lafs.h +++ b/lafs.h @@ -121,7 +121,6 @@ int lafs_index_empty(struct indexblock *ib); #define lafs_iolock_written(b) do { _lafs_iolock_written(b); set_iolock_info(b); } while(0) #define lafs_iolock_written_async(b) ( _lafs_iolock_written_async(b) ? ( set_iolock_info(b), 1) : 0) -void lafs_io_wake(struct block *b); void _lafs_iolock_block(struct block *b); void _lafs_iolock_written(struct block *b); int _lafs_iolock_block_async(struct block *b);