mirror of
https://github.com/torvalds/linux
synced 2024-09-06 18:01:05 +00:00
btrfs: Add self-tests for btrfs_rmap_block
Add RAID1 and single testcases to verify that data stripes are excluded from super block locations and that the address mapping is valid. Signed-off-by: Nikolay Borisov <nborisov@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> [ update changelog ] Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
b3ad2c17fd
commit
bf2e2eb060
|
@ -6,6 +6,9 @@
|
|||
#include <linux/types.h>
|
||||
#include "btrfs-tests.h"
|
||||
#include "../ctree.h"
|
||||
#include "../volumes.h"
|
||||
#include "../disk-io.h"
|
||||
#include "../block-group.h"
|
||||
|
||||
static void free_extent_map_tree(struct extent_map_tree *em_tree)
|
||||
{
|
||||
|
@ -437,11 +440,153 @@ static int test_case_4(struct btrfs_fs_info *fs_info,
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct rmap_test_vector {
|
||||
u64 raid_type;
|
||||
u64 physical_start;
|
||||
u64 data_stripe_size;
|
||||
u64 num_data_stripes;
|
||||
u64 num_stripes;
|
||||
/* Assume we won't have more than 5 physical stripes */
|
||||
u64 data_stripe_phys_start[5];
|
||||
bool expected_mapped_addr;
|
||||
/* Physical to logical addresses */
|
||||
u64 mapped_logical[5];
|
||||
};
|
||||
|
||||
static int test_rmap_block(struct btrfs_fs_info *fs_info,
|
||||
struct rmap_test_vector *test)
|
||||
{
|
||||
struct extent_map *em;
|
||||
struct map_lookup *map = NULL;
|
||||
u64 *logical = NULL;
|
||||
int i, out_ndaddrs, out_stripe_len;
|
||||
int ret;
|
||||
|
||||
em = alloc_extent_map();
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
map = kmalloc(map_lookup_size(test->num_stripes), GFP_KERNEL);
|
||||
if (!map) {
|
||||
kfree(em);
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags);
|
||||
/* Start at 4GiB logical address */
|
||||
em->start = SZ_4G;
|
||||
em->len = test->data_stripe_size * test->num_data_stripes;
|
||||
em->block_len = em->len;
|
||||
em->orig_block_len = test->data_stripe_size;
|
||||
em->map_lookup = map;
|
||||
|
||||
map->num_stripes = test->num_stripes;
|
||||
map->stripe_len = BTRFS_STRIPE_LEN;
|
||||
map->type = test->raid_type;
|
||||
|
||||
for (i = 0; i < map->num_stripes; i++) {
|
||||
struct btrfs_device *dev = btrfs_alloc_dummy_device(fs_info);
|
||||
|
||||
if (IS_ERR(dev)) {
|
||||
test_err("cannot allocate device");
|
||||
ret = PTR_ERR(dev);
|
||||
goto out;
|
||||
}
|
||||
map->stripes[i].dev = dev;
|
||||
map->stripes[i].physical = test->data_stripe_phys_start[i];
|
||||
}
|
||||
|
||||
write_lock(&fs_info->mapping_tree.lock);
|
||||
ret = add_extent_mapping(&fs_info->mapping_tree, em, 0);
|
||||
write_unlock(&fs_info->mapping_tree.lock);
|
||||
if (ret) {
|
||||
test_err("error adding block group mapping to mapping tree");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = btrfs_rmap_block(fs_info, em->start, btrfs_sb_offset(1),
|
||||
&logical, &out_ndaddrs, &out_stripe_len);
|
||||
if (ret || (out_ndaddrs == 0 && test->expected_mapped_addr)) {
|
||||
test_err("didn't rmap anything but expected %d",
|
||||
test->expected_mapped_addr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (out_stripe_len != BTRFS_STRIPE_LEN) {
|
||||
test_err("calculated stripe length doesn't match");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (out_ndaddrs != test->expected_mapped_addr) {
|
||||
for (i = 0; i < out_ndaddrs; i++)
|
||||
test_msg("mapped %llu", logical[i]);
|
||||
test_err("unexpected number of mapped addresses: %d", out_ndaddrs);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < out_ndaddrs; i++) {
|
||||
if (logical[i] != test->mapped_logical[i]) {
|
||||
test_err("unexpected logical address mapped");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
write_lock(&fs_info->mapping_tree.lock);
|
||||
remove_extent_mapping(&fs_info->mapping_tree, em);
|
||||
write_unlock(&fs_info->mapping_tree.lock);
|
||||
/* For us */
|
||||
free_extent_map(em);
|
||||
out_free:
|
||||
/* For the tree */
|
||||
free_extent_map(em);
|
||||
kfree(logical);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_test_extent_map(void)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = NULL;
|
||||
struct extent_map_tree *em_tree;
|
||||
int ret = 0;
|
||||
int ret = 0, i;
|
||||
struct rmap_test_vector rmap_tests[] = {
|
||||
{
|
||||
/*
|
||||
* Test a chunk with 2 data stripes one of which
|
||||
* interesects the physical address of the super block
|
||||
* is correctly recognised.
|
||||
*/
|
||||
.raid_type = BTRFS_BLOCK_GROUP_RAID1,
|
||||
.physical_start = SZ_64M - SZ_4M,
|
||||
.data_stripe_size = SZ_256M,
|
||||
.num_data_stripes = 2,
|
||||
.num_stripes = 2,
|
||||
.data_stripe_phys_start =
|
||||
{SZ_64M - SZ_4M, SZ_64M - SZ_4M + SZ_256M},
|
||||
.expected_mapped_addr = true,
|
||||
.mapped_logical= {SZ_4G + SZ_4M}
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that out-of-range physical addresses are
|
||||
* ignored
|
||||
*/
|
||||
|
||||
/* SINGLE chunk type */
|
||||
.raid_type = 0,
|
||||
.physical_start = SZ_4G,
|
||||
.data_stripe_size = SZ_256M,
|
||||
.num_data_stripes = 1,
|
||||
.num_stripes = 1,
|
||||
.data_stripe_phys_start = {SZ_256M},
|
||||
.expected_mapped_addr = false,
|
||||
.mapped_logical = {0}
|
||||
}
|
||||
};
|
||||
|
||||
test_msg("running extent_map tests");
|
||||
|
||||
|
@ -474,6 +619,13 @@ int btrfs_test_extent_map(void)
|
|||
goto out;
|
||||
ret = test_case_4(fs_info, em_tree);
|
||||
|
||||
test_msg("running rmap tests");
|
||||
for (i = 0; i < ARRAY_SIZE(rmap_tests); i++) {
|
||||
ret = test_rmap_block(fs_info, &rmap_tests[i]);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(em_tree);
|
||||
btrfs_free_dummy_fs_info(fs_info);
|
||||
|
|
Loading…
Reference in a new issue