Commit 294947ec authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] writeback livelock fix

To avoid various livelocks, the writeback code parks all the dirty inodes onto
sb->s_io and then works through that list until it is empty.  This assumes
that each inode will be moved to some other list as it is processed.

But there's a loophole: if the ->writepages() implementation does nothing at
all, the inode is not redirtied (which would move it to s_dirty).  This causes
s_io to not empty and pdflush goes nuts.

So when this happens, move the inode onto s_dirty within
__sync_single_inode().  Use list_move_tail() to attempt to preserve the
time-ordering of the s_dirty list.
parent ec5510b9
......@@ -170,17 +170,19 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
if (!(inode->i_state & I_DIRTY) &&
mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
/*
* We didn't write back all the pages. Redirty the
* inode. It is still on sb->s_dirty.
* We didn't write back all the pages. nfs_writepages()
* sometimes bales out without doing anything. Redirty
* the inode. It is still on sb->s_io.
*/
if (wbc->for_kupdate) {
/*
* For the kupdate function we leave the inode
* where it is on sb_dirty so it will get more
* at the head of sb_dirty so it will get more
* writeout as soon as the queue becomes
* uncongested.
*/
inode->i_state |= I_DIRTY_PAGES;
list_move_tail(&inode->i_list, &sb->s_dirty);
} else {
/*
* Otherwise fully redirty the inode so that
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment