1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2024 Western Digital Corporation or its affiliates.
6 #include <linux/sizes.h>
8 #include "../disk-io.h"
9 #include "../transaction.h"
10 #include "../volumes.h"
11 #include "../raid-stripe-tree.h"
12 #include "btrfs-tests.h"
14 #define RST_TEST_NUM_DEVICES (2)
15 #define RST_TEST_RAID1_TYPE (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_RAID1)
17 typedef int (*test_func_t
)(struct btrfs_trans_handle
*trans
);
19 static struct btrfs_device
*btrfs_device_by_devid(struct btrfs_fs_devices
*fs_devices
,
22 struct btrfs_device
*dev
;
24 list_for_each_entry(dev
, &fs_devices
->devices
, dev_list
) {
25 if (dev
->devid
== devid
)
33 * Test a 64K RST write on a 2 disk RAID1 at a logical address of 1M and then
34 * delete the 1st 32K, making the new start address 1M+32K.
36 static int test_front_delete(struct btrfs_trans_handle
*trans
)
38 struct btrfs_fs_info
*fs_info
= trans
->fs_info
;
39 struct btrfs_io_context
*bioc
;
40 struct btrfs_io_stripe io_stripe
= { 0 };
41 u64 map_type
= RST_TEST_RAID1_TYPE
;
46 bioc
= alloc_btrfs_io_context(fs_info
, logical
, RST_TEST_NUM_DEVICES
);
48 test_std_err(TEST_ALLOC_IO_CONTEXT
);
53 io_stripe
.dev
= btrfs_device_by_devid(fs_info
->fs_devices
, 0);
54 bioc
->map_type
= map_type
;
57 for (int i
= 0; i
< RST_TEST_NUM_DEVICES
; i
++) {
58 struct btrfs_io_stripe
*stripe
= &bioc
->stripes
[i
];
60 stripe
->dev
= btrfs_device_by_devid(fs_info
->fs_devices
, i
);
62 test_err("cannot find device with devid %d", i
);
67 stripe
->physical
= logical
+ i
* SZ_1G
;
70 ret
= btrfs_insert_one_raid_extent(trans
, bioc
);
72 test_err("inserting RAID extent failed: %d", ret
);
76 ret
= btrfs_get_raid_extent_offset(fs_info
, logical
, &len
, map_type
, 0, &io_stripe
);
78 test_err("lookup of RAID extent [%llu, %llu] failed", logical
,
83 if (io_stripe
.physical
!= logical
) {
84 test_err("invalid physical address, expected %llu got %llu",
85 logical
, io_stripe
.physical
);
91 test_err("invalid stripe length, expected %llu got %llu",
97 ret
= btrfs_delete_raid_extent(trans
, logical
, SZ_32K
);
99 test_err("deleting RAID extent [%llu, %llu] failed", logical
,
105 ret
= btrfs_get_raid_extent_offset(fs_info
, logical
+ SZ_32K
, &len
,
106 map_type
, 0, &io_stripe
);
108 test_err("lookup of RAID extent [%llu, %llu] failed",
109 logical
+ SZ_32K
, logical
+ SZ_32K
+ len
);
113 if (io_stripe
.physical
!= logical
+ SZ_32K
) {
114 test_err("invalid physical address, expected %llu, got %llu",
115 logical
+ SZ_32K
, io_stripe
.physical
);
121 test_err("invalid stripe length, expected %llu, got %llu",
127 ret
= btrfs_get_raid_extent_offset(fs_info
, logical
, &len
, map_type
, 0, &io_stripe
);
130 test_err("lookup of RAID extent [%llu, %llu] succeeded, should fail",
131 logical
, logical
+ SZ_32K
);
135 ret
= btrfs_delete_raid_extent(trans
, logical
+ SZ_32K
, SZ_32K
);
137 btrfs_put_bioc(bioc
);
142 * Test a 64K RST write on a 2 disk RAID1 at a logical address of 1M and then
143 * truncate the stripe extent down to 32K.
145 static int test_tail_delete(struct btrfs_trans_handle
*trans
)
147 struct btrfs_fs_info
*fs_info
= trans
->fs_info
;
148 struct btrfs_io_context
*bioc
;
149 struct btrfs_io_stripe io_stripe
= { 0 };
150 u64 map_type
= RST_TEST_RAID1_TYPE
;
155 bioc
= alloc_btrfs_io_context(fs_info
, logical
, RST_TEST_NUM_DEVICES
);
157 test_std_err(TEST_ALLOC_IO_CONTEXT
);
162 io_stripe
.dev
= btrfs_device_by_devid(fs_info
->fs_devices
, 0);
163 bioc
->map_type
= map_type
;
166 for (int i
= 0; i
< RST_TEST_NUM_DEVICES
; i
++) {
167 struct btrfs_io_stripe
*stripe
= &bioc
->stripes
[i
];
169 stripe
->dev
= btrfs_device_by_devid(fs_info
->fs_devices
, i
);
171 test_err("cannot find device with devid %d", i
);
176 stripe
->physical
= logical
+ i
* SZ_1G
;
179 ret
= btrfs_insert_one_raid_extent(trans
, bioc
);
181 test_err("inserting RAID extent failed: %d", ret
);
185 io_stripe
.dev
= btrfs_device_by_devid(fs_info
->fs_devices
, 0);
186 if (!io_stripe
.dev
) {
191 ret
= btrfs_get_raid_extent_offset(fs_info
, logical
, &len
, map_type
, 0, &io_stripe
);
193 test_err("lookup of RAID extent [%llu, %llu] failed", logical
,
198 if (io_stripe
.physical
!= logical
) {
199 test_err("invalid physical address, expected %llu got %llu",
200 logical
, io_stripe
.physical
);
206 test_err("invalid stripe length, expected %llu got %llu",
212 ret
= btrfs_delete_raid_extent(trans
, logical
+ SZ_32K
, SZ_32K
);
214 test_err("deleting RAID extent [%llu, %llu] failed",
215 logical
+ SZ_32K
, logical
+ SZ_64K
);
220 ret
= btrfs_get_raid_extent_offset(fs_info
, logical
, &len
, map_type
, 0, &io_stripe
);
222 test_err("lookup of RAID extent [%llu, %llu] failed", logical
,
227 if (io_stripe
.physical
!= logical
) {
228 test_err("invalid physical address, expected %llu, got %llu",
229 logical
, io_stripe
.physical
);
235 test_err("invalid stripe length, expected %llu, got %llu",
241 ret
= btrfs_delete_raid_extent(trans
, logical
, len
);
243 test_err("deleting RAID extent [%llu, %llu] failed", logical
,
247 btrfs_put_bioc(bioc
);
252 * Test a 64K RST write on a 2 disk RAID1 at a logical address of 1M and then
253 * overwrite the whole range giving it new physical address at an offset of 1G.
254 * The intent of this test is to exercise the 'update_raid_extent_item()'
255 * function called be btrfs_insert_one_raid_extent().
257 static int test_create_update_delete(struct btrfs_trans_handle
*trans
)
259 struct btrfs_fs_info
*fs_info
= trans
->fs_info
;
260 struct btrfs_io_context
*bioc
;
261 struct btrfs_io_stripe io_stripe
= { 0 };
262 u64 map_type
= RST_TEST_RAID1_TYPE
;
267 bioc
= alloc_btrfs_io_context(fs_info
, logical
, RST_TEST_NUM_DEVICES
);
269 test_std_err(TEST_ALLOC_IO_CONTEXT
);
274 io_stripe
.dev
= btrfs_device_by_devid(fs_info
->fs_devices
, 0);
275 bioc
->map_type
= map_type
;
278 for (int i
= 0; i
< RST_TEST_NUM_DEVICES
; i
++) {
279 struct btrfs_io_stripe
*stripe
= &bioc
->stripes
[i
];
281 stripe
->dev
= btrfs_device_by_devid(fs_info
->fs_devices
, i
);
283 test_err("cannot find device with devid %d", i
);
288 stripe
->physical
= logical
+ i
* SZ_1G
;
291 ret
= btrfs_insert_one_raid_extent(trans
, bioc
);
293 test_err("inserting RAID extent failed: %d", ret
);
297 io_stripe
.dev
= btrfs_device_by_devid(fs_info
->fs_devices
, 0);
298 if (!io_stripe
.dev
) {
303 ret
= btrfs_get_raid_extent_offset(fs_info
, logical
, &len
, map_type
, 0, &io_stripe
);
305 test_err("lookup of RAID extent [%llu, %llu] failed", logical
,
310 if (io_stripe
.physical
!= logical
) {
311 test_err("invalid physical address, expected %llu got %llu",
312 logical
, io_stripe
.physical
);
318 test_err("invalid stripe length, expected %llu got %llu",
324 for (int i
= 0; i
< RST_TEST_NUM_DEVICES
; i
++) {
325 struct btrfs_io_stripe
*stripe
= &bioc
->stripes
[i
];
327 stripe
->dev
= btrfs_device_by_devid(fs_info
->fs_devices
, i
);
329 test_err("cannot find device with devid %d", i
);
334 stripe
->physical
= SZ_1G
+ logical
+ i
* SZ_1G
;
337 ret
= btrfs_insert_one_raid_extent(trans
, bioc
);
339 test_err("updating RAID extent failed: %d", ret
);
343 ret
= btrfs_get_raid_extent_offset(fs_info
, logical
, &len
, map_type
, 0, &io_stripe
);
345 test_err("lookup of RAID extent [%llu, %llu] failed", logical
,
350 if (io_stripe
.physical
!= logical
+ SZ_1G
) {
351 test_err("invalid physical address, expected %llu, got %llu",
352 logical
+ SZ_1G
, io_stripe
.physical
);
358 test_err("invalid stripe length, expected %llu, got %llu",
364 ret
= btrfs_delete_raid_extent(trans
, logical
, len
);
366 test_err("deleting RAID extent [%llu, %llu] failed", logical
,
370 btrfs_put_bioc(bioc
);
375 * Test a simple 64K RST write on a 2 disk RAID1 at a logical address of 1M.
376 * The "physical" copy on device 0 is at 1M, on device 1 it is at 1G+1M.
378 static int test_simple_create_delete(struct btrfs_trans_handle
*trans
)
380 struct btrfs_fs_info
*fs_info
= trans
->fs_info
;
381 struct btrfs_io_context
*bioc
;
382 struct btrfs_io_stripe io_stripe
= { 0 };
383 u64 map_type
= RST_TEST_RAID1_TYPE
;
388 bioc
= alloc_btrfs_io_context(fs_info
, logical
, RST_TEST_NUM_DEVICES
);
390 test_std_err(TEST_ALLOC_IO_CONTEXT
);
395 bioc
->map_type
= map_type
;
398 for (int i
= 0; i
< RST_TEST_NUM_DEVICES
; i
++) {
399 struct btrfs_io_stripe
*stripe
= &bioc
->stripes
[i
];
401 stripe
->dev
= btrfs_device_by_devid(fs_info
->fs_devices
, i
);
403 test_err("cannot find device with devid %d", i
);
408 stripe
->physical
= logical
+ i
* SZ_1G
;
411 ret
= btrfs_insert_one_raid_extent(trans
, bioc
);
413 test_err("inserting RAID extent failed: %d", ret
);
417 io_stripe
.dev
= btrfs_device_by_devid(fs_info
->fs_devices
, 0);
418 if (!io_stripe
.dev
) {
423 ret
= btrfs_get_raid_extent_offset(fs_info
, logical
, &len
, map_type
, 0, &io_stripe
);
425 test_err("lookup of RAID extent [%llu, %llu] failed", logical
,
430 if (io_stripe
.physical
!= logical
) {
431 test_err("invalid physical address, expected %llu got %llu",
432 logical
, io_stripe
.physical
);
438 test_err("invalid stripe length, expected %llu got %llu",
444 ret
= btrfs_delete_raid_extent(trans
, logical
, len
);
446 test_err("deleting RAID extent [%llu, %llu] failed", logical
,
450 btrfs_put_bioc(bioc
);
454 static const test_func_t tests
[] = {
455 test_simple_create_delete
,
456 test_create_update_delete
,
461 static int run_test(test_func_t test
, u32 sectorsize
, u32 nodesize
)
463 struct btrfs_trans_handle trans
;
464 struct btrfs_fs_info
*fs_info
;
465 struct btrfs_root
*root
= NULL
;
468 fs_info
= btrfs_alloc_dummy_fs_info(sectorsize
, nodesize
);
470 test_std_err(TEST_ALLOC_FS_INFO
);
475 root
= btrfs_alloc_dummy_root(fs_info
);
477 test_std_err(TEST_ALLOC_ROOT
);
481 btrfs_set_super_compat_ro_flags(root
->fs_info
->super_copy
,
482 BTRFS_FEATURE_INCOMPAT_RAID_STRIPE_TREE
);
483 root
->root_key
.objectid
= BTRFS_RAID_STRIPE_TREE_OBJECTID
;
484 root
->root_key
.type
= BTRFS_ROOT_ITEM_KEY
;
485 root
->root_key
.offset
= 0;
486 fs_info
->stripe_root
= root
;
487 root
->fs_info
->tree_root
= root
;
489 root
->node
= alloc_test_extent_buffer(root
->fs_info
, nodesize
);
490 if (IS_ERR(root
->node
)) {
491 test_std_err(TEST_ALLOC_EXTENT_BUFFER
);
492 ret
= PTR_ERR(root
->node
);
495 btrfs_set_header_level(root
->node
, 0);
496 btrfs_set_header_nritems(root
->node
, 0);
497 root
->alloc_bytenr
+= 2 * nodesize
;
499 for (int i
= 0; i
< RST_TEST_NUM_DEVICES
; i
++) {
500 struct btrfs_device
*dev
;
502 dev
= btrfs_alloc_dummy_device(fs_info
);
504 test_err("cannot allocate device");
511 btrfs_init_dummy_trans(&trans
, root
->fs_info
);
517 btrfs_free_dummy_root(root
);
518 btrfs_free_dummy_fs_info(fs_info
);
523 int btrfs_test_raid_stripe_tree(u32 sectorsize
, u32 nodesize
)
527 test_msg("running raid-stripe-tree tests");
528 for (int i
= 0; i
< ARRAY_SIZE(tests
); i
++) {
529 ret
= run_test(tests
[i
], sectorsize
, nodesize
);
531 test_err("test-case %ps failed with %d\n", tests
[i
], ret
);