Re: [PATCH v2 3/3] btrfs: update stripe_extent delete loop assumptions

From: Qu Wenruo
Date: Thu Jul 11 2024 - 03:45:09 EST




在 2024/7/11 16:25, Qu Wenruo 写道:


在 2024/7/11 15:51, Johannes Thumshirn 写道:
From: Johannes Thumshirn <johannes.thumshirn@xxxxxxx>

btrfs_delete_raid_extent() was written under the assumption, that it's
call-chain always passes a start, length tuple that matches a single
extent. But btrfs_delete_raid_extent() is called by
do_free_extent_acounting() which in term is called by > __btrfs_free_extent().

But from the call site __btrfs_free_extent(), it is still called for a single extent.

Or we will get an error and abort the current transaction.

Or does it mean, one data extent can have multiple RST entries?

Is that a non-zoned RST specific behavior?
As I still remember that we split ordered extents for zoned devices, so that it should always have one extent for each split OE.

Thanks,
Qu


But this call-chain passes in a start address and a length that can
possibly match multiple on-disk extents.

Mind to give a more detailed example on this?

Thanks,
Qu


To make this possible, we have to adjust the start and length of each
btree node lookup, to not delete beyond the requested range.

Signed-off-by: Johannes Thumshirn <johannes.thumshirn@xxxxxxx>
---
  fs/btrfs/raid-stripe-tree.c | 5 +++++
  1 file changed, 5 insertions(+)

diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c
index fd56535b2289..6f65be334637 100644
--- a/fs/btrfs/raid-stripe-tree.c
+++ b/fs/btrfs/raid-stripe-tree.c
@@ -66,6 +66,11 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
          if (ret)
              break;
+        start += key.offset;
+        length -= key.offset;
+        if (length == 0)
+            break;
+
          btrfs_release_path(path);
      }