• Andrew Morton's avatar
    [PATCH] dirty inode management · 610c5ab8
    Andrew Morton authored
    Fix the "race with umount" in __sync_list().  __sync_list() no longer
    puts inodes onto a local list while writing them out.
    
    The super_block.sb_dirty list is kept time-ordered.  Mappings which
    have the "oldest" ->dirtied_when are kept at sb->s_dirty.prev.
    
    So the time-based writeback (kupdate) can just bale out when it
    encounters a not-old-enough mapping, rather than walking the entire
    list.
    
    dirtied_when is set on the *first* dirtying of a mapping.  So once the
    mapping is marked dirty it strictly retains its place on s_dirty until
    it reaches the oldest end and is written out.  So frequently-dirtied
    mappings don't stay dirty at the head of the list for all time.
    
    That local inode list was there for livelock avoidance.  Livelock is
    instead avoided by looking at each mapping's ->dirtied_when.  If we
    encounter one which was dirtied after this invokation of __sync_list(),
    then just bale out - the sync functions are only required to write out
    data which was dirty at the time when they were called.
    
    Keeping the s_dirty list in time-order is the right thing to do anyway
    - so all the various writeback callers always work against the oldest
    data.
    610c5ab8
page-writeback.c 14.8 KB