linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jan Schmidt <list.btrfs@jan-o-sch.net>
To: chris.mason@fusionio.com, linux-btrfs@vger.kernel.org
Subject: [PATCH 7/7] Btrfs: resolve tree mod log locking issue in btrfs_next_leaf
Date: Wed, 27 Jun 2012 19:24:59 +0200	[thread overview]
Message-ID: <1340817899-16343-8-git-send-email-list.btrfs@jan-o-sch.net> (raw)
In-Reply-To: <1340817899-16343-1-git-send-email-list.btrfs@jan-o-sch.net>

With the tree mod log, we may end up with two roots (the current root and a
rewinded version of it) both pointing to two leaves, l1 and l2, of which l2
had already been cow-ed in the current transaction. If we don't rewind any
tree blocks, we cannot have two roots both pointing to an already cowed tree
block.

Now there is btrfs_next_leaf, which has a leaf locked and wants a lock on
the next (right) leaf. And there is push_leaf_left, which has a (cowed!)
leaf locked and wants a lock on the previous (left) leaf.

In order to solve this dead lock situation, we use try_lock in
btrfs_next_leaf (only in case it's called with a tree mod log time_seq
paramter) and if we fail to get a lock on the next leaf, we give up our lock
on the current leaf and retry from the very beginning.

Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
---
 fs/btrfs/ctree.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index b98f860..8206b39 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -5119,6 +5119,18 @@ again:
 
 		if (!path->skip_locking) {
 			ret = btrfs_try_tree_read_lock(next);
+			if (!ret && time_seq) {
+				/*
+				 * If we don't get the lock, we may be racing
+				 * with push_leaf_left, holding that lock while
+				 * itself waiting for the leaf we've currently
+				 * locked. To solve this situation, we give up
+				 * on our lock and cycle.
+				 */
+				btrfs_release_path(path);
+				cond_resched();
+				goto again;
+			}
 			if (!ret) {
 				btrfs_set_path_blocking(path);
 				btrfs_tree_read_lock(next);
-- 
1.7.3.4


      parent reply	other threads:[~2012-06-27 17:25 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-27 17:24 [PATCH 0/7] Btrfs: fixes for 3.5-rc5 Jan Schmidt
2012-06-27 17:24 ` [PATCH 1/7] Btrfs: avoid waiting for delayed refs when we must not Jan Schmidt
2012-06-27 17:24 ` [PATCH 2/7] Btrfs: support root level changes in __resolve_indirect_ref Jan Schmidt
2012-06-27 17:24 ` [PATCH 3/7] Btrfs: fix tree mod log for root replacements at leaf level Jan Schmidt
2012-06-27 17:24 ` [PATCH 4/7] Btrfs: always put insert_ptr modifications into the tree mod log Jan Schmidt
2012-06-27 17:24 ` [PATCH 5/7] Btrfs: leave critical region in btrfs_find_all_roots as soon as possible Jan Schmidt
2012-06-27 17:24 ` [PATCH 6/7] Btrfs: fix tree mod log rewind of ADD operations Jan Schmidt
2012-06-27 17:24 ` Jan Schmidt [this message]

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=1340817899-16343-8-git-send-email-list.btrfs@jan-o-sch.net \
    --to=list.btrfs@jan-o-sch.net \
    --cc=chris.mason@fusionio.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).