public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] btrfs: check for overlapping extent items in tree checker
@ 2022-08-03 18:28 Josef Bacik
  2022-08-03 22:09 ` Qu Wenruo
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Josef Bacik @ 2022-08-03 18:28 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

We're seeing a weird problem in production where we have overlapping
extent items in the extent tree.  It's unclear where these are coming
from, and in debugging we realized there's no check in the tree checker
for this sort of problem.  Add a check to the tree-checker to make sure
that the extents do not overlap each other.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/tree-checker.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
index 9e0e0ae2288c..43f905ab0a18 100644
--- a/fs/btrfs/tree-checker.c
+++ b/fs/btrfs/tree-checker.c
@@ -1233,7 +1233,8 @@ static void extent_err(const struct extent_buffer *eb, int slot,
 }
 
 static int check_extent_item(struct extent_buffer *leaf,
-			     struct btrfs_key *key, int slot)
+			     struct btrfs_key *key, int slot,
+			     struct btrfs_key *prev_key)
 {
 	struct btrfs_fs_info *fs_info = leaf->fs_info;
 	struct btrfs_extent_item *ei;
@@ -1453,6 +1454,26 @@ static int check_extent_item(struct extent_buffer *leaf,
 			   total_refs, inline_refs);
 		return -EUCLEAN;
 	}
+
+	if ((prev_key->type == BTRFS_EXTENT_ITEM_KEY) ||
+	    (prev_key->type == BTRFS_METADATA_ITEM_KEY)) {
+		u64 prev_end = prev_key->objectid;
+
+		if (prev_key->type == BTRFS_METADATA_ITEM_KEY)
+			prev_end += fs_info->nodesize;
+		else
+			prev_end += prev_key->offset;
+
+		if (unlikely(prev_end > key->objectid)) {
+			extent_err(leaf, slot,
+	"previous extent [%llu %u %llu] overlaps current extent [%llu %u %llu]",
+				   prev_key->objectid, prev_key->type,
+				   prev_key->offset, key->objectid, key->type,
+				   key->offset);
+			return -EUCLEAN;
+		}
+	}
+
 	return 0;
 }
 
@@ -1621,7 +1642,7 @@ static int check_leaf_item(struct extent_buffer *leaf,
 		break;
 	case BTRFS_EXTENT_ITEM_KEY:
 	case BTRFS_METADATA_ITEM_KEY:
-		ret = check_extent_item(leaf, key, slot);
+		ret = check_extent_item(leaf, key, slot, prev_key);
 		break;
 	case BTRFS_TREE_BLOCK_REF_KEY:
 	case BTRFS_SHARED_DATA_REF_KEY:
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] btrfs: check for overlapping extent items in tree checker
  2022-08-03 18:28 [PATCH] btrfs: check for overlapping extent items in tree checker Josef Bacik
@ 2022-08-03 22:09 ` Qu Wenruo
  2022-08-04 14:46 ` David Sterba
  2022-09-06 11:25 ` Christoph Anton Mitterer
  2 siblings, 0 replies; 4+ messages in thread
From: Qu Wenruo @ 2022-08-03 22:09 UTC (permalink / raw)
  To: Josef Bacik, linux-btrfs, kernel-team



