xref: /linux/fs/btrfs/tests/raid-stripe-tree-tests.c (revision e814f3fd16acfb7f9966773953de8f740a1e3202)
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 
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  */
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 
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. */
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  */
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  */
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  */
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  */
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  */
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 
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 
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