Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
[safe/jmp/linux-2.6] / fs / fs-writeback.c
index 414df43..c007607 100644 (file)
@@ -89,7 +89,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
                if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev"))
                        printk(KERN_DEBUG
                               "%s(%d): dirtied inode %lu (%s) on %s\n",
-                              current->comm, current->pid, inode->i_ino,
+                              current->comm, task_pid_nr(current), inode->i_ino,
                               name, inode->i_sb->s_id);
        }
 
@@ -100,11 +100,11 @@ void __mark_inode_dirty(struct inode *inode, int flags)
                inode->i_state |= flags;
 
                /*
-                * If the inode is locked, just update its dirty state. 
+                * If the inode is being synced, just update its dirty state.
                 * The unlocker will place the inode on the appropriate
                 * superblock list, based upon its state.
                 */
-               if (inode->i_state & I_LOCK)
+               if (inode->i_state & I_SYNC)
                        goto out;
 
                /*
@@ -172,6 +172,15 @@ static void requeue_io(struct inode *inode)
        list_move(&inode->i_list, &inode->i_sb->s_more_io);
 }
 
+static void inode_sync_complete(struct inode *inode)
+{
+       /*
+        * Prevent speculative execution through spin_unlock(&inode_lock);
+        */
+       smp_mb();
+       wake_up_bit(&inode->i_state, __I_SYNC);
+}
+
 /*
  * Move expired dirty inodes from @delaying_queue to @dispatch_queue.
  */
@@ -225,11 +234,11 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
        int wait = wbc->sync_mode == WB_SYNC_ALL;
        int ret;
 
-       BUG_ON(inode->i_state & I_LOCK);
+       BUG_ON(inode->i_state & I_SYNC);
 
-       /* Set I_LOCK, reset I_DIRTY */
+       /* Set I_SYNC, reset I_DIRTY */
        dirty = inode->i_state & I_DIRTY;
-       inode->i_state |= I_LOCK;
+       inode->i_state |= I_SYNC;
        inode->i_state &= ~I_DIRTY;
 
        spin_unlock(&inode_lock);
@@ -250,7 +259,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
        }
 
        spin_lock(&inode_lock);
-       inode->i_state &= ~I_LOCK;
+       inode->i_state &= ~I_SYNC;
        if (!(inode->i_state & I_FREEING)) {
                if (!(inode->i_state & I_DIRTY) &&
                    mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
@@ -275,7 +284,17 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
                                 * soon as the queue becomes uncongested.
                                 */
                                inode->i_state |= I_DIRTY_PAGES;
-                               requeue_io(inode);
+                               if (wbc->nr_to_write <= 0) {
+                                       /*
+                                        * slice used up: queue for next turn
+                                        */
+                                       requeue_io(inode);
+                               } else {
+                                       /*
+                                        * somehow blocked: retry later
+                                        */
+                                       redirty_tail(inode);
+                               }
                        } else {
                                /*
                                 * Otherwise fully redirty the inode so that
@@ -305,7 +324,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
                        list_move(&inode->i_list, &inode_unused);
                }
        }
-       wake_up_inode(inode);
+       inode_sync_complete(inode);
        return ret;
 }
 
@@ -324,10 +343,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
        else
                WARN_ON(inode->i_state & I_WILL_FREE);
 
-       if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) {
-               struct address_space *mapping = inode->i_mapping;
-               int ret;
-
+       if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_SYNC)) {
                /*
                 * We're skipping this inode because it's locked, and we're not
                 * doing writeback-for-data-integrity.  Move it to s_more_io so
@@ -336,30 +352,22 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
                 * completed a full scan of s_io.
                 */
                requeue_io(inode);
-
-               /*
-                * Even if we don't actually write the inode itself here,
-                * we can at least start some of the data writeout..
-                */
-               spin_unlock(&inode_lock);
-               ret = do_writepages(mapping, wbc);
-               spin_lock(&inode_lock);
-               return ret;
+               return 0;
        }
 
        /*
         * It's a data-integrity sync.  We must wait.
         */
-       if (inode->i_state & I_LOCK) {
-               DEFINE_WAIT_BIT(wq, &inode->i_state, __I_LOCK);
+       if (inode->i_state & I_SYNC) {
+               DEFINE_WAIT_BIT(wq, &inode->i_state, __I_SYNC);
 
-               wqh = bit_waitqueue(&inode->i_state, __I_LOCK);
+               wqh = bit_waitqueue(&inode->i_state, __I_SYNC);
                do {
                        spin_unlock(&inode_lock);
                        __wait_on_bit(wqh, &wq, inode_wait,
                                                        TASK_UNINTERRUPTIBLE);
                        spin_lock(&inode_lock);
-               } while (inode->i_state & I_LOCK);
+               } while (inode->i_state & I_SYNC);
        }
        return __sync_single_inode(inode, wbc);
 }
@@ -392,7 +400,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
  * The inodes to be written are parked on sb->s_io.  They are moved back onto
  * sb->s_dirty as they are selected for writing.  This way, none can be missed
  * on the writer throttling path, and we get decent balancing between many
- * throttled threads: we don't want them all piling up on __wait_on_inode.
+ * throttled threads: we don't want them all piling up on inode_sync_wait.
  */
 static void
 sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
@@ -470,8 +478,12 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
                iput(inode);
                cond_resched();
                spin_lock(&inode_lock);
-               if (wbc->nr_to_write <= 0)
+               if (wbc->nr_to_write <= 0) {
+                       wbc->more_io = 1;
                        break;
+               }
+               if (!list_empty(&sb->s_more_io))
+                       wbc->more_io = 1;
        }
        return;         /* Leave any unwritten inodes on s_io */
 }
@@ -503,8 +515,7 @@ writeback_inodes(struct writeback_control *wbc)
        might_sleep();
        spin_lock(&sb_lock);
 restart:
-       sb = sb_entry(super_blocks.prev);
-       for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) {
+       list_for_each_entry_reverse(sb, &super_blocks, s_list) {
                if (sb_has_dirty_inodes(sb)) {
                        /* we're making our own get_super here */
                        sb->s_count++;
@@ -569,10 +580,8 @@ static void set_sb_syncing(int val)
 {
        struct super_block *sb;
        spin_lock(&sb_lock);
-       sb = sb_entry(super_blocks.prev);
-       for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) {
+       list_for_each_entry_reverse(sb, &super_blocks, s_list)
                sb->s_syncing = val;
-       }
        spin_unlock(&sb_lock);
 }
 
@@ -646,7 +655,7 @@ int write_inode_now(struct inode *inode, int sync)
        int ret;
        struct writeback_control wbc = {
                .nr_to_write = LONG_MAX,
-               .sync_mode = WB_SYNC_ALL,
+               .sync_mode = sync ? WB_SYNC_ALL : WB_SYNC_NONE,
                .range_start = 0,
                .range_end = LLONG_MAX,
        };
@@ -659,7 +668,7 @@ int write_inode_now(struct inode *inode, int sync)
        ret = __writeback_single_inode(inode, &wbc);
        spin_unlock(&inode_lock);
        if (sync)
-               wait_on_inode(inode);
+               inode_sync_wait(inode);
        return ret;
 }
 EXPORT_SYMBOL(write_inode_now);
@@ -734,7 +743,7 @@ int generic_osync_inode(struct inode *inode, struct address_space *mapping, int
                        err = err2;
        }
        else
-               wait_on_inode(inode);
+               inode_sync_wait(inode);
 
        return err;
 }