On 2022/8/4 02:28, Josef Bacik wrote:
> We're seeing a weird problem in production where we have overlapping
> extent items in the extent tree.  It's unclear where these are coming
> from, and in debugging we realized there's no check in the tree checker
> for this sort of problem.  Add a check to the tree-checker to make sure
> that the extents do not overlap each other.
>
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>   fs/btrfs/tree-checker.c | 25 +++++++++++++++++++++++--
>   1 file changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
> index 9e0e0ae2288c..43f905ab0a18 100644
> --- a/fs/btrfs/tree-checker.c
> +++ b/fs/btrfs/tree-checker.c
> @@ -1233,7 +1233,8 @@ static void extent_err(const struct extent_buffer *eb, int slot,
>   }
>
>   static int check_extent_item(struct extent_buffer *leaf,
> -			     struct btrfs_key *key, int slot)
> +			     struct btrfs_key *key, int slot,
> +			     struct btrfs_key *prev_key)
>   {
>   	struct btrfs_fs_info *fs_info = leaf->fs_info;
>   	struct btrfs_extent_item *ei;
> @@ -1453,6 +1454,26 @@ static int check_extent_item(struct extent_buffer *leaf,
>   			   total_refs, inline_refs);
>   		return -EUCLEAN;
>   	}
> +
> +	if ((prev_key->type == BTRFS_EXTENT_ITEM_KEY) ||
> +	    (prev_key->type == BTRFS_METADATA_ITEM_KEY)) {
> +		u64 prev_end = prev_key->objectid;
> +
> +		if (prev_key->type == BTRFS_METADATA_ITEM_KEY)
> +			prev_end += fs_info->nodesize;
> +		else
> +			prev_end += prev_key->offset;
> +
> +		if (unlikely(prev_end > key->objectid)) {
> +			extent_err(leaf, slot,
> +	"previous extent [%llu %u %llu] overlaps current extent [%llu %u %llu]",
> +				   prev_key->objectid, prev_key->type,
> +				   prev_key->offset, key->objectid, key->type,
> +				   key->offset);
> +			return -EUCLEAN;
> +		}
> +	}
> +
>   	return 0;
>   }
>
> @@ -1621,7 +1642,7 @@ static int check_leaf_item(struct extent_buffer *leaf,
>   		break;
>   	case BTRFS_EXTENT_ITEM_KEY:
>   	case BTRFS_METADATA_ITEM_KEY:
> -		ret = check_extent_item(leaf, key, slot);
> +		ret = check_extent_item(leaf, key, slot, prev_key);
>   		break;
>   	case BTRFS_TREE_BLOCK_REF_KEY:
>   	case BTRFS_SHARED_DATA_REF_KEY:

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] btrfs: check for overlapping extent items in tree checker
  2022-08-03 18:28 [PATCH] btrfs: check for overlapping extent items in tree checker Josef Bacik
  2022-08-03 22:09 ` Qu Wenruo
@ 2022-08-04 14:46 ` David Sterba
  2022-09-06 11:25 ` Christoph Anton Mitterer
  2 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2022-08-04 14:46 UTC (permalink / raw)
  To: Josef Bacik; +Cc: linux-btrfs, kernel-team

On Wed, Aug 03, 2022 at 02:28:47PM -0400, Josef Bacik wrote:
> We're seeing a weird problem in production where we have overlapping
> extent items in the extent tree.  It's unclear where these are coming
> from, and in debugging we realized there's no check in the tree checker
> for this sort of problem.  Add a check to the tree-checker to make sure
> that the extents do not overlap each other.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>

Added to misc-next, thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] btrfs: check for overlapping extent items in tree checker
  2022-08-03 18:28 [PATCH] btrfs: check for overlapping extent items in tree checker Josef Bacik
  2022-08-03 22:09 ` Qu Wenruo
  2022-08-04 14:46 ` David Sterba
@ 2022-09-06 11:25 ` Christoph Anton Mitterer
  2 siblings, 0 replies; 4+ messages in thread
From: Christoph Anton Mitterer @ 2022-09-06 11:25 UTC (permalink / raw)
  To: Josef Bacik, linux-btrfs

Hey.

On Wed, 2022-08-03 at 14:28 -0400, Josef Bacik wrote:
> We're seeing a weird problem in production where we have overlapping
> extent items in the extent tree.  It's unclear where these are coming
> from, and in debugging we realized there's no check in the tree
> checker
> for this sort of problem.  Add a check to the tree-checker to make
> sure
> that the extents do not overlap each other.

Is there a way to check whether one was affected by this? I mean pro-
actively on already existing data? scrubbing once one has a kernel with
a patch?


And I assume this could cause data corruption?


Cheers,
Chris.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-09-06 11:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-03 18:28 [PATCH] btrfs: check for overlapping extent items in tree checker Josef Bacik
2022-08-03 22:09 ` Qu Wenruo
2022-08-04 14:46 ` David Sterba
2022-09-06 11:25 ` Christoph Anton Mitterer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox