summaryrefslogtreecommitdiff
path: root/fs/fs-writeback.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r--fs/fs-writeback.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index d3db0faa9abe..ad8ef0487ad2 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -61,6 +61,12 @@ void __mark_inode_dirty(struct inode *inode, int flags)
sb->s_op->dirty_inode(inode);
}
+ /*
+ * make sure that changes are seen by all cpus before we test i_state
+ * -- mikulas
+ */
+ smp_mb();
+
/* avoid the locking if we can */
if ((inode->i_state & flags) == flags)
return;
@@ -137,6 +143,12 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
inode->i_state |= I_LOCK;
inode->i_state &= ~I_DIRTY;
+ /*
+ * smp_rmb(); note: if you remove write_lock below, you must add this.
+ * mark_inode_dirty doesn't take spinlock, make sure that inode is not
+ * read speculatively by this cpu before &= ~I_DIRTY -- mikulas
+ */
+
write_lock(&mapping->page_lock);
if (wait || !wbc->for_kupdate || list_empty(&mapping->io_pages))
list_splice_init(&mapping->dirty_pages, &mapping->io_pages);
@@ -334,7 +346,6 @@ writeback_inodes(struct writeback_control *wbc)
}
spin_unlock(&sb_lock);
spin_unlock(&inode_lock);
- blk_run_queues();
}
/*