linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: fdmanana@kernel.org
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 2/2] Btrfs: report and handle error on unexpected first key on extent buffer
Date: Mon, 18 Feb 2019 16:58:26 +0000	[thread overview]
Message-ID: <20190218165826.23549-1-fdmanana@kernel.org> (raw)

From: Filipe Manana <fdmanana@suse.com>

When there is a kind of corruption in an extent buffer such that its first
key does not match the key at the respective parent slot, one of two things
happens:

1) When assertions are enabled, we effectively hit a BUG_ON() which
   requires rebooting the machine later. This also does not tell any
   information about which extent buffer is affected, from which root,
   the expected and found keys, etc.

2) When assertions are disabled, we just ignore the mismatch and assume
   everything is ok, which can potentially lead to all sorts of unexpected
   problems later after a tree search (in the worst case, could lead to
   further silent corruption).

So improve this by always checking if the first key of an extent buffer is
what it's supposed to be, when doing a key search at key_search(), and
report and return an appropriate error. The overhead is just comparing one
key, which is minimal and is anyway just done in a special case where we
skip the more expensive binary search (the binary search in the parent
node returned 0, exact key match).

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/ctree.c | 38 +++++++++++++++++---------------------
 1 file changed, 17 insertions(+), 21 deletions(-)

diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 5b9f602fb9e2..a0bd0278208d 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2529,35 +2529,31 @@ setup_nodes_for_search(struct btrfs_trans_handle *trans,
 	return ret;
 }
 
-static void key_search_validate(struct extent_buffer *b,
-				const struct btrfs_key *key,
-				int level)
-{
-#ifdef CONFIG_BTRFS_ASSERT
-	struct btrfs_disk_key disk_key;
-
-	btrfs_cpu_key_to_disk(&disk_key, key);
-
-	if (level == 0)
-		ASSERT(!memcmp_extent_buffer(b, &disk_key,
-		    offsetof(struct btrfs_leaf, items[0].key),
-		    sizeof(disk_key)));
-	else
-		ASSERT(!memcmp_extent_buffer(b, &disk_key,
-		    offsetof(struct btrfs_node, ptrs[0].key),
-		    sizeof(disk_key)));
-#endif
-}
-
 static int key_search(struct extent_buffer *b, const struct btrfs_key *key,
 		      int level, int *prev_cmp, int *slot)
 {
+	struct btrfs_key found_key;
+
 	if (*prev_cmp != 0) {
 		*prev_cmp = btrfs_bin_search(b, key, level, slot);
 		return *prev_cmp;
 	}
 
-	key_search_validate(b, key, level);
+	if (level == 0)
+		btrfs_item_key_to_cpu(b, &found_key, 0);
+	else
+		btrfs_node_key_to_cpu(b, &found_key, 0);
+
+	if (btrfs_comp_cpu_keys(&found_key, key) != 0) {
+		btrfs_crit(b->fs_info,
+"unexpected first key for extent buffer: bytenr=%llu level=%d root=%llu expected key=(%llu %u %llu) found key=(%llu %u %llu)",
+			   btrfs_header_bytenr(b), level, btrfs_header_owner(b),
+			   key->objectid, key->type, key->offset,
+			   found_key.objectid, found_key.type,
+			   found_key.offset);
+		return -EUCLEAN;
+	}
+
 	*slot = 0;
 
 	return 0;
-- 
2.11.0


             reply	other threads:[~2019-02-18 16:58 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-18 16:58 fdmanana [this message]
2019-02-19  0:53 ` [PATCH 2/2] Btrfs: report and handle error on unexpected first key on extent buffer Qu Wenruo
2019-02-19 11:59   ` Filipe Manana
2019-02-19 12:24     ` Qu Wenruo
2019-02-20 11:12       ` Filipe Manana

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=20190218165826.23549-1-fdmanana@kernel.org \
    --to=fdmanana@kernel.org \
    --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).