summaryrefslogtreecommitdiffstats
path: root/fs/fs-writeback.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-05-03 14:47:56 +0200
committerFengguang Wu <fengguang.wu@intel.com>2012-05-06 13:43:38 +0800
commitcc1676d917f32504dbadc858fa790bc524c9f0da (patch)
treed665d5ad0a844a6b1aff74deb4c8aa01c7596135 /fs/fs-writeback.c
parent365b94ae67d2915d412b593d47449a6bffed9d37 (diff)
downloadlinux-stable-cc1676d917f32504dbadc858fa790bc524c9f0da.tar.gz
linux-stable-cc1676d917f32504dbadc858fa790bc524c9f0da.tar.bz2
linux-stable-cc1676d917f32504dbadc858fa790bc524c9f0da.zip
writeback: Move requeueing when I_SYNC set to writeback_sb_inodes()
When writeback_single_inode() is called on inode which has I_SYNC already set while doing WB_SYNC_NONE, inode is moved to b_more_io list. However this makes sense only if the caller is flusher thread. For other callers of writeback_single_inode() it doesn't really make sense and may be even wrong - flusher thread may be doing WB_SYNC_ALL writeback in parallel. So we move requeueing from writeback_single_inode() to writeback_sb_inodes(). Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r--fs/fs-writeback.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index dd41437b7a1f..65cd14769226 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -373,21 +373,8 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
WARN_ON(inode->i_state & I_WILL_FREE);
if (inode->i_state & I_SYNC) {
- /*
- * If this inode is locked for writeback and we are not doing
- * writeback-for-data-integrity, move it to b_more_io so that
- * writeback can proceed with the other inodes on s_io.
- *
- * We'll have another go at writing back this inode when we
- * completed a full scan of b_io.
- */
- if (wbc->sync_mode != WB_SYNC_ALL) {
- requeue_io(inode, wb);
- trace_writeback_single_inode_requeue(inode, wbc,
- nr_to_write);
+ if (wbc->sync_mode != WB_SYNC_ALL)
return 0;
- }
-
/*
* It's a data-integrity sync. We must wait.
*/
@@ -576,6 +563,21 @@ static long writeback_sb_inodes(struct super_block *sb,
redirty_tail(inode, wb);
continue;
}
+ if ((inode->i_state & I_SYNC) && wbc.sync_mode != WB_SYNC_ALL) {
+ /*
+ * If this inode is locked for writeback and we are not
+ * doing writeback-for-data-integrity, move it to
+ * b_more_io so that writeback can proceed with the
+ * other inodes on s_io.
+ *
+ * We'll have another go at writing back this inode
+ * when we completed a full scan of b_io.
+ */
+ spin_unlock(&inode->i_lock);
+ requeue_io(inode, wb);
+ trace_writeback_sb_inodes_requeue(inode);
+ continue;
+ }
__iget(inode);
write_chunk = writeback_chunk_size(wb->bdi, work);
wbc.nr_to_write = write_chunk;