diff options
Diffstat (limited to 'fs/fs-writeback.c')
| -rw-r--r-- | fs/fs-writeback.c | 13 |
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(); } /* |
