From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dmitry Monakhov Subject: [PATCH] writeback: Update dirty flags in two steps Date: Fri, 07 May 2010 13:35:44 +0400 Message-ID: <877hngf40f.fsf@openvz.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: jens.axboe@oracle.com, chris.mason@oracle.com To: linux-fsdevel@vger.kernel.org Return-path: Received: from mail-bw0-f219.google.com ([209.85.218.219]:57852 "EHLO mail-bw0-f219.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756185Ab0EGJft (ORCPT ); Fri, 7 May 2010 05:35:49 -0400 Received: by bwz19 with SMTP id 19so457840bwz.21 for ; Fri, 07 May 2010 02:35:47 -0700 (PDT) Sender: linux-fsdevel-owner@vger.kernel.org List-ID: 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 --- fs/fs-writeback.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index fdc07e3..e73d8ff 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -459,11 +459,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); @@ -479,6 +477,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); -- 1.6.6.1