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>
This commit is contained in:
parent
e913fc825d
commit
5547e8aac6
1 changed files with 11 additions and 4 deletions
|
@ -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);
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue