1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2024 Western Digital Corporation or its affiliates.
4 */
5
6 #include <linux/sizes.h>
7 #include "../fs.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"
13
14 #define RST_TEST_NUM_DEVICES (2)
15 #define RST_TEST_RAID1_TYPE (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_RAID1)
16
17 #define SZ_48K (SZ_32K + SZ_16K)
18
19 typedef int (*test_func_t)(struct btrfs_trans_handle *trans);
20
btrfs_device_by_devid(struct btrfs_fs_devices * fs_devices,u64 devid)21 static struct btrfs_device *btrfs_device_by_devid(struct btrfs_fs_devices *fs_devices,
22 u64 devid)
23 {
24 struct btrfs_device *dev;
25
26 list_for_each_entry(dev, &fs_devices->devices, dev_list) {
27 if (dev->devid == devid)
28 return dev;
29 }
30
31 return NULL;
32 }
33
34 /*
35 * Test creating a range of three extents and then punch a hole in the middle,
36 * deleting all of the middle extents and partially deleting the "book ends".
37 */
test_punch_hole_3extents(struct btrfs_trans_handle * trans)38 static int test_punch_hole_3extents(struct btrfs_trans_handle *trans)
39 {
40 struct btrfs_fs_info *fs_info = trans->fs_info;
41 struct btrfs_io_context *bioc;
42 struct btrfs_io_stripe io_stripe = { 0 };
43 u64 map_type = RST_TEST_RAID1_TYPE;
44 u64 logical1 = SZ_1M;
45 u64 len1 = SZ_1M;
46 u64 logical2 = logical1 + len1;
47 u64 len2 = SZ_1M;
48 u64 logical3 = logical2 + len2;
49 u64 len3 = SZ_1M;
50 u64 hole_start = logical1 + SZ_256K;
51 u64 hole_len = SZ_2M;
52 int ret;
53
54 bioc = alloc_btrfs_io_context(fs_info, logical1, RST_TEST_NUM_DEVICES);
55 if (!bioc) {
56 test_std_err(TEST_ALLOC_IO_CONTEXT);
57 ret = -ENOMEM;
58 goto out;
59 }
60
61 io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
62
63 /* Prepare for the test, 1st create 3 x 1M extents. */
64 bioc->map_type = map_type;
65 bioc->size = len1;
66
67 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
68 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
69
70 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
71 if (!stripe->dev) {
72 test_err("cannot find device with devid %d", i);
73 ret = -EINVAL;
74 goto out;
75 }
76
77 stripe->physical = logical1 + i * SZ_1G;
78 }
79
80 ret = btrfs_insert_one_raid_extent(trans, bioc);
81 if (ret) {
82 test_err("inserting RAID extent failed: %d", ret);
83 goto out;
84 }
85
86 bioc->logical = logical2;
87 bioc->size = len2;
88 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
89 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
90
91 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
92 if (!stripe->dev) {
93 test_err("cannot find device with devid %d", i);
94 ret = -EINVAL;
95 goto out;
96 }
97
98 stripe->physical = logical2 + i * SZ_1G;
99 }
100
101 ret = btrfs_insert_one_raid_extent(trans, bioc);
102 if (ret) {
103 test_err("inserting RAID extent failed: %d", ret);
104 goto out;
105 }
106
107 bioc->logical = logical3;
108 bioc->size = len3;
109 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
110 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
111
112 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
113 if (!stripe->dev) {
114 test_err("cannot find device with devid %d", i);
115 ret = -EINVAL;
116 goto out;
117 }
118
119 stripe->physical = logical3 + i * SZ_1G;
120 }
121
122 ret = btrfs_insert_one_raid_extent(trans, bioc);
123 if (ret) {
124 test_err("inserting RAID extent failed: %d", ret);
125 goto out;
126 }
127
128 /*
129 * Delete a range starting at logical1 + 256K and 2M in length. Extent
130 * 1 is truncated to 256k length, extent 2 is completely dropped and
131 * extent 3 is moved 256K to the right.
132 */
133 ret = btrfs_delete_raid_extent(trans, hole_start, hole_len);
134 if (ret) {
135 test_err("deleting RAID extent [%llu, %llu] failed",
136 hole_start, hole_start + hole_len);
137 goto out;
138 }
139
140 /* Get the first extent and check its size. */
141 ret = btrfs_get_raid_extent_offset(fs_info, logical1, &len1, map_type,
142 0, &io_stripe);
143 if (ret) {
144 test_err("lookup of RAID extent [%llu, %llu] failed",
145 logical1, logical1 + len1);
146 goto out;
147 }
148
149 if (io_stripe.physical != logical1) {
150 test_err("invalid physical address, expected %llu, got %llu",
151 logical1, io_stripe.physical);
152 ret = -EINVAL;
153 goto out;
154 }
155
156 if (len1 != SZ_256K) {
157 test_err("invalid stripe length, expected %llu, got %llu",
158 (u64)SZ_256K, len1);
159 ret = -EINVAL;
160 goto out;
161 }
162
163 /* Get the second extent and check it's absent. */
164 ret = btrfs_get_raid_extent_offset(fs_info, logical2, &len2, map_type,
165 0, &io_stripe);
166 if (ret != -ENODATA) {
167 test_err("lookup of RAID extent [%llu, %llu] succeeded should fail",
168 logical2, logical2 + len2);
169 ret = -EINVAL;
170 goto out;
171 }
172
173 /* Get the third extent and check its size. */
174 logical3 += SZ_256K;
175 ret = btrfs_get_raid_extent_offset(fs_info, logical3, &len3, map_type,
176 0, &io_stripe);
177 if (ret) {
178 test_err("lookup of RAID extent [%llu, %llu] failed",
179 logical3, logical3 + len3);
180 goto out;
181 }
182
183 if (io_stripe.physical != logical3) {
184 test_err("invalid physical address, expected %llu, got %llu",
185 logical3 + SZ_256K, io_stripe.physical);
186 ret = -EINVAL;
187 goto out;
188 }
189
190 if (len3 != SZ_1M - SZ_256K) {
191 test_err("invalid stripe length, expected %llu, got %llu",
192 (u64)SZ_1M - SZ_256K, len3);
193 ret = -EINVAL;
194 goto out;
195 }
196
197 ret = btrfs_delete_raid_extent(trans, logical1, len1);
198 if (ret) {
199 test_err("deleting RAID extent [%llu, %llu] failed",
200 logical1, logical1 + len1);
201 goto out;
202 }
203
204 ret = btrfs_delete_raid_extent(trans, logical3, len3);
205 if (ret) {
206 test_err("deleting RAID extent [%llu, %llu] failed",
207 logical1, logical1 + len1);
208 goto out;
209 }
210
211 out:
212 btrfs_put_bioc(bioc);
213 return ret;
214 }
215
test_delete_two_extents(struct btrfs_trans_handle * trans)216 static int test_delete_two_extents(struct btrfs_trans_handle *trans)
217 {
218 struct btrfs_fs_info *fs_info = trans->fs_info;
219 struct btrfs_io_context *bioc;
220 struct btrfs_io_stripe io_stripe = { 0 };
221 u64 map_type = RST_TEST_RAID1_TYPE;
222 u64 logical1 = SZ_1M;
223 u64 len1 = SZ_1M;
224 u64 logical2 = logical1 + len1;
225 u64 len2 = SZ_1M;
226 u64 logical3 = logical2 + len2;
227 u64 len3 = SZ_1M;
228 int ret;
229
230 bioc = alloc_btrfs_io_context(fs_info, logical1, RST_TEST_NUM_DEVICES);
231 if (!bioc) {
232 test_std_err(TEST_ALLOC_IO_CONTEXT);
233 ret = -ENOMEM;
234 goto out;
235 }
236
237 io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
238
239 /* Prepare for the test, 1st create 3 x 1M extents. */
240 bioc->map_type = map_type;
241 bioc->size = len1;
242
243 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
244 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
245
246 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
247 if (!stripe->dev) {
248 test_err("cannot find device with devid %d", i);
249 ret = -EINVAL;
250 goto out;
251 }
252
253 stripe->physical = logical1 + i * SZ_1G;
254 }
255
256 ret = btrfs_insert_one_raid_extent(trans, bioc);
257 if (ret) {
258 test_err("inserting RAID extent failed: %d", ret);
259 goto out;
260 }
261
262 bioc->logical = logical2;
263 bioc->size = len2;
264 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
265 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
266
267 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
268 if (!stripe->dev) {
269 test_err("cannot find device with devid %d", i);
270 ret = -EINVAL;
271 goto out;
272 }
273
274 stripe->physical = logical2 + i * SZ_1G;
275 }
276
277 ret = btrfs_insert_one_raid_extent(trans, bioc);
278 if (ret) {
279 test_err("inserting RAID extent failed: %d", ret);
280 goto out;
281 }
282
283 bioc->logical = logical3;
284 bioc->size = len3;
285 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
286 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
287
288 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
289 if (!stripe->dev) {
290 test_err("cannot find device with devid %d", i);
291 ret = -EINVAL;
292 goto out;
293 }
294
295 stripe->physical = logical3 + i * SZ_1G;
296 }
297
298 ret = btrfs_insert_one_raid_extent(trans, bioc);
299 if (ret) {
300 test_err("inserting RAID extent failed: %d", ret);
301 goto out;
302 }
303
304 /*
305 * Delete a range starting at logical1 and 2M in length. Extents 1
306 * and 2 are dropped and extent 3 is kept as is.
307 */
308 ret = btrfs_delete_raid_extent(trans, logical1, len1 + len2);
309 if (ret) {
310 test_err("deleting RAID extent [%llu, %llu] failed",
311 logical1, logical1 + len1 + len2);
312 goto out;
313 }
314
315 ret = btrfs_get_raid_extent_offset(fs_info, logical1, &len1, map_type,
316 0, &io_stripe);
317 if (ret != -ENODATA) {
318 test_err("lookup of RAID extent [%llu, %llu] succeeded, should fail",
319 logical1, len1);
320 goto out;
321 }
322
323 ret = btrfs_get_raid_extent_offset(fs_info, logical2, &len2, map_type,
324 0, &io_stripe);
325 if (ret != -ENODATA) {
326 test_err("lookup of RAID extent [%llu, %llu] succeeded, should fail",
327 logical2, len2);
328 goto out;
329 }
330
331 ret = btrfs_get_raid_extent_offset(fs_info, logical3, &len3, map_type,
332 0, &io_stripe);
333 if (ret) {
334 test_err("lookup of RAID extent [%llu, %llu] failed",
335 logical3, len3);
336 goto out;
337 }
338
339 if (io_stripe.physical != logical3) {
340 test_err("invalid physical address, expected %llu, got %llu",
341 logical3, io_stripe.physical);
342 ret = -EINVAL;
343 goto out;
344 }
345
346 if (len3 != SZ_1M) {
347 test_err("invalid stripe length, expected %llu, got %llu",
348 (u64)SZ_1M, len3);
349 ret = -EINVAL;
350 goto out;
351 }
352
353 ret = btrfs_delete_raid_extent(trans, logical3, len3);
354 out:
355 btrfs_put_bioc(bioc);
356 return ret;
357 }
358
359 /* Test punching a hole into a single RAID stripe-extent. */
test_punch_hole(struct btrfs_trans_handle * trans)360 static int test_punch_hole(struct btrfs_trans_handle *trans)
361 {
362 struct btrfs_fs_info *fs_info = trans->fs_info;
363 struct btrfs_io_context *bioc;
364 struct btrfs_io_stripe io_stripe = { 0 };
365 u64 map_type = RST_TEST_RAID1_TYPE;
366 u64 logical1 = SZ_1M;
367 u64 hole_start = logical1 + SZ_32K;
368 u64 hole_len = SZ_64K;
369 u64 logical2 = hole_start + hole_len;
370 u64 len = SZ_1M;
371 u64 len1 = SZ_32K;
372 u64 len2 = len - len1 - hole_len;
373 int ret;
374
375 bioc = alloc_btrfs_io_context(fs_info, logical1, RST_TEST_NUM_DEVICES);
376 if (!bioc) {
377 test_std_err(TEST_ALLOC_IO_CONTEXT);
378 ret = -ENOMEM;
379 goto out;
380 }
381
382 io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
383 bioc->map_type = map_type;
384 bioc->size = len;
385
386 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
387 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
388
389 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
390 if (!stripe->dev) {
391 test_err("cannot find device with devid %d", i);
392 ret = -EINVAL;
393 goto out;
394 }
395
396 stripe->physical = logical1 + i * SZ_1G;
397 }
398
399 ret = btrfs_insert_one_raid_extent(trans, bioc);
400 if (ret) {
401 test_err("inserting RAID extent failed: %d", ret);
402 goto out;
403 }
404
405 ret = btrfs_get_raid_extent_offset(fs_info, logical1, &len, map_type, 0,
406 &io_stripe);
407 if (ret) {
408 test_err("lookup of RAID extent [%llu, %llu] failed", logical1,
409 logical1 + len);
410 goto out;
411 }
412
413 if (io_stripe.physical != logical1) {
414 test_err("invalid physical address, expected %llu got %llu",
415 logical1, io_stripe.physical);
416 ret = -EINVAL;
417 goto out;
418 }
419
420 if (len != SZ_1M) {
421 test_err("invalid stripe length, expected %llu got %llu",
422 (u64)SZ_1M, len);
423 ret = -EINVAL;
424 goto out;
425 }
426
427 ret = btrfs_delete_raid_extent(trans, hole_start, hole_len);
428 if (ret) {
429 test_err("deleting RAID extent [%llu, %llu] failed",
430 hole_start, hole_start + hole_len);
431 goto out;
432 }
433
434 ret = btrfs_get_raid_extent_offset(fs_info, logical1, &len1, map_type,
435 0, &io_stripe);
436 if (ret) {
437 test_err("lookup of RAID extent [%llu, %llu] failed",
438 logical1, logical1 + len1);
439 goto out;
440 }
441
442 if (io_stripe.physical != logical1) {
443 test_err("invalid physical address, expected %llu, got %llu",
444 logical1, io_stripe.physical);
445 ret = -EINVAL;
446 goto out;
447 }
448
449 if (len1 != SZ_32K) {
450 test_err("invalid stripe length, expected %llu, got %llu",
451 (u64)SZ_32K, len1);
452 ret = -EINVAL;
453 goto out;
454 }
455
456 ret = btrfs_get_raid_extent_offset(fs_info, logical2, &len2, map_type,
457 0, &io_stripe);
458 if (ret) {
459 test_err("lookup of RAID extent [%llu, %llu] failed", logical2,
460 logical2 + len2);
461 goto out;
462 }
463
464 if (io_stripe.physical != logical2) {
465 test_err("invalid physical address, expected %llu, got %llu",
466 logical2, io_stripe.physical);
467 ret = -EINVAL;
468 goto out;
469 }
470
471 if (len2 != len - len1 - hole_len) {
472 test_err("invalid length, expected %llu, got %llu",
473 len - len1 - hole_len, len2);
474 ret = -EINVAL;
475 goto out;
476 }
477
478 /* Check for the absence of the hole. */
479 ret = btrfs_get_raid_extent_offset(fs_info, hole_start, &hole_len,
480 map_type, 0, &io_stripe);
481 if (ret != -ENODATA) {
482 ret = -EINVAL;
483 test_err("lookup of RAID extent [%llu, %llu] succeeded, should fail",
484 hole_start, hole_start + SZ_64K);
485 goto out;
486 }
487
488 ret = btrfs_delete_raid_extent(trans, logical1, len1);
489 if (ret)
490 goto out;
491
492 ret = btrfs_delete_raid_extent(trans, logical2, len2);
493 out:
494 btrfs_put_bioc(bioc);
495 return ret;
496 }
497
498 /*
499 * Test a 1M RST write that spans two adjacent RST items on disk and then
500 * delete a portion starting in the first item and spanning into the second
501 * item. This is similar to test_front_delete(), but spanning multiple items.
502 */
test_front_delete_prev_item(struct btrfs_trans_handle * trans)503 static int test_front_delete_prev_item(struct btrfs_trans_handle *trans)
504 {
505 struct btrfs_fs_info *fs_info = trans->fs_info;
506 struct btrfs_io_context *bioc;
507 struct btrfs_io_stripe io_stripe = { 0 };
508 u64 map_type = RST_TEST_RAID1_TYPE;
509 u64 logical1 = SZ_1M;
510 u64 logical2 = SZ_2M;
511 u64 len = SZ_1M;
512 int ret;
513
514 bioc = alloc_btrfs_io_context(fs_info, logical1, RST_TEST_NUM_DEVICES);
515 if (!bioc) {
516 test_std_err(TEST_ALLOC_IO_CONTEXT);
517 ret = -ENOMEM;
518 goto out;
519 }
520
521 io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
522 bioc->map_type = map_type;
523 bioc->size = len;
524
525 /* Insert RAID extent 1. */
526 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
527 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
528
529 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
530 if (!stripe->dev) {
531 test_err("cannot find device with devid %d", i);
532 ret = -EINVAL;
533 goto out;
534 }
535
536 stripe->physical = logical1 + i * SZ_1G;
537 }
538
539 ret = btrfs_insert_one_raid_extent(trans, bioc);
540 if (ret) {
541 test_err("inserting RAID extent failed: %d", ret);
542 goto out;
543 }
544
545 bioc->logical = logical2;
546 /* Insert RAID extent 2, directly adjacent to it. */
547 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
548 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
549
550 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
551 if (!stripe->dev) {
552 test_err("cannot find device with devid %d", i);
553 ret = -EINVAL;
554 goto out;
555 }
556
557 stripe->physical = logical2 + i * SZ_1G;
558 }
559
560 ret = btrfs_insert_one_raid_extent(trans, bioc);
561 if (ret) {
562 test_err("inserting RAID extent failed: %d", ret);
563 goto out;
564 }
565
566 ret = btrfs_delete_raid_extent(trans, logical1 + SZ_512K, SZ_1M);
567 if (ret) {
568 test_err("deleting RAID extent [%llu, %llu] failed",
569 logical1 + SZ_512K, (u64)SZ_1M);
570 goto out;
571 }
572
573 /* Verify item 1 is truncated to 512K. */
574 ret = btrfs_get_raid_extent_offset(fs_info, logical1, &len, map_type, 0,
575 &io_stripe);
576 if (ret) {
577 test_err("lookup of RAID extent [%llu, %llu] failed", logical1,
578 logical1 + len);
579 goto out;
580 }
581
582 if (io_stripe.physical != logical1) {
583 test_err("invalid physical address, expected %llu got %llu",
584 logical1, io_stripe.physical);
585 ret = -EINVAL;
586 goto out;
587 }
588
589 if (len != SZ_512K) {
590 test_err("invalid stripe length, expected %llu got %llu",
591 (u64)SZ_512K, len);
592 ret = -EINVAL;
593 goto out;
594 }
595
596 /* Verify item 2's start is moved by 512K. */
597 ret = btrfs_get_raid_extent_offset(fs_info, logical2 + SZ_512K, &len,
598 map_type, 0, &io_stripe);
599 if (ret) {
600 test_err("lookup of RAID extent [%llu, %llu] failed",
601 logical2 + SZ_512K, logical2 + len);
602 goto out;
603 }
604
605 if (io_stripe.physical != logical2 + SZ_512K) {
606 test_err("invalid physical address, expected %llu got %llu",
607 logical2 + SZ_512K, io_stripe.physical);
608 ret = -EINVAL;
609 goto out;
610 }
611
612 if (len != SZ_512K) {
613 test_err("invalid stripe length, expected %llu got %llu",
614 (u64)SZ_512K, len);
615 ret = -EINVAL;
616 goto out;
617 }
618
619 /* Verify there's a hole at [1M+512K, 2M+512K] . */
620 len = SZ_1M;
621 ret = btrfs_get_raid_extent_offset(fs_info, logical1 + SZ_512K, &len,
622 map_type, 0, &io_stripe);
623 if (ret != -ENODATA) {
624 test_err("lookup of RAID [%llu, %llu] succeeded, should fail",
625 logical1 + SZ_512K, logical1 + SZ_512K + len);
626 goto out;
627 }
628
629 /* Clean up after us. */
630 ret = btrfs_delete_raid_extent(trans, logical1, SZ_512K);
631 if (ret)
632 goto out;
633
634 ret = btrfs_delete_raid_extent(trans, logical2 + SZ_512K, SZ_512K);
635
636 out:
637 btrfs_put_bioc(bioc);
638 return ret;
639 }
640
641 /*
642 * Test a 64K RST write on a 2 disk RAID1 at a logical address of 1M and then
643 * delete the 1st 32K, making the new start address 1M+32K.
644 */
test_front_delete(struct btrfs_trans_handle * trans)645 static int test_front_delete(struct btrfs_trans_handle *trans)
646 {
647 struct btrfs_fs_info *fs_info = trans->fs_info;
648 struct btrfs_io_context *bioc;
649 struct btrfs_io_stripe io_stripe = { 0 };
650 u64 map_type = RST_TEST_RAID1_TYPE;
651 u64 logical = SZ_1M;
652 u64 len = SZ_64K;
653 int ret;
654
655 bioc = alloc_btrfs_io_context(fs_info, logical, RST_TEST_NUM_DEVICES);
656 if (!bioc) {
657 test_std_err(TEST_ALLOC_IO_CONTEXT);
658 ret = -ENOMEM;
659 goto out;
660 }
661
662 io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
663 bioc->map_type = map_type;
664 bioc->size = len;
665
666 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
667 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
668
669 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
670 if (!stripe->dev) {
671 test_err("cannot find device with devid %d", i);
672 ret = -EINVAL;
673 goto out;
674 }
675
676 stripe->physical = logical + i * SZ_1G;
677 }
678
679 ret = btrfs_insert_one_raid_extent(trans, bioc);
680 if (ret) {
681 test_err("inserting RAID extent failed: %d", ret);
682 goto out;
683 }
684
685 ret = btrfs_get_raid_extent_offset(fs_info, logical, &len, map_type, 0, &io_stripe);
686 if (ret) {
687 test_err("lookup of RAID extent [%llu, %llu] failed", logical,
688 logical + len);
689 goto out;
690 }
691
692 if (io_stripe.physical != logical) {
693 test_err("invalid physical address, expected %llu got %llu",
694 logical, io_stripe.physical);
695 ret = -EINVAL;
696 goto out;
697 }
698
699 if (len != SZ_64K) {
700 test_err("invalid stripe length, expected %llu got %llu",
701 (u64)SZ_64K, len);
702 ret = -EINVAL;
703 goto out;
704 }
705
706 ret = btrfs_delete_raid_extent(trans, logical, SZ_16K);
707 if (ret) {
708 test_err("deleting RAID extent [%llu, %llu] failed", logical,
709 logical + SZ_16K);
710 goto out;
711 }
712
713 len -= SZ_16K;
714 ret = btrfs_get_raid_extent_offset(fs_info, logical + SZ_16K, &len,
715 map_type, 0, &io_stripe);
716 if (ret) {
717 test_err("lookup of RAID extent [%llu, %llu] failed",
718 logical + SZ_16K, logical + SZ_64K);
719 goto out;
720 }
721
722 if (io_stripe.physical != logical + SZ_16K) {
723 test_err("invalid physical address, expected %llu, got %llu",
724 logical + SZ_16K, io_stripe.physical);
725 ret = -EINVAL;
726 goto out;
727 }
728
729 if (len != SZ_48K) {
730 test_err("invalid stripe length, expected %llu, got %llu",
731 (u64)SZ_48K, len);
732 ret = -EINVAL;
733 goto out;
734 }
735
736 ret = btrfs_get_raid_extent_offset(fs_info, logical, &len, map_type, 0, &io_stripe);
737 if (ret != -ENODATA) {
738 ret = -EINVAL;
739 test_err("lookup of RAID extent [%llu, %llu] succeeded, should fail",
740 logical, logical + SZ_16K);
741 goto out;
742 }
743
744 ret = btrfs_delete_raid_extent(trans, logical + SZ_16K, SZ_48K);
745 out:
746 btrfs_put_bioc(bioc);
747 return ret;
748 }
749
750 /*
751 * Test a 64K RST write on a 2 disk RAID1 at a logical address of 1M and then
752 * truncate the stripe extent down to 32K.
753 */
test_tail_delete(struct btrfs_trans_handle * trans)754 static int test_tail_delete(struct btrfs_trans_handle *trans)
755 {
756 struct btrfs_fs_info *fs_info = trans->fs_info;
757 struct btrfs_io_context *bioc;
758 struct btrfs_io_stripe io_stripe = { 0 };
759 u64 map_type = RST_TEST_RAID1_TYPE;
760 u64 logical = SZ_1M;
761 u64 len = SZ_64K;
762 int ret;
763
764 bioc = alloc_btrfs_io_context(fs_info, logical, RST_TEST_NUM_DEVICES);
765 if (!bioc) {
766 test_std_err(TEST_ALLOC_IO_CONTEXT);
767 ret = -ENOMEM;
768 goto out;
769 }
770
771 io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
772 bioc->map_type = map_type;
773 bioc->size = len;
774
775 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
776 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
777
778 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
779 if (!stripe->dev) {
780 test_err("cannot find device with devid %d", i);
781 ret = -EINVAL;
782 goto out;
783 }
784
785 stripe->physical = logical + i * SZ_1G;
786 }
787
788 ret = btrfs_insert_one_raid_extent(trans, bioc);
789 if (ret) {
790 test_err("inserting RAID extent failed: %d", ret);
791 goto out;
792 }
793
794 io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
795 if (!io_stripe.dev) {
796 ret = -EINVAL;
797 goto out;
798 }
799
800 ret = btrfs_get_raid_extent_offset(fs_info, logical, &len, map_type, 0, &io_stripe);
801 if (ret) {
802 test_err("lookup of RAID extent [%llu, %llu] failed", logical,
803 logical + len);
804 goto out;
805 }
806
807 if (io_stripe.physical != logical) {
808 test_err("invalid physical address, expected %llu got %llu",
809 logical, io_stripe.physical);
810 ret = -EINVAL;
811 goto out;
812 }
813
814 if (len != SZ_64K) {
815 test_err("invalid stripe length, expected %llu got %llu",
816 (u64)SZ_64K, len);
817 ret = -EINVAL;
818 goto out;
819 }
820
821 ret = btrfs_delete_raid_extent(trans, logical + SZ_48K, SZ_16K);
822 if (ret) {
823 test_err("deleting RAID extent [%llu, %llu] failed",
824 logical + SZ_48K, logical + SZ_64K);
825 goto out;
826 }
827
828 len = SZ_48K;
829 ret = btrfs_get_raid_extent_offset(fs_info, logical, &len, map_type, 0, &io_stripe);
830 if (ret) {
831 test_err("lookup of RAID extent [%llu, %llu] failed", logical,
832 logical + len);
833 goto out;
834 }
835
836 if (io_stripe.physical != logical) {
837 test_err("invalid physical address, expected %llu, got %llu",
838 logical, io_stripe.physical);
839 ret = -EINVAL;
840 goto out;
841 }
842
843 if (len != SZ_48K) {
844 test_err("invalid stripe length, expected %llu, got %llu",
845 (u64)SZ_48K, len);
846 ret = -EINVAL;
847 goto out;
848 }
849
850 len = SZ_16K;
851 ret = btrfs_get_raid_extent_offset(fs_info, logical + SZ_48K, &len,
852 map_type, 0, &io_stripe);
853 if (ret != -ENODATA) {
854 test_err("lookup of RAID extent [%llu, %llu] succeeded should fail",
855 logical + SZ_48K, logical + SZ_64K);
856 ret = -EINVAL;
857 goto out;
858 }
859
860 ret = btrfs_delete_raid_extent(trans, logical, len);
861 if (ret)
862 test_err("deleting RAID extent [%llu, %llu] failed", logical,
863 logical + len);
864
865 out:
866 btrfs_put_bioc(bioc);
867 return ret;
868 }
869
870 /*
871 * Test a 64K RST write on a 2 disk RAID1 at a logical address of 1M and then
872 * overwrite the whole range giving it new physical address at an offset of 1G.
873 * The intent of this test is to exercise the 'update_raid_extent_item()'
874 * function called be btrfs_insert_one_raid_extent().
875 */
test_create_update_delete(struct btrfs_trans_handle * trans)876 static int test_create_update_delete(struct btrfs_trans_handle *trans)
877 {
878 struct btrfs_fs_info *fs_info = trans->fs_info;
879 struct btrfs_io_context *bioc;
880 struct btrfs_io_stripe io_stripe = { 0 };
881 u64 map_type = RST_TEST_RAID1_TYPE;
882 u64 logical = SZ_1M;
883 u64 len = SZ_64K;
884 int ret;
885
886 bioc = alloc_btrfs_io_context(fs_info, logical, RST_TEST_NUM_DEVICES);
887 if (!bioc) {
888 test_std_err(TEST_ALLOC_IO_CONTEXT);
889 ret = -ENOMEM;
890 goto out;
891 }
892
893 io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
894 bioc->map_type = map_type;
895 bioc->size = len;
896
897 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
898 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
899
900 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
901 if (!stripe->dev) {
902 test_err("cannot find device with devid %d", i);
903 ret = -EINVAL;
904 goto out;
905 }
906
907 stripe->physical = logical + i * SZ_1G;
908 }
909
910 ret = btrfs_insert_one_raid_extent(trans, bioc);
911 if (ret) {
912 test_err("inserting RAID extent failed: %d", ret);
913 goto out;
914 }
915
916 io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
917 if (!io_stripe.dev) {
918 ret = -EINVAL;
919 goto out;
920 }
921
922 ret = btrfs_get_raid_extent_offset(fs_info, logical, &len, map_type, 0, &io_stripe);
923 if (ret) {
924 test_err("lookup of RAID extent [%llu, %llu] failed", logical,
925 logical + len);
926 goto out;
927 }
928
929 if (io_stripe.physical != logical) {
930 test_err("invalid physical address, expected %llu got %llu",
931 logical, io_stripe.physical);
932 ret = -EINVAL;
933 goto out;
934 }
935
936 if (len != SZ_64K) {
937 test_err("invalid stripe length, expected %llu got %llu",
938 (u64)SZ_64K, len);
939 ret = -EINVAL;
940 goto out;
941 }
942
943 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
944 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
945
946 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
947 if (!stripe->dev) {
948 test_err("cannot find device with devid %d", i);
949 ret = -EINVAL;
950 goto out;
951 }
952
953 stripe->physical = SZ_1G + logical + i * SZ_1G;
954 }
955
956 ret = btrfs_insert_one_raid_extent(trans, bioc);
957 if (ret) {
958 test_err("updating RAID extent failed: %d", ret);
959 goto out;
960 }
961
962 ret = btrfs_get_raid_extent_offset(fs_info, logical, &len, map_type, 0, &io_stripe);
963 if (ret) {
964 test_err("lookup of RAID extent [%llu, %llu] failed", logical,
965 logical + len);
966 goto out;
967 }
968
969 if (io_stripe.physical != logical + SZ_1G) {
970 test_err("invalid physical address, expected %llu, got %llu",
971 logical + SZ_1G, io_stripe.physical);
972 ret = -EINVAL;
973 goto out;
974 }
975
976 if (len != SZ_64K) {
977 test_err("invalid stripe length, expected %llu, got %llu",
978 (u64)SZ_64K, len);
979 ret = -EINVAL;
980 goto out;
981 }
982
983 ret = btrfs_delete_raid_extent(trans, logical, len);
984 if (ret)
985 test_err("deleting RAID extent [%llu, %llu] failed", logical,
986 logical + len);
987
988 out:
989 btrfs_put_bioc(bioc);
990 return ret;
991 }
992
993 /*
994 * Test a simple 64K RST write on a 2 disk RAID1 at a logical address of 1M.
995 * The "physical" copy on device 0 is at 1M, on device 1 it is at 1G+1M.
996 */
test_simple_create_delete(struct btrfs_trans_handle * trans)997 static int test_simple_create_delete(struct btrfs_trans_handle *trans)
998 {
999 struct btrfs_fs_info *fs_info = trans->fs_info;
1000 struct btrfs_io_context *bioc;
1001 struct btrfs_io_stripe io_stripe = { 0 };
1002 u64 map_type = RST_TEST_RAID1_TYPE;
1003 u64 logical = SZ_1M;
1004 u64 len = SZ_64K;
1005 int ret;
1006
1007 bioc = alloc_btrfs_io_context(fs_info, logical, RST_TEST_NUM_DEVICES);
1008 if (!bioc) {
1009 test_std_err(TEST_ALLOC_IO_CONTEXT);
1010 ret = -ENOMEM;
1011 goto out;
1012 }
1013
1014 bioc->map_type = map_type;
1015 bioc->size = SZ_64K;
1016
1017 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
1018 struct btrfs_io_stripe *stripe = &bioc->stripes[i];
1019
1020 stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
1021 if (!stripe->dev) {
1022 test_err("cannot find device with devid %d", i);
1023 ret = -EINVAL;
1024 goto out;
1025 }
1026
1027 stripe->physical = logical + i * SZ_1G;
1028 }
1029
1030 ret = btrfs_insert_one_raid_extent(trans, bioc);
1031 if (ret) {
1032 test_err("inserting RAID extent failed: %d", ret);
1033 goto out;
1034 }
1035
1036 io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
1037 if (!io_stripe.dev) {
1038 ret = -EINVAL;
1039 goto out;
1040 }
1041
1042 ret = btrfs_get_raid_extent_offset(fs_info, logical, &len, map_type, 0, &io_stripe);
1043 if (ret) {
1044 test_err("lookup of RAID extent [%llu, %llu] failed", logical,
1045 logical + len);
1046 goto out;
1047 }
1048
1049 if (io_stripe.physical != logical) {
1050 test_err("invalid physical address, expected %llu got %llu",
1051 logical, io_stripe.physical);
1052 ret = -EINVAL;
1053 goto out;
1054 }
1055
1056 if (len != SZ_64K) {
1057 test_err("invalid stripe length, expected %llu got %llu",
1058 (u64)SZ_64K, len);
1059 ret = -EINVAL;
1060 goto out;
1061 }
1062
1063 ret = btrfs_delete_raid_extent(trans, logical, len);
1064 if (ret)
1065 test_err("deleting RAID extent [%llu, %llu] failed", logical,
1066 logical + len);
1067
1068 out:
1069 btrfs_put_bioc(bioc);
1070 return ret;
1071 }
1072
1073 static const test_func_t tests[] = {
1074 test_simple_create_delete,
1075 test_create_update_delete,
1076 test_tail_delete,
1077 test_front_delete,
1078 test_front_delete_prev_item,
1079 test_punch_hole,
1080 test_punch_hole_3extents,
1081 test_delete_two_extents,
1082 };
1083
run_test(test_func_t test,u32 sectorsize,u32 nodesize)1084 static int run_test(test_func_t test, u32 sectorsize, u32 nodesize)
1085 {
1086 struct btrfs_trans_handle trans;
1087 struct btrfs_fs_info *fs_info;
1088 struct btrfs_root *root = NULL;
1089 int ret;
1090
1091 fs_info = btrfs_alloc_dummy_fs_info(sectorsize, nodesize);
1092 if (!fs_info) {
1093 test_std_err(TEST_ALLOC_FS_INFO);
1094 ret = -ENOMEM;
1095 goto out;
1096 }
1097
1098 root = btrfs_alloc_dummy_root(fs_info);
1099 if (IS_ERR(root)) {
1100 test_std_err(TEST_ALLOC_ROOT);
1101 ret = PTR_ERR(root);
1102 goto out;
1103 }
1104 btrfs_set_super_incompat_flags(root->fs_info->super_copy,
1105 BTRFS_FEATURE_INCOMPAT_RAID_STRIPE_TREE);
1106 root->root_key.objectid = BTRFS_RAID_STRIPE_TREE_OBJECTID;
1107 root->root_key.type = BTRFS_ROOT_ITEM_KEY;
1108 root->root_key.offset = 0;
1109 fs_info->stripe_root = root;
1110 root->fs_info->tree_root = root;
1111
1112 root->node = alloc_test_extent_buffer(root->fs_info, nodesize);
1113 if (IS_ERR(root->node)) {
1114 test_std_err(TEST_ALLOC_EXTENT_BUFFER);
1115 ret = PTR_ERR(root->node);
1116 goto out;
1117 }
1118 btrfs_set_header_level(root->node, 0);
1119 btrfs_set_header_nritems(root->node, 0);
1120 root->alloc_bytenr += 2 * nodesize;
1121
1122 for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
1123 struct btrfs_device *dev;
1124
1125 dev = btrfs_alloc_dummy_device(fs_info);
1126 if (IS_ERR(dev)) {
1127 test_err("cannot allocate device");
1128 ret = PTR_ERR(dev);
1129 goto out;
1130 }
1131 dev->devid = i;
1132 }
1133
1134 btrfs_init_dummy_trans(&trans, root->fs_info);
1135 ret = test(&trans);
1136 if (ret)
1137 goto out;
1138
1139 out:
1140 btrfs_free_dummy_root(root);
1141 btrfs_free_dummy_fs_info(fs_info);
1142
1143 return ret;
1144 }
1145
btrfs_test_raid_stripe_tree(u32 sectorsize,u32 nodesize)1146 int btrfs_test_raid_stripe_tree(u32 sectorsize, u32 nodesize)
1147 {
1148 int ret = 0;
1149
1150 test_msg("running raid-stripe-tree tests");
1151 for (int i = 0; i < ARRAY_SIZE(tests); i++) {
1152 ret = run_test(tests[i], sectorsize, nodesize);
1153 if (ret) {
1154 test_err("test-case %ps failed with %d\n", tests[i], ret);
1155 goto out;
1156 }
1157 }
1158
1159 out:
1160 return ret;
1161 }
1162