Move the terminate conditions to the end of the loop, and move the work->older_than_this updates close to each others. Proposed-by: Dave Chinner Signed-off-by: Wu Fengguang --- fs/fs-writeback.c | 58 +++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 27 deletions(-) --- linux-next.orig/fs/fs-writeback.c 2011-05-20 05:41:35.000000000 +0800 +++ linux-next/fs/fs-writeback.c 2011-05-20 05:41:36.000000000 +0800 @@ -712,42 +712,22 @@ static long wb_writeback(struct bdi_writ unsigned long oldest_jif; struct inode *inode; long progress; + bool bg_retry_all = false; oldest_jif = jiffies; work->older_than_this = &oldest_jif; spin_lock(&wb->list_lock); for (;;) { - /* - * Stop writeback when nr_pages has been consumed - */ - if (work->nr_pages <= 0) - break; - - /* - * Background writeout and kupdate-style writeback may - * run forever. Stop them if there is other work to do - * so that e.g. sync can proceed. They'll be restarted - * after the other works are all done. - */ - if ((work->for_background || work->for_kupdate) && - !list_empty(&wb->bdi->work_list)) - break; - - /* - * For background writeout, stop when we are below the - * background dirty threshold - */ - if (work->for_background && !over_bground_thresh()) - break; - - if (work->for_kupdate || work->for_background) { + if (bg_retry_all) { + bg_retry_all = false; + work->older_than_this = NULL; + } else if (work->for_kupdate || work->for_background) { oldest_jif = jiffies - msecs_to_jiffies(dirty_expire_interval * 10); work->older_than_this = &oldest_jif; } -retry: trace_writeback_start(wb->bdi, work); if (list_empty(&wb->b_io)) queue_io(wb, work->older_than_this); @@ -777,14 +757,38 @@ retry: work->older_than_this && list_empty(&wb->b_io) && list_empty(&wb->b_more_io)) { - work->older_than_this = NULL; - goto retry; + bg_retry_all = true; + continue; } /* * No more inodes for IO, bail */ if (list_empty(&wb->b_more_io)) break; + + /* + * Stop writeback when nr_pages has been consumed + */ + if (work->nr_pages <= 0) + break; + + /* + * For background writeout, stop when we are below the + * background dirty threshold + */ + if (work->for_background && !over_bground_thresh()) + break; + + /* + * Background writeout and kupdate-style writeback may + * run forever. Stop them if there is other work to do + * so that e.g. sync can proceed. They'll be restarted + * after the other works are all done. + */ + if ((work->for_background || work->for_kupdate) && + !list_empty(&wb->bdi->work_list)) + break; + /* * Nothing written. Wait for some inode to * become available for writeback. Otherwise -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/