linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Liu Bo <liubo2009@cn.fujitsu.com>
To: <linux-btrfs@vger.kernel.org>
Subject: [PATCH 03/10] Btrfs: fix race between direct io and autodefrag
Date: Tue, 27 Mar 2012 14:44:31 +0800	[thread overview]
Message-ID: <1332830678-3992-4-git-send-email-liubo2009@cn.fujitsu.com> (raw)
In-Reply-To: <1332830678-3992-1-git-send-email-liubo2009@cn.fujitsu.com>

The bug is from running xfstests 209 with autodefrag.

The race is as follows:
       t1                       t2(autodefrag)
   direct IO
     invalidate pagecache
     dio(old data)             add_inode_defrag
     invalidate pagecache
   endio

   direct IO
     invalidate pagecache
                                run_defrag
                                  readpage(old data)
                                  set page dirty (old data)
     dio(new data, rewrite)
     invalidate pagecache (*)
     endio

t2(autodefrag) will get old data into pagecache via readpage and set
pagecache dirty.  Meanwhile, invalidate pagecache(*) will fail due to
dirty flags in pages.  So the old data may be flushed into disk by
flush thread, which will lead to data loss.

And so does the case of user defragment progs.

The patch fixes this race by holding i_mutex when we readpage and set page dirty.

Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
 fs/btrfs/ioctl.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index d8b5471..0acc828 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1123,12 +1123,16 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
 			ra_index += max_cluster;
 		}
 
+		mutex_lock(&inode->i_mutex);
 		ret = cluster_pages_for_defrag(inode, pages, i, cluster);
-		if (ret < 0)
+		if (ret < 0) {
+			mutex_unlock(&inode->i_mutex);
 			goto out_ra;
+		}
 
 		defrag_count += ret;
 		balance_dirty_pages_ratelimited_nr(inode->i_mapping, ret);
+		mutex_unlock(&inode->i_mutex);
 
 		if (newer_than) {
 			if (newer_off == (u64)-1)
-- 
1.6.5.2


  parent reply	other threads:[~2012-03-27  6:44 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-27  6:44 [PATCH 00/10] several fixes and cleanups Liu Bo
2012-03-27  6:44 ` [PATCH 01/10] Btrfs: show useful info in space reservation tracepoint Liu Bo
2012-03-27  6:44 ` [PATCH 02/10][RESEND] Btrfs: fix deadlock during allocating chunks Liu Bo
2012-03-27  6:44 ` Liu Bo [this message]
2012-03-27  6:44 ` [PATCH 04/10] Btrfs: fix the mismatch of page->mapping Liu Bo
2012-03-27  6:44 ` [PATCH 05/10][RESEND] Btrfs: fix recursive defragment with autodefrag option Liu Bo
2012-03-27  6:44 ` [PATCH 06/10] Btrfs: add a check to decide if we should defrag the range Liu Bo
2012-03-27  6:44 ` [PATCH 07/10] Btrfs: do not bother to defrag an extent if it is a big real extent Liu Bo
2012-03-27  6:44 ` [PATCH 08/10] Btrfs: update to the right index of defragment Liu Bo
2012-03-27  6:44 ` [PATCH 09/10] Btrfs: use PagePrivate2 to check ordered data Liu Bo
2012-03-27  6:44 ` [PATCH 10/10] Btrfs: drop cache with VACANCY em when we fail to start a transaction Liu Bo
2012-03-29 14:01   ` Chris Mason
2012-03-30  1:08     ` Liu Bo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1332830678-3992-4-git-send-email-liubo2009@cn.fujitsu.com \
    --to=liubo2009@cn.fujitsu.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).