diff mbox series

[03/14] btrfs: fix search when deleting a RAID stripe-extent

Message ID 29bc20b873dca2bf2e44af4b13ffb85c28d7b3de.1733989299.git.jth@kernel.org (mailing list archive)
State New
Headers show
Series btrfs: more RST delete fixes | expand

Commit Message

Johannes Thumshirn Dec. 12, 2024, 7:55 a.m. UTC
From: Johannes Thumshirn <johannes.thumshirn@wdc.com>

When searching for a RAID stripe-extent for deletion, use an offset of -1
to always get the "left" slot in the btree and correctly handle the slot
selection.

Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
 fs/btrfs/raid-stripe-tree.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Comments

Filipe Manana Dec. 17, 2024, 2:56 p.m. UTC | #1
On Thu, Dec 12, 2024 at 7:56 AM Johannes Thumshirn <jth@kernel.org> wrote:
>
> From: Johannes Thumshirn <johannes.thumshirn@wdc.com>
>
> When searching for a RAID stripe-extent for deletion, use an offset of -1
> to always get the "left" slot in the btree and correctly handle the slot
> selection.

Can you elaborate?

It's not clear from this very brief change log what the problem is, or
if there's actually a problem.

Is this a bug, and what are the consequences? Are we missing stripe
extent items and causing some corruption or just unnecessary items?

Or is it just an optimization?

>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> ---
>  fs/btrfs/raid-stripe-tree.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c
> index d341fc2a8a4f..d6f7d7d60e76 100644
> --- a/fs/btrfs/raid-stripe-tree.c
> +++ b/fs/btrfs/raid-stripe-tree.c
> @@ -81,14 +81,18 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
>         while (1) {
>                 key.objectid = start;
>                 key.type = BTRFS_RAID_STRIPE_KEY;
> -               key.offset = 0;
> +               key.offset = (u64)-1;

On a first glance, having the 0 seems to be what leaves us at what you
mention in the change log as "the most left slot" and not -1.

For example if there's an item with key (X BTRFS_RAID_STRIPE_KEY 1M)
and the input arguments are start == X and length == 1M,
doing the search with offset 0 leaves at that exact slot where the
item is, but with an offset of (u64)-1 it leaves us on the next slot.

So please provide an example leaf layout and an example range passed
to btrfs_delete_raid_extent() that results in a bug or non-optimal
behaviour, or whatever is the problem you found.

Thanks.

>
>                 ret = btrfs_search_slot(trans, stripe_root, &key, path, -1, 1);
>                 if (ret < 0)
>                         break;
>
> -               if (path->slots[0] == btrfs_header_nritems(path->nodes[0]))
> -                       path->slots[0]--;
> +               if (ret == 1) {
> +                       ret = 0;
> +                       if (path->slots[0] ==
> +                           btrfs_header_nritems(path->nodes[0]))
> +                               path->slots[0]--;
> +               }
>
>                 leaf = path->nodes[0];
>                 slot = path->slots[0];
> --
> 2.43.0
>
>
diff mbox series

Patch

diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c
index d341fc2a8a4f..d6f7d7d60e76 100644
--- a/fs/btrfs/raid-stripe-tree.c
+++ b/fs/btrfs/raid-stripe-tree.c
@@ -81,14 +81,18 @@  int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
 	while (1) {
 		key.objectid = start;
 		key.type = BTRFS_RAID_STRIPE_KEY;
-		key.offset = 0;
+		key.offset = (u64)-1;
 
 		ret = btrfs_search_slot(trans, stripe_root, &key, path, -1, 1);
 		if (ret < 0)
 			break;
 
-		if (path->slots[0] == btrfs_header_nritems(path->nodes[0]))
-			path->slots[0]--;
+		if (ret == 1) {
+			ret = 0;
+			if (path->slots[0] ==
+			    btrfs_header_nritems(path->nodes[0]))
+				path->slots[0]--;
+		}
 
 		leaf = path->nodes[0];
 		slot = path->slots[0];