diff options
| author | Johannes Thumshirn <johannes.thumshirn@wdc.com> | 2025-01-13 20:31:55 +0100 | 
|---|---|---|
| committer | David Sterba <dsterba@suse.com> | 2025-01-14 15:57:55 +0100 | 
| commit | 9d0c23db26cb58c9fc6ee8817e8f9ebeb25776e5 (patch) | |
| tree | 443606db42dc886800ee738fcd62d14bb2faf3e3 /fs | |
| parent | cfda28fb706d53b332d5183d6091224289e96863 (diff) | |
btrfs: selftests: add a selftest for deleting two out of three extents
Add a selftest creating three extents and then deleting two out of the
three extents.
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/btrfs/tests/raid-stripe-tree-tests.c | 144 | 
1 files changed, 144 insertions, 0 deletions
| diff --git a/fs/btrfs/tests/raid-stripe-tree-tests.c b/fs/btrfs/tests/raid-stripe-tree-tests.c index 482e10b0d7ed..a7bc58a5c1e2 100644 --- a/fs/btrfs/tests/raid-stripe-tree-tests.c +++ b/fs/btrfs/tests/raid-stripe-tree-tests.c @@ -213,6 +213,149 @@ out:  	return ret;  } +static int test_delete_two_extents(struct btrfs_trans_handle *trans) +{ +	struct btrfs_fs_info *fs_info = trans->fs_info; +	struct btrfs_io_context *bioc; +	struct btrfs_io_stripe io_stripe = { 0 }; +	u64 map_type = RST_TEST_RAID1_TYPE; +	u64 logical1 = SZ_1M; +	u64 len1 = SZ_1M; +	u64 logical2 = logical1 + len1; +	u64 len2 = SZ_1M; +	u64 logical3 = logical2 + len2; +	u64 len3 = SZ_1M; +	int ret; + +	bioc = alloc_btrfs_io_context(fs_info, logical1, RST_TEST_NUM_DEVICES); +	if (!bioc) { +		test_std_err(TEST_ALLOC_IO_CONTEXT); +		ret = -ENOMEM; +		goto out; +	} + +	io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0); + +	/* Prepare for the test, 1st create 3 x 1M extents. */ +	bioc->map_type = map_type; +	bioc->size = len1; + +	for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) { +		struct btrfs_io_stripe *stripe = &bioc->stripes[i]; + +		stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i); +		if (!stripe->dev) { +			test_err("cannot find device with devid %d", i); +			ret = -EINVAL; +			goto out; +		} + +		stripe->physical = logical1 + i * SZ_1G; +	} + +	ret = btrfs_insert_one_raid_extent(trans, bioc); +	if (ret) { +		test_err("inserting RAID extent failed: %d", ret); +		goto out; +	} + +	bioc->logical = logical2; +	bioc->size = len2; +	for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) { +		struct btrfs_io_stripe *stripe = &bioc->stripes[i]; + +		stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i); +		if (!stripe->dev) { +			test_err("cannot find device with devid %d", i); +			ret = -EINVAL; +			goto out; +		} + +		stripe->physical = logical2 + i * SZ_1G; +	} + +	ret = btrfs_insert_one_raid_extent(trans, bioc); +	if (ret) { +		test_err("inserting RAID extent failed: %d", ret); +		goto out; +	} + +	bioc->logical = logical3; +	bioc->size = len3; +	for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) { +		struct btrfs_io_stripe *stripe = &bioc->stripes[i]; + +		stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i); +		if (!stripe->dev) { +			test_err("cannot find device with devid %d", i); +			ret = -EINVAL; +			goto out; +		} + +		stripe->physical = logical3 + i * SZ_1G; +	} + +	ret = btrfs_insert_one_raid_extent(trans, bioc); +	if (ret) { +		test_err("inserting RAID extent failed: %d", ret); +		goto out; +	} + +	/* +	 * Delete a range starting at logical1 and 2M in length. Extents 1 +	 * and 2 are dropped and extent 3 is kept as is. +	 */ +	ret = btrfs_delete_raid_extent(trans, logical1, len1 + len2); +	if (ret) { +		test_err("deleting RAID extent [%llu, %llu] failed", +			 logical1, logical1 + len1 + len2); +		goto out; +	} + +	ret = btrfs_get_raid_extent_offset(fs_info, logical1, &len1, map_type, +					   0, &io_stripe); +	if (ret != -ENODATA) { +		test_err("lookup of RAID extent [%llu, %llu] succeeded, should fail", +			 logical1, len1); +		goto out; +	} + +	ret = btrfs_get_raid_extent_offset(fs_info, logical2, &len2, map_type, +					   0, &io_stripe); +	if (ret != -ENODATA) { +		test_err("lookup of RAID extent [%llu, %llu] succeeded, should fail", +			 logical2, len2); +		goto out; +	} + +	ret = btrfs_get_raid_extent_offset(fs_info, logical3, &len3, map_type, +					   0, &io_stripe); +	if (ret) { +		test_err("lookup of RAID extent [%llu, %llu] failed", +			 logical3, len3); +		goto out; +	} + +	if (io_stripe.physical != logical3) { +		test_err("invalid physical address, expected %llu, got %llu", +			 logical3, io_stripe.physical); +		ret = -EINVAL; +		goto out; +	} + +	if (len3 != SZ_1M) { +		test_err("invalid stripe length, expected %llu, got %llu", +			 (u64)SZ_1M, len3); +		ret = -EINVAL; +		goto out; +	} + +	ret = btrfs_delete_raid_extent(trans, logical3, len3); +out: +	btrfs_put_bioc(bioc); +	return ret; +} +  /* Test punching a hole into a single RAID stripe-extent. */  static int test_punch_hole(struct btrfs_trans_handle *trans)  { @@ -935,6 +1078,7 @@ static const test_func_t tests[] = {  	test_front_delete_prev_item,  	test_punch_hole,  	test_punch_hole_3extents, +	test_delete_two_extents,  };  static int run_test(test_func_t test, u32 sectorsize, u32 nodesize) | 
