writeback: kupdate writeback shall not stop when more io is possible
[linux-block.git] / fs / fs-writeback.c
index 8e1e5e19d21e1fd60c9f99b3988fee0191c3e901..551684de13924dc256d89bb3b7ce175a02b73fdf 100644 (file)
@@ -41,8 +41,9 @@ struct wb_writeback_args {
        long nr_pages;
        struct super_block *sb;
        enum writeback_sync_modes sync_mode;
-       int for_kupdate;
-       int range_cyclic;
+       int for_kupdate:1;
+       int range_cyclic:1;
+       int for_background:1;
 };
 
 /*
@@ -257,6 +258,15 @@ void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages)
                .range_cyclic   = 1,
        };
 
+       /*
+        * We treat @nr_pages=0 as the special case to do background writeback,
+        * ie. to sync pages until the background dirty threshold is reached.
+        */
+       if (!nr_pages) {
+               args.nr_pages = LONG_MAX;
+               args.for_background = 1;
+       }
+
        bdi_alloc_queue_work(bdi, &args);
 }
 
@@ -706,6 +716,7 @@ static long wb_writeback(struct bdi_writeback *wb,
        };
        unsigned long oldest_jif;
        long wrote = 0;
+       struct inode *inode;
 
        if (wbc.for_kupdate) {
                wbc.older_than_this = &oldest_jif;
@@ -719,20 +730,16 @@ static long wb_writeback(struct bdi_writeback *wb,
 
        for (;;) {
                /*
-                * Don't flush anything for non-integrity writeback where
-                * no nr_pages was given
+                * Stop writeback when nr_pages has been consumed
                 */
-               if (!args->for_kupdate && args->nr_pages <= 0 &&
-                    args->sync_mode == WB_SYNC_NONE)
+               if (args->nr_pages <= 0)
                        break;
 
                /*
-                * If no specific pages were given and this is just a
-                * periodic background writeout and we are below the
-                * background dirty threshold, don't do anything
+                * For background writeout, stop when we are below the
+                * background dirty threshold
                 */
-               if (args->for_kupdate && args->nr_pages <= 0 &&
-                   !over_bground_thresh())
+               if (args->for_background && !over_bground_thresh())
                        break;
 
                wbc.more_io = 0;
@@ -746,9 +753,25 @@ static long wb_writeback(struct bdi_writeback *wb,
                /*
                 * If we ran out of stuff to write, bail unless more_io got set
                 */
-               if (wbc.nr_to_write > 0 || wbc.pages_skipped > 0) {
-                       if (wbc.more_io && !wbc.for_kupdate)
+               if (wbc.nr_to_write > 0) {
+                       if (wbc.more_io) {
+                               if (wbc.nr_to_write < MAX_WRITEBACK_PAGES)
+                                       continue;
+                               /*
+                                * Nothing written. Wait for some inode to
+                                * become available for writeback. Otherwise
+                                * we'll just busyloop.
+                                */
+                               spin_lock(&inode_lock);
+                               if (!list_empty(&wb->b_more_io))  {
+                                       inode = list_entry(
+                                                       wb->b_more_io.prev,
+                                                       struct inode, i_list);
+                                       inode_wait_for_writeback(inode);
+                               }
+                               spin_unlock(&inode_lock);
                                continue;
+                       }
                        break;
                }
        }