-
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