]> git.neil.brown.name Git - LaFS.git/commitdiff
Use wait_on_bit / wake_bit to get more wait_queues
authorNeilBrown <neilb@suse.de>
Sat, 2 Oct 2010 02:41:00 +0000 (12:41 +1000)
committerNeilBrown <neilb@suse.de>
Sun, 10 Oct 2010 23:33:55 +0000 (10:33 +1100)
... rather than having just one wait queue for all IO.

Signed-off-by: NeilBrown <neilb@suse.de>
index.c
io.c
lafs.h

diff --git a/index.c b/index.c
index d1c40978d979075105fa471aaabe74445bc8671b..5fa303782bff372dc962b11d0dff7bada430424b 100644 (file)
--- 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 ca0e3509266757e73088e0deac7a5761dd86f33e..260e92638b8a0e6059be729a99bfc15bd99900fd 100644 (file)
--- 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 66a58d8290c2e033ee7fe1e34dd1a37006363e20..30f9424d3eb14bdd070284b0b045058c291935d1 100644 (file)
--- 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);