• Jan Kara's avatar
    writeback: avoid livelocking WB_SYNC_ALL writeback · b9543dac
    Jan Kara authored
    When wb_writeback() is called in WB_SYNC_ALL mode, work->nr_to_write is
    usually set to LONG_MAX.  The logic in wb_writeback() then calls
    __writeback_inodes_sb() with nr_to_write == MAX_WRITEBACK_PAGES and we
    easily end up with non-positive nr_to_write after the function returns, if
    the inode has more than MAX_WRITEBACK_PAGES dirty pages at the moment.
    
    When nr_to_write is <= 0 wb_writeback() decides we need another round of
    writeback but this is wrong in some cases!  For example when a single
    large file is continuously dirtied, we would never finish syncing it
    because each pass would be able to write MAX_WRITEBACK_PAGES and inode
    dirty timestamp never gets updated (as inode is never completely clean).
    Thus __writeback_inodes_sb() would write the redirtied inode again and
    again.
    
    Fix the issue by setting nr_to_write to LONG_MAX in WB_SYNC_ALL mode.  We
    do not need nr_to_write in WB_SYNC_ALL mode anyway since
    write_cache_pages() does livelock avoidance using page tagging in
    WB_SYNC_ALL mode.
    
    This makes wb_writeback() call __writeback_inodes_sb() only once on
    WB_SYNC_ALL.  The latter function won't livelock because it works on
    
    - a finite set of files by doing queue_io() once at the beginning
    - a finite set of pages by PAGECACHE_TAG_TOWRITE page tagging
    
    After this patch, program from http://lkml.org/lkml/2010/10/24/154 is no
    longer able to stall sync forever.
    
    [fengguang.wu@intel.com: fix locking comment]
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    Signed-off-by: default avatarWu Fengguang <fengguang.wu@intel.com>
    Cc: Johannes Weiner <hannes@cmpxchg.org>
    Cc: Dave Chinner <david@fromorbit.com>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Jan Engelhardt <jengelh@medozas.de>
    Cc: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    b9543dac
fs-writeback.c 34.3 KB