writeback: introduce writeback_control.inodes_written
authorWu Fengguang <fengguang.wu@intel.com>
Thu, 22 Jul 2010 04:50:57 +0000 (22:50 -0600)
committerWu Fengguang <fengguang.wu@intel.com>
Wed, 8 Jun 2011 00:25:20 +0000 (08:25 +0800)
The flusher works on dirty inodes in batches, and may quit prematurely
if the batch of inodes happen to be metadata-only dirtied: in this case
wbc->nr_to_write won't be decreased at all, which stands for "no pages
written" but also mis-interpreted as "no progress".

So introduce writeback_control.inodes_written to count the inodes get
cleaned from VFS POV.  A non-zero value means there are some progress on
writeback, in which case more writeback can be tried.

Acked-by: Jan Kara <jack@suse.cz>
Acked-by: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
fs/fs-writeback.c
include/linux/writeback.h

index fe190a8..e450429 100644 (file)
@@ -464,6 +464,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
                         * No need to add it back to the LRU.
                         */
                        list_del_init(&inode->i_wb_list);
+                       wbc->inodes_written++;
                }
        }
        inode_sync_complete(inode);
@@ -725,6 +726,7 @@ static long wb_writeback(struct bdi_writeback *wb,
                wbc.more_io = 0;
                wbc.nr_to_write = write_chunk;
                wbc.pages_skipped = 0;
+               wbc.inodes_written = 0;
 
                trace_wbc_writeback_start(&wbc, wb->bdi);
                if (work->sb)
@@ -741,6 +743,8 @@ static long wb_writeback(struct bdi_writeback *wb,
                 */
                if (wbc.nr_to_write <= 0)
                        continue;
+               if (wbc.inodes_written)
+                       continue;
                /*
                 * Didn't write everything and we don't have more IO, bail
                 */
index 3f6542c..7df9026 100644 (file)
@@ -34,6 +34,7 @@ struct writeback_control {
        long nr_to_write;               /* Write this many pages, and decrement
                                           this for each page written */
        long pages_skipped;             /* Pages which were not written */
+       long inodes_written;            /* # of inodes written (at least) */
 
        /*
         * For a_ops->writepages(): is start or end are non-zero then this is