linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Josef Bacik <josef@toxicpanda.com>
To: linux-btrfs@vger.kernel.org, kernel-team@fb.com
Subject: [PATCH 8/8] btrfs: remove a BUG_ON() from merge_reloc_roots()
Date: Wed,  4 Mar 2020 11:18:30 -0500	[thread overview]
Message-ID: <20200304161830.2360-9-josef@toxicpanda.com> (raw)
In-Reply-To: <20200304161830.2360-1-josef@toxicpanda.com>

This was pretty subtle, we default to reloc roots having 0 root refs, so
if we crash in the middle of the relocation they can just be deleted.
If we successfully complete the relocation operations we'll set our root
refs to 1 in prepare_to_merge() and then go on to merge_reloc_roots().

At prepare_to_merge() time if any of the reloc roots have a 0 reference
still, we will remove that reloc root from our reloc root rb tree, and
then clean it up later.

However this only happens if we successfully start a transaction.  If
we've aborted previously we will skip this step completely, and only
have reloc roots with a reference count of 0, but were never properly
removed from the reloc control's rb tree.

This isn't a problem per-se, our references are held by the list the
reloc roots are on, and by the original root the reloc root belongs to.
If we end up in this situation all the reloc roots will be added to the
dirty_reloc_list, and then properly dropped at that point.  The reloc
control will be free'd and the rb tree is no longer used.

There were two options when fixing this, one was to remove the BUG_ON(),
the other was to make prepare_to_merge() handle the case where we
couldn't start a trans handle.

IMO this is the cleaner solution.  I started with handling the error in
prepare_to_merge(), but it turned out super ugly.  And in the end this
BUG_ON() simply doesn't matter, the cleanup was happening properly, we
were just panicing because this BUG_ON() only matters in the success
case.  So I've opted to just remove it and add a comment where it was.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/relocation.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 0f19a22d7f44..a2b26cf9ee5b 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2653,7 +2653,21 @@ void merge_reloc_roots(struct reloc_control *rc)
 			free_reloc_roots(&reloc_roots);
 	}
 
-	BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root));
+	/*
+	 * We used to have
+	 *
+	 * BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root));
+	 *
+	 * here, but it's wrong.  If we fail to start the transaction in
+	 * prepare_to_merge() we will have only 0 ref reloc roots, none of which
+	 * have actually been removed from the reloc_root_tree rb tree.  This is
+	 * fine because we're bailing here, and we hold a reference on the root
+	 * for the list that holds it, so these roots will be cleaned up when we
+	 * do the reloc_dirty_list afterwards.  Meanwhile the root->reloc_root
+	 * will be cleaned up on unmount.
+	 *
+	 * The remaining nodes will be cleaned up by free_reloc_control.
+	 */
 }
 
 static void free_block_list(struct rb_root *blocks)
-- 
2.24.1


  parent reply	other threads:[~2020-03-04 16:18 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-04 16:18 [PATCH 0/8][v2] relocation error handling fixes Josef Bacik
2020-03-04 16:18 ` [PATCH 1/8] btrfs: drop block from cache on error in relocation Josef Bacik
2020-03-05 11:37   ` Qu Wenruo
2020-03-04 16:18 ` [PATCH 2/8] btrfs: do not init a reloc root if we aren't relocating Josef Bacik
2020-03-04 18:44   ` Nikolay Borisov
2020-03-04 18:47     ` Josef Bacik
2020-03-05 11:24   ` Qu Wenruo
2020-03-04 16:18 ` [PATCH 3/8] btrfs: unset reloc control if we fail to recover Josef Bacik
2020-03-05 11:38   ` Qu Wenruo
2020-03-04 16:18 ` [PATCH 4/8] btrfs: free the reloc_control in a consistent way Josef Bacik
2020-03-05 11:39   ` Qu Wenruo
2020-03-13 15:18     ` David Sterba
2020-03-13 15:32       ` Josef Bacik
2020-03-14  0:13         ` Qu Wenruo
2020-03-04 16:18 ` [PATCH 5/8] btrfs: run clean_dirty_subvols if we fail to start a trans Josef Bacik
2020-03-05 11:40   ` Qu Wenruo
2020-03-05 17:46   ` David Sterba
2020-03-04 16:18 ` [PATCH 6/8] btrfs: clear BTRFS_ROOT_DEAD_RELOC_TREE before dropping the reloc root Josef Bacik
2020-03-05 11:41   ` Qu Wenruo
2020-03-05 13:54     ` Josef Bacik
2020-03-04 16:18 ` [PATCH 7/8] btrfs: hold a ref on the root->reloc_root Josef Bacik
2020-03-04 16:18 ` Josef Bacik [this message]
2020-03-13 14:35 ` [PATCH 0/8][v2] relocation error handling fixes David Sterba
2020-03-13 15:44 [PATCH 0/8][v3] " Josef Bacik
2020-03-13 15:44 ` [PATCH 8/8] btrfs: remove a BUG_ON() from merge_reloc_roots() Josef Bacik

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=20200304161830.2360-9-josef@toxicpanda.com \
    --to=josef@toxicpanda.com \
    --cc=kernel-team@fb.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).