aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fs-writeback.c
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2010-05-07 05:35:44 -0400
committerJens Axboe <jens.axboe@oracle.com>2010-05-17 07:00:41 -0400
commit5547e8aac6f71505d621a612de2fca0dd988b439 (patch)
tree36bb4a62fe5773c5acd43c9e72dca1c2f32b1bff /fs/fs-writeback.c
parente913fc825dc685a444cb4c1d0f9d32f372f59861 (diff)
writeback: Update dirty flags in two steps
Filesystems with delalloc support may dirty inode during writepages. As result inode will have dirty metadata flags even after write_inode. In fact we have two dedicated functions for proper data and metadata writeback. It is reasonable to separate flags updates in two stages. https://bugzilla.kernel.org/show_bug.cgi?id=15906 Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r--fs/fs-writeback.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 67db89786e7d..0f629571234f 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -460,11 +460,9 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
460 460
461 BUG_ON(inode->i_state & I_SYNC); 461 BUG_ON(inode->i_state & I_SYNC);
462 462
463 /* Set I_SYNC, reset I_DIRTY */ 463 /* Set I_SYNC, reset I_DIRTY_PAGES */
464 dirty = inode->i_state & I_DIRTY;
465 inode->i_state |= I_SYNC; 464 inode->i_state |= I_SYNC;
466 inode->i_state &= ~I_DIRTY; 465 inode->i_state &= ~I_DIRTY_PAGES;
467
468 spin_unlock(&inode_lock); 466 spin_unlock(&inode_lock);
469 467
470 ret = do_writepages(mapping, wbc); 468 ret = do_writepages(mapping, wbc);
@@ -480,6 +478,15 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
480 ret = err; 478 ret = err;
481 } 479 }
482 480
481 /*
482 * Some filesystems may redirty the inode during the writeback
483 * due to delalloc, clear dirty metadata flags right before
484 * write_inode()
485 */
486 spin_lock(&inode_lock);
487 dirty = inode->i_state & I_DIRTY;
488 inode->i_state &= ~(I_DIRTY_SYNC | I_DIRTY_DATASYNC);
489 spin_unlock(&inode_lock);
483 /* Don't write the inode if only I_DIRTY_PAGES was set */ 490 /* Don't write the inode if only I_DIRTY_PAGES was set */
484 if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { 491 if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
485 int err = write_inode(inode, wbc); 492 int err = write_inode(inode, wbc);