File Index
Files and directories
Sign in
FILE

raid-stripe-tree-tests.c

File preview with syntax highlighting.

linux-6.19.14/fs/btrfs/tests/raid-stripe-tree-tests.c C
   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
  19typedef int (*test_func_t)(struct btrfs_trans_handle *trans);
  20
  21static 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 */
  38static 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
 211out:
 212	btrfs_put_bioc(bioc);
 213	return ret;
 214}
 215
 216static 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);
 354out:
 355	btrfs_put_bioc(bioc);
 356	return ret;
 357}
 358
 359/* Test punching a hole into a single RAID stripe-extent. */
 360static 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);
 493out:
 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 */
 503static 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
 636out:
 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 */
 645static 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);
 745out:
 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 */
 754static 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
 865out:
 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 */
 876static 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
 988out:
 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 */
 997static 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
1068out:
1069	btrfs_put_bioc(bioc);
1070	return ret;
1071}
1072
1073static 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
1084static 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
1139out:
1140	btrfs_free_dummy_root(root);
1141	btrfs_free_dummy_fs_info(fs_info);
1142
1143	return ret;
1144}
1145
1146int 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
1159out:
1160	return ret;
1161}
~/ Read-only file preview.