mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 15:03:53 +02:00
btrfs: implement hole punching for RAID stripe extents
If the stripe extent we want to delete starts before the range we want to delete and ends after the range we want to delete we're punching a hole in the stripe extent: |--- RAID Stripe Extent ---| | keep |--- drop ---| keep | This means we need to a) truncate the existing item and b) create a second item for the remaining range. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
7664311904
commit
6aa0e7cc56
|
|
@ -3833,6 +3833,7 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,
|
|||
btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
|
||||
|
||||
BUG_ON(key.type != BTRFS_EXTENT_DATA_KEY &&
|
||||
key.type != BTRFS_RAID_STRIPE_KEY &&
|
||||
key.type != BTRFS_EXTENT_CSUM_KEY);
|
||||
|
||||
if (btrfs_leaf_free_space(leaf) >= ins_len)
|
||||
|
|
|
|||
|
|
@ -140,6 +140,54 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
|
|||
trace_btrfs_raid_extent_delete(fs_info, start, end,
|
||||
found_start, found_end);
|
||||
|
||||
/*
|
||||
* The stripe extent starts before the range we want to delete
|
||||
* and ends after the range we want to delete, i.e. we're
|
||||
* punching a hole in the stripe extent:
|
||||
*
|
||||
* |--- RAID Stripe Extent ---|
|
||||
* | keep |--- drop ---| keep |
|
||||
*
|
||||
* This means we need to a) truncate the existing item and b)
|
||||
* create a second item for the remaining range.
|
||||
*/
|
||||
if (found_start < start && found_end > end) {
|
||||
size_t item_size;
|
||||
u64 diff_start = start - found_start;
|
||||
u64 diff_end = found_end - end;
|
||||
struct btrfs_stripe_extent *extent;
|
||||
struct btrfs_key newkey = {
|
||||
.objectid = end,
|
||||
.type = BTRFS_RAID_STRIPE_KEY,
|
||||
.offset = diff_end,
|
||||
};
|
||||
|
||||
/* The "right" item. */
|
||||
ret = btrfs_duplicate_item(trans, stripe_root, path, &newkey);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
item_size = btrfs_item_size(leaf, path->slots[0]);
|
||||
extent = btrfs_item_ptr(leaf, path->slots[0],
|
||||
struct btrfs_stripe_extent);
|
||||
|
||||
for (int i = 0; i < btrfs_num_raid_stripes(item_size); i++) {
|
||||
struct btrfs_raid_stride *stride = &extent->strides[i];
|
||||
u64 phys;
|
||||
|
||||
phys = btrfs_raid_stride_physical(leaf, stride);
|
||||
phys += diff_start + length;
|
||||
btrfs_set_raid_stride_physical(leaf, stride, phys);
|
||||
}
|
||||
|
||||
/* The "left" item. */
|
||||
path->slots[0]--;
|
||||
btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
|
||||
btrfs_partially_delete_raid_extent(trans, path, &key,
|
||||
diff_start, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* The stripe extent starts before the range we want to delete:
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user