1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2023 Western Digital Corporation or its affiliates.
6 #include <linux/btrfs_tree.h>
10 #include "transaction.h"
12 #include "raid-stripe-tree.h"
14 #include "print-tree.h"
16 static void btrfs_partially_delete_raid_extent(struct btrfs_trans_handle
*trans
,
17 struct btrfs_path
*path
,
18 const struct btrfs_key
*oldkey
,
19 u64 newlen
, u64 frontpad
)
21 struct btrfs_stripe_extent
*extent
;
22 struct extent_buffer
*leaf
;
25 struct btrfs_key newkey
= {
26 .objectid
= oldkey
->objectid
+ frontpad
,
27 .type
= BTRFS_RAID_STRIPE_KEY
,
31 ASSERT(oldkey
->type
== BTRFS_RAID_STRIPE_KEY
);
33 leaf
= path
->nodes
[0];
34 slot
= path
->slots
[0];
35 item_size
= btrfs_item_size(leaf
, slot
);
36 extent
= btrfs_item_ptr(leaf
, slot
, struct btrfs_stripe_extent
);
38 for (int i
= 0; i
< btrfs_num_raid_stripes(item_size
); i
++) {
39 struct btrfs_raid_stride
*stride
= &extent
->strides
[i
];
42 phys
= btrfs_raid_stride_physical(leaf
, stride
);
43 btrfs_set_raid_stride_physical(leaf
, stride
, phys
+ frontpad
);
46 btrfs_set_item_key_safe(trans
, path
, &newkey
);
49 int btrfs_delete_raid_extent(struct btrfs_trans_handle
*trans
, u64 start
, u64 length
)
51 struct btrfs_fs_info
*fs_info
= trans
->fs_info
;
52 struct btrfs_root
*stripe_root
= fs_info
->stripe_root
;
53 struct btrfs_path
*path
;
55 struct extent_buffer
*leaf
;
58 u64 end
= start
+ length
;
65 path
= btrfs_alloc_path();
71 key
.type
= BTRFS_RAID_STRIPE_KEY
;
74 ret
= btrfs_search_slot(trans
, stripe_root
, &key
, path
, -1, 1);
78 if (path
->slots
[0] == btrfs_header_nritems(path
->nodes
[0]))
81 leaf
= path
->nodes
[0];
82 slot
= path
->slots
[0];
83 btrfs_item_key_to_cpu(leaf
, &key
, slot
);
84 found_start
= key
.objectid
;
85 found_end
= found_start
+ key
.offset
;
88 if (key
.type
!= BTRFS_RAID_STRIPE_KEY
)
91 /* That stripe ends before we start, we're done. */
92 if (found_end
<= start
)
95 trace_btrfs_raid_extent_delete(fs_info
, start
, end
,
96 found_start
, found_end
);
99 * The stripe extent starts before the range we want to delete:
101 * |--- RAID Stripe Extent ---|
102 * |--- keep ---|--- drop ---|
104 * This means we have to duplicate the tree item, truncate the
105 * length to the new size and then re-insert the item.
107 if (found_start
< start
) {
108 u64 diff
= start
- found_start
;
110 btrfs_partially_delete_raid_extent(trans
, path
, &key
,
116 * The stripe extent ends after the range we want to delete:
118 * |--- RAID Stripe Extent ---|
119 * |--- drop ---|--- keep ---|
121 * This means we have to duplicate the tree item, truncate the
122 * length to the new size and then re-insert the item.
124 if (found_end
> end
) {
125 u64 diff
= found_end
- end
;
127 btrfs_partially_delete_raid_extent(trans
, path
, &key
,
132 ret
= btrfs_del_item(trans
, stripe_root
, path
);
137 length
-= key
.offset
;
141 btrfs_release_path(path
);
144 btrfs_free_path(path
);
148 static int update_raid_extent_item(struct btrfs_trans_handle
*trans
,
149 struct btrfs_key
*key
,
150 struct btrfs_stripe_extent
*stripe_extent
,
151 const size_t item_size
)
153 struct btrfs_path
*path
;
154 struct extent_buffer
*leaf
;
158 path
= btrfs_alloc_path();
162 ret
= btrfs_search_slot(trans
, trans
->fs_info
->stripe_root
, key
, path
,
165 return (ret
== 1 ? ret
: -EINVAL
);
167 leaf
= path
->nodes
[0];
168 slot
= path
->slots
[0];
170 write_extent_buffer(leaf
, stripe_extent
, btrfs_item_ptr_offset(leaf
, slot
),
172 btrfs_mark_buffer_dirty(trans
, leaf
);
173 btrfs_free_path(path
);
179 int btrfs_insert_one_raid_extent(struct btrfs_trans_handle
*trans
,
180 struct btrfs_io_context
*bioc
)
182 struct btrfs_fs_info
*fs_info
= trans
->fs_info
;
183 struct btrfs_key stripe_key
;
184 struct btrfs_root
*stripe_root
= fs_info
->stripe_root
;
185 const int num_stripes
= btrfs_bg_type_to_factor(bioc
->map_type
);
186 struct btrfs_stripe_extent
*stripe_extent
;
187 const size_t item_size
= struct_size(stripe_extent
, strides
, num_stripes
);
190 stripe_extent
= kzalloc(item_size
, GFP_NOFS
);
191 if (!stripe_extent
) {
192 btrfs_abort_transaction(trans
, -ENOMEM
);
193 btrfs_end_transaction(trans
);
197 trace_btrfs_insert_one_raid_extent(fs_info
, bioc
->logical
, bioc
->size
,
199 for (int i
= 0; i
< num_stripes
; i
++) {
200 u64 devid
= bioc
->stripes
[i
].dev
->devid
;
201 u64 physical
= bioc
->stripes
[i
].physical
;
202 u64 length
= bioc
->stripes
[i
].length
;
203 struct btrfs_raid_stride
*raid_stride
= &stripe_extent
->strides
[i
];
208 btrfs_set_stack_raid_stride_devid(raid_stride
, devid
);
209 btrfs_set_stack_raid_stride_physical(raid_stride
, physical
);
212 stripe_key
.objectid
= bioc
->logical
;
213 stripe_key
.type
= BTRFS_RAID_STRIPE_KEY
;
214 stripe_key
.offset
= bioc
->size
;
216 ret
= btrfs_insert_item(trans
, stripe_root
, &stripe_key
, stripe_extent
,
219 ret
= update_raid_extent_item(trans
, &stripe_key
, stripe_extent
,
222 btrfs_abort_transaction(trans
, ret
);
224 kfree(stripe_extent
);
229 int btrfs_insert_raid_extent(struct btrfs_trans_handle
*trans
,
230 struct btrfs_ordered_extent
*ordered_extent
)
232 struct btrfs_io_context
*bioc
;
235 if (!btrfs_fs_incompat(trans
->fs_info
, RAID_STRIPE_TREE
))
238 list_for_each_entry(bioc
, &ordered_extent
->bioc_list
, rst_ordered_entry
) {
239 ret
= btrfs_insert_one_raid_extent(trans
, bioc
);
244 while (!list_empty(&ordered_extent
->bioc_list
)) {
245 bioc
= list_first_entry(&ordered_extent
->bioc_list
,
246 typeof(*bioc
), rst_ordered_entry
);
247 list_del(&bioc
->rst_ordered_entry
);
248 btrfs_put_bioc(bioc
);
254 int btrfs_get_raid_extent_offset(struct btrfs_fs_info
*fs_info
,
255 u64 logical
, u64
*length
, u64 map_type
,
256 u32 stripe_index
, struct btrfs_io_stripe
*stripe
)
258 struct btrfs_root
*stripe_root
= fs_info
->stripe_root
;
259 struct btrfs_stripe_extent
*stripe_extent
;
260 struct btrfs_key stripe_key
;
261 struct btrfs_key found_key
;
262 struct btrfs_path
*path
;
263 struct extent_buffer
*leaf
;
264 const u64 end
= logical
+ *length
;
273 stripe_key
.objectid
= logical
;
274 stripe_key
.type
= BTRFS_RAID_STRIPE_KEY
;
275 stripe_key
.offset
= 0;
277 path
= btrfs_alloc_path();
281 if (stripe
->rst_search_commit_root
) {
282 path
->skip_locking
= 1;
283 path
->search_commit_root
= 1;
286 ret
= btrfs_search_slot(NULL
, stripe_root
, &stripe_key
, path
, 0, 0);
290 if (path
->slots
[0] != 0)
295 leaf
= path
->nodes
[0];
296 slot
= path
->slots
[0];
298 btrfs_item_key_to_cpu(leaf
, &found_key
, slot
);
299 found_logical
= found_key
.objectid
;
300 found_length
= found_key
.offset
;
301 found_end
= found_logical
+ found_length
;
303 if (found_logical
> end
) {
308 if (in_range(logical
, found_logical
, found_length
))
311 ret
= btrfs_next_item(stripe_root
, path
);
316 offset
= logical
- found_logical
;
319 * If we have a logically contiguous, but physically non-continuous
320 * range, we need to split the bio. Record the length after which we
321 * must split the bio.
324 *length
-= end
- found_end
;
326 num_stripes
= btrfs_num_raid_stripes(btrfs_item_size(leaf
, slot
));
327 stripe_extent
= btrfs_item_ptr(leaf
, slot
, struct btrfs_stripe_extent
);
329 for (int i
= 0; i
< num_stripes
; i
++) {
330 struct btrfs_raid_stride
*stride
= &stripe_extent
->strides
[i
];
331 u64 devid
= btrfs_raid_stride_devid(leaf
, stride
);
332 u64 physical
= btrfs_raid_stride_physical(leaf
, stride
);
334 if (devid
!= stripe
->dev
->devid
)
337 if ((map_type
& BTRFS_BLOCK_GROUP_DUP
) && stripe_index
!= i
)
340 stripe
->physical
= physical
+ offset
;
342 trace_btrfs_get_raid_extent_offset(fs_info
, logical
, *length
,
343 stripe
->physical
, devid
);
349 /* If we're here, we haven't found the requested devid in the stripe. */
354 if (ret
&& ret
!= -EIO
&& !stripe
->rst_search_commit_root
) {
356 "cannot find raid-stripe for logical [%llu, %llu] devid %llu, profile %s",
357 logical
, logical
+ *length
, stripe
->dev
->devid
,
358 btrfs_bg_type_to_raid_name(map_type
));
361 btrfs_free_path(path
);