Skip to content

Commit

Permalink
btrfs: Add self-tests for btrfs_rmap_block
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nikolay Borisov authored and David Sterba committed Jan 23, 2020
1 parent b3ad2c1 commit bf2e2eb
Showing 1 changed file with 153 additions and 1 deletion.
154 changes: 153 additions & 1 deletion fs/btrfs/tests/extent-map-tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit bf2e2eb

Please sign in to comment.