• Jan Kara's avatar
    writeback: put unused inodes to LRU after writeback completion · 4eff96dd
    Jan Kara authored
    Commit 169ebd90 ("writeback: Avoid iput() from flusher thread")
    removed iget-iput pair from inode writeback.  As a side effect, inodes
    that are dirty during iput_final() call won't be ever added to inode LRU
    (iput_final() doesn't add dirty inodes to LRU and later when the inode
    is cleaned there's noone to add the inode there).  Thus inodes are
    effectively unreclaimable until someone looks them up again.
    
    The practical effect of this bug is limited by the fact that inodes are
    pinned by a dentry for long enough that the inode gets cleaned.  But
    still the bug can have nasty consequences leading up to OOM conditions
    under certain circumstances.  Following can easily reproduce the
    problem:
    
      for (( i = 0; i < 1000; i++ )); do
        mkdir $i
        for (( j = 0; j < 1000; j++ )); do
          touch $i/$j
          echo 2 > /proc/sys/vm/drop_caches
        done
      done
    
    then one needs to run 'sync; ls -lR' to make inodes reclaimable again.
    
    We fix the issue by inserting unused clean inodes into the LRU after
    writeback finishes in inode_sync_complete().
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    Reported-by: default avatarOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
    Cc: Wu Fengguang <fengguang.wu@intel.com>
    Cc: Dave Chinner <david@fromorbit.com>
    Cc: <stable@vger.kernel.org>		[3.5+]
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    4eff96dd
inode.c 48.7 KB