Message ID | 93790ce532e9e18fba57268a6230ec312ca38360.1733989299.git.jth@kernel.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | btrfs: more RST delete fixes | expand |
On Thu, Dec 12, 2024 at 7:56 AM Johannes Thumshirn <jth@kernel.org> wrote: > > From: Johannes Thumshirn <johannes.thumshirn@wdc.com> > > Fix tail delete of RAID stripe-extents, if there is a range to be deleted > as well after the tail delete of the extent. > > Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> > --- > fs/btrfs/raid-stripe-tree.c | 13 ++++++++++--- > 1 file changed, 10 insertions(+), 3 deletions(-) > > diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c > index 092e24e1de32..6246ab4c1a21 100644 > --- a/fs/btrfs/raid-stripe-tree.c > +++ b/fs/btrfs/raid-stripe-tree.c > @@ -121,11 +121,18 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le > * length to the new size and then re-insert the item. > */ > if (found_start < start) { > - u64 diff = start - found_start; > + u64 diff_start = start - found_start; > > btrfs_partially_delete_raid_extent(trans, path, &key, > - diff, 0); > - break; > + diff_start, 0); > + > + start += (key.offset - diff_start); > + length -= (key.offset - diff_start); So this can underflow in case the item we found covers a range that spans 'end', that is in case found_end > end. For example if the length argument was originally 1M, the item has a found_start < start, diff_start is 512K and item's offset is 2M, in which case we get: length -= 2M - 512K length -= 1.5M 1M -= 1.5M -512K So it should be: start += min(found_end, end) - start; length += min(found_end, end) - start; But in this case we would also need to split the item into two, as we're "punching a hole". Or is this an impossible case, to have a single stripe extent with found_start < start and found_end > end? Thanks. > + if (length == 0) > + break; > + > + btrfs_release_path(path); > + continue; > } > > /* > -- > 2.43.0 > >
diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c index 092e24e1de32..6246ab4c1a21 100644 --- a/fs/btrfs/raid-stripe-tree.c +++ b/fs/btrfs/raid-stripe-tree.c @@ -121,11 +121,18 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le * length to the new size and then re-insert the item. */ if (found_start < start) { - u64 diff = start - found_start; + u64 diff_start = start - found_start; btrfs_partially_delete_raid_extent(trans, path, &key, - diff, 0); - break; + diff_start, 0); + + start += (key.offset - diff_start); + length -= (key.offset - diff_start); + if (length == 0) + break; + + btrfs_release_path(path); + continue; } /*