Skip to content

Commit 6aa0e7c

Browse files
morbidrsakdave
authored andcommitted
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 <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 7664311 commit 6aa0e7c

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

fs/btrfs/ctree.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3833,6 +3833,7 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,
38333833
btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
38343834

38353835
BUG_ON(key.type != BTRFS_EXTENT_DATA_KEY &&
3836+
key.type != BTRFS_RAID_STRIPE_KEY &&
38363837
key.type != BTRFS_EXTENT_CSUM_KEY);
38373838

38383839
if (btrfs_leaf_free_space(leaf) >= ins_len)

fs/btrfs/raid-stripe-tree.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,54 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
140140
trace_btrfs_raid_extent_delete(fs_info, start, end,
141141
found_start, found_end);
142142

143+
/*
144+
* The stripe extent starts before the range we want to delete
145+
* and ends after the range we want to delete, i.e. we're
146+
* punching a hole in the stripe extent:
147+
*
148+
* |--- RAID Stripe Extent ---|
149+
* | keep |--- drop ---| keep |
150+
*
151+
* This means we need to a) truncate the existing item and b)
152+
* create a second item for the remaining range.
153+
*/
154+
if (found_start < start && found_end > end) {
155+
size_t item_size;
156+
u64 diff_start = start - found_start;
157+
u64 diff_end = found_end - end;
158+
struct btrfs_stripe_extent *extent;
159+
struct btrfs_key newkey = {
160+
.objectid = end,
161+
.type = BTRFS_RAID_STRIPE_KEY,
162+
.offset = diff_end,
163+
};
164+
165+
/* The "right" item. */
166+
ret = btrfs_duplicate_item(trans, stripe_root, path, &newkey);
167+
if (ret)
168+
break;
169+
170+
item_size = btrfs_item_size(leaf, path->slots[0]);
171+
extent = btrfs_item_ptr(leaf, path->slots[0],
172+
struct btrfs_stripe_extent);
173+
174+
for (int i = 0; i < btrfs_num_raid_stripes(item_size); i++) {
175+
struct btrfs_raid_stride *stride = &extent->strides[i];
176+
u64 phys;
177+
178+
phys = btrfs_raid_stride_physical(leaf, stride);
179+
phys += diff_start + length;
180+
btrfs_set_raid_stride_physical(leaf, stride, phys);
181+
}
182+
183+
/* The "left" item. */
184+
path->slots[0]--;
185+
btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
186+
btrfs_partially_delete_raid_extent(trans, path, &key,
187+
diff_start, 0);
188+
break;
189+
}
190+
143191
/*
144192
* The stripe extent starts before the range we want to delete:
145193
*

0 commit comments

Comments
 (0)