Skip to content

Commit

Permalink
writeback: Update dirty flags in two steps
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dmitry Monakhov authored and Jens Axboe committed May 17, 2010
1 parent e913fc8 commit 5547e8a
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions fs/fs-writeback.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,11 +460,9 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)

BUG_ON(inode->i_state & I_SYNC);

/* Set I_SYNC, reset I_DIRTY */
dirty = inode->i_state & I_DIRTY;
/* Set I_SYNC, reset I_DIRTY_PAGES */
inode->i_state |= I_SYNC;
inode->i_state &= ~I_DIRTY;

inode->i_state &= ~I_DIRTY_PAGES;
spin_unlock(&inode_lock);

ret = do_writepages(mapping, wbc);
Expand All @@ -480,6 +478,15 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
ret = err;
}

/*
* Some filesystems may redirty the inode during the writeback
* due to delalloc, clear dirty metadata flags right before
* write_inode()
*/
spin_lock(&inode_lock);
dirty = inode->i_state & I_DIRTY;
inode->i_state &= ~(I_DIRTY_SYNC | I_DIRTY_DATASYNC);
spin_unlock(&inode_lock);
/* Don't write the inode if only I_DIRTY_PAGES was set */
if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
int err = write_inode(inode, wbc);
Expand Down

0 comments on commit 5547e8a

Please sign in to comment.