@@ -5961,6 +5961,8 @@ struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,
btrfs_set_header_nritems(eb, 0);
set_bit(EXTENT_BUFFER_UNMAPPED, &eb->bflags);
memzero_extent_buffer(eb, 0, sizeof(struct btrfs_header));
+ if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+ btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_V2);
return eb;
err:
@@ -113,7 +113,8 @@ static void btrfs_free_dummy_device(struct btrfs_device *dev)
kfree(dev);
}
-struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize)
+struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize,
+ u64 incompat_flags)
{
struct btrfs_fs_info *fs_info = kzalloc(sizeof(struct btrfs_fs_info),
GFP_KERNEL);
@@ -142,6 +143,7 @@ struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize)
fs_info->sectorsize = sectorsize;
fs_info->sectorsize_bits = ilog2(sectorsize);
set_bit(BTRFS_FS_STATE_DUMMY_FS_INFO, &fs_info->fs_state);
+ btrfs_set_super_incompat_flags(fs_info->super_copy, incompat_flags);
test_mnt->mnt_sb->s_fs_info = fs_info;
@@ -256,42 +258,61 @@ void btrfs_init_dummy_trans(struct btrfs_trans_handle *trans,
trans->fs_info = fs_info;
}
+static int run_sectorsize_tests(u32 sectorsize, u32 nodesize,
+ u64 incompat_flags)
+{
+ int ret;
+
+ pr_info("BTRFS: selftest: sectorsize: %u nodesize: %u incompat_flags: %llu\n",
+ sectorsize, nodesize, incompat_flags);
+ ret = btrfs_test_free_space_cache(sectorsize, nodesize, incompat_flags);
+ if (ret)
+ return ret;
+ ret = btrfs_test_extent_buffer_operations(sectorsize, nodesize,
+ incompat_flags);
+ if (ret)
+ return ret;
+ ret = btrfs_test_extent_io(sectorsize, nodesize, incompat_flags);
+ if (ret)
+ return ret;
+ ret = btrfs_test_inodes(sectorsize, nodesize, incompat_flags);
+ if (ret)
+ return ret;
+ ret = btrfs_test_qgroups(sectorsize, nodesize, incompat_flags);
+ if (ret)
+ return ret;
+ return btrfs_test_free_space_tree(sectorsize, nodesize, incompat_flags);
+}
+
int btrfs_run_sanity_tests(void)
{
- int ret, i;
+ int ret, i, c;
u32 sectorsize, nodesize;
u32 test_sectorsize[] = {
PAGE_SIZE,
};
+ u64 test_incompat_flags[] = {
+ 0,
+ BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2,
+ };
+ u64 flags;
+
ret = btrfs_init_test_fs();
if (ret)
return ret;
- for (i = 0; i < ARRAY_SIZE(test_sectorsize); i++) {
- sectorsize = test_sectorsize[i];
- for (nodesize = sectorsize;
- nodesize <= BTRFS_MAX_METADATA_BLOCKSIZE;
- nodesize <<= 1) {
- pr_info("BTRFS: selftest: sectorsize: %u nodesize: %u\n",
- sectorsize, nodesize);
- ret = btrfs_test_free_space_cache(sectorsize, nodesize);
- if (ret)
- goto out;
- ret = btrfs_test_extent_buffer_operations(sectorsize,
- nodesize);
- if (ret)
- goto out;
- ret = btrfs_test_extent_io(sectorsize, nodesize);
- if (ret)
- goto out;
- ret = btrfs_test_inodes(sectorsize, nodesize);
- if (ret)
- goto out;
- ret = btrfs_test_qgroups(sectorsize, nodesize);
- if (ret)
- goto out;
- ret = btrfs_test_free_space_tree(sectorsize, nodesize);
- if (ret)
- goto out;
+
+ for (c = 0; c < ARRAY_SIZE(test_incompat_flags); c++) {
+ flags = test_incompat_flags[c];
+ for (i = 0; i < ARRAY_SIZE(test_sectorsize); i++) {
+ sectorsize = test_sectorsize[i];
+ for (nodesize = sectorsize;
+ nodesize <= BTRFS_MAX_METADATA_BLOCKSIZE;
+ nodesize <<= 1) {
+ ret = run_sectorsize_tests(sectorsize, nodesize,
+ flags);
+ if (ret)
+ goto out;
+ }
}
}
ret = btrfs_test_extent_map();
@@ -30,15 +30,19 @@ extern const char *test_error[];
struct btrfs_root;
struct btrfs_trans_handle;
-int btrfs_test_extent_buffer_operations(u32 sectorsize, u32 nodesize);
-int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize);
-int btrfs_test_extent_io(u32 sectorsize, u32 nodesize);
-int btrfs_test_inodes(u32 sectorsize, u32 nodesize);
-int btrfs_test_qgroups(u32 sectorsize, u32 nodesize);
-int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize);
+int btrfs_test_extent_buffer_operations(u32 sectorsize, u32 nodesize,
+ u64 incompat_flags);
+int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize,
+ u64 incompat_flags);
+int btrfs_test_extent_io(u32 sectorsize, u32 nodesize, u64 incompat_flags);
+int btrfs_test_inodes(u32 sectorsize, u32 nodesize, u64 incompat_flags);
+int btrfs_test_qgroups(u32 sectorsize, u32 nodesize, u64 incompat_flags);
+int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize,
+ u64 incompat_flags);
int btrfs_test_extent_map(void);
struct inode *btrfs_new_test_inode(void);
-struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize);
+struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize,
+ u64 incompat_flags);
void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info);
void btrfs_free_dummy_root(struct btrfs_root *root);
struct btrfs_block_group *
@@ -10,7 +10,8 @@
#include "../disk-io.h"
#include "../transaction.h"
-static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)
+static int test_btrfs_split_item(u32 sectorsize, u32 nodesize,
+ u64 incompat_flags)
{
struct btrfs_fs_info *fs_info;
struct btrfs_path *path = NULL;
@@ -28,7 +29,8 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)
test_msg("running btrfs_split_item tests");
- fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
+ fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize,
+ incompat_flags);
if (!fs_info) {
test_std_err(TEST_ALLOC_FS_INFO);
return -ENOMEM;
@@ -211,7 +213,8 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)
return ret;
}
-static int test_delete_one_dir_name(u32 sectorsize, u32 nodesize)
+static int test_delete_one_dir_name(u32 sectorsize, u32 nodesize,
+ u64 incompat_flags)
{
struct btrfs_fs_info *fs_info;
struct btrfs_path *path = NULL;
@@ -228,7 +231,8 @@ static int test_delete_one_dir_name(u32 sectorsize, u32 nodesize)
test_msg("running btrfs_delete_one_dir_name tests");
- fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
+ fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize,
+ incompat_flags);
if (!fs_info) {
test_std_err(TEST_ALLOC_FS_INFO);
return -ENOMEM;
@@ -372,14 +376,15 @@ static int test_delete_one_dir_name(u32 sectorsize, u32 nodesize)
return ret;
}
-int btrfs_test_extent_buffer_operations(u32 sectorsize, u32 nodesize)
+int btrfs_test_extent_buffer_operations(u32 sectorsize, u32 nodesize,
+ u64 incompat_flags)
{
int ret;
test_msg("running extent buffer operation tests");
- ret = test_btrfs_split_item(sectorsize, nodesize);
+ ret = test_btrfs_split_item(sectorsize, nodesize, incompat_flags);
if (ret)
return ret;
test_msg("running delete dir name etests");
- return test_delete_one_dir_name(sectorsize, nodesize);
+ return test_delete_one_dir_name(sectorsize, nodesize, incompat_flags);
}
@@ -426,7 +426,7 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb,
return 0;
}
-static int test_eb_bitmaps(u32 sectorsize, u32 nodesize)
+static int test_eb_bitmaps(u32 sectorsize, u32 nodesize, u64 incompat_flags)
{
struct btrfs_fs_info *fs_info;
unsigned long *bitmap = NULL;
@@ -435,7 +435,8 @@ static int test_eb_bitmaps(u32 sectorsize, u32 nodesize)
test_msg("running extent buffer bitmap tests");
- fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
+ fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize,
+ incompat_flags);
if (!fs_info) {
test_std_err(TEST_ALLOC_FS_INFO);
return -ENOMEM;
@@ -591,7 +592,7 @@ static int test_find_first_clear_extent_bit(void)
return ret;
}
-int btrfs_test_extent_io(u32 sectorsize, u32 nodesize)
+int btrfs_test_extent_io(u32 sectorsize, u32 nodesize, u64 incompat_flags)
{
int ret;
@@ -605,7 +606,7 @@ int btrfs_test_extent_io(u32 sectorsize, u32 nodesize)
if (ret)
goto out;
- ret = test_eb_bitmaps(sectorsize, nodesize);
+ ret = test_eb_bitmaps(sectorsize, nodesize, incompat_flags);
out:
return ret;
}
@@ -596,7 +596,7 @@ int btrfs_test_extent_map(void)
* Note: the fs_info is not set up completely, we only need
* fs_info::fsid for the tracepoint.
*/
- fs_info = btrfs_alloc_dummy_fs_info(PAGE_SIZE, PAGE_SIZE);
+ fs_info = btrfs_alloc_dummy_fs_info(PAGE_SIZE, PAGE_SIZE, 0);
if (!fs_info) {
test_std_err(TEST_ALLOC_FS_INFO);
return -ENOMEM;
@@ -1002,7 +1002,8 @@ static int test_bytes_index(struct btrfs_block_group *cache, u32 sectorsize)
return 0;
}
-int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)
+int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize,
+ u64 incompat_flags)
{
struct btrfs_fs_info *fs_info;
struct btrfs_block_group *cache;
@@ -1010,7 +1011,8 @@ int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)
int ret = -ENOMEM;
test_msg("running btrfs free space cache tests");
- fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
+ fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize,
+ incompat_flags);
if (!fs_info) {
test_std_err(TEST_ALLOC_FS_INFO);
return -ENOMEM;
@@ -421,7 +421,7 @@ typedef int (*test_func_t)(struct btrfs_trans_handle *,
u32 alignment);
static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
- u32 nodesize, u32 alignment)
+ u32 nodesize, u32 alignment, u64 incompat_flags)
{
struct btrfs_fs_info *fs_info;
struct btrfs_root *root = NULL;
@@ -430,7 +430,8 @@ static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
struct btrfs_path *path = NULL;
int ret;
- fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
+ fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize,
+ incompat_flags);
if (!fs_info) {
test_std_err(TEST_ALLOC_FS_INFO);
ret = -ENOMEM;
@@ -522,12 +523,14 @@ static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
}
static int run_test_both_formats(test_func_t test_func, u32 sectorsize,
- u32 nodesize, u32 alignment)
+ u32 nodesize, u32 alignment,
+ u64 incompat_flags)
{
int test_ret = 0;
int ret;
- ret = run_test(test_func, 0, sectorsize, nodesize, alignment);
+ ret = run_test(test_func, 0, sectorsize, nodesize, alignment,
+ incompat_flags);
if (ret) {
test_err(
"%ps failed with extents, sectorsize=%u, nodesize=%u, alignment=%u",
@@ -535,7 +538,8 @@ static int run_test_both_formats(test_func_t test_func, u32 sectorsize,
test_ret = ret;
}
- ret = run_test(test_func, 1, sectorsize, nodesize, alignment);
+ ret = run_test(test_func, 1, sectorsize, nodesize, alignment,
+ incompat_flags);
if (ret) {
test_err(
"%ps failed with bitmaps, sectorsize=%u, nodesize=%u, alignment=%u",
@@ -546,7 +550,8 @@ static int run_test_both_formats(test_func_t test_func, u32 sectorsize,
return test_ret;
}
-int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize)
+int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize,
+ u64 incompat_flags)
{
test_func_t tests[] = {
test_empty_block_group,
@@ -574,12 +579,12 @@ int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize)
int ret;
ret = run_test_both_formats(tests[i], sectorsize, nodesize,
- sectorsize);
+ sectorsize, incompat_flags);
if (ret)
test_ret = ret;
ret = run_test_both_formats(tests[i], sectorsize, nodesize,
- bitmap_alignment);
+ bitmap_alignment, incompat_flags);
if (ret)
test_ret = ret;
}
@@ -213,7 +213,8 @@ static unsigned long prealloc_only = 0;
static unsigned long compressed_only = 0;
static unsigned long vacancy_only = 0;
-static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
+static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize,
+ u64 incompat_flags)
{
struct btrfs_fs_info *fs_info = NULL;
struct inode *inode = NULL;
@@ -232,7 +233,8 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
return ret;
}
- fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
+ fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize,
+ incompat_flags);
if (!fs_info) {
test_std_err(TEST_ALLOC_FS_INFO);
goto out;
@@ -814,7 +816,7 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
return ret;
}
-static int test_hole_first(u32 sectorsize, u32 nodesize)
+static int test_hole_first(u32 sectorsize, u32 nodesize, u64 incompat_flags)
{
struct btrfs_fs_info *fs_info = NULL;
struct inode *inode = NULL;
@@ -830,7 +832,8 @@ static int test_hole_first(u32 sectorsize, u32 nodesize)
return ret;
}
- fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
+ fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize,
+ incompat_flags);
if (!fs_info) {
test_std_err(TEST_ALLOC_FS_INFO);
goto out;
@@ -912,7 +915,8 @@ static int test_hole_first(u32 sectorsize, u32 nodesize)
return ret;
}
-static int test_extent_accounting(u32 sectorsize, u32 nodesize)
+static int test_extent_accounting(u32 sectorsize, u32 nodesize,
+ u64 incompat_flags)
{
struct btrfs_fs_info *fs_info = NULL;
struct inode *inode = NULL;
@@ -927,7 +931,8 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
return ret;
}
- fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
+ fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize,
+ incompat_flags);
if (!fs_info) {
test_std_err(TEST_ALLOC_FS_INFO);
goto out;
@@ -1099,7 +1104,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
return ret;
}
-int btrfs_test_inodes(u32 sectorsize, u32 nodesize)
+int btrfs_test_inodes(u32 sectorsize, u32 nodesize, u64 incompat_flags)
{
int ret;
@@ -1108,11 +1113,11 @@ int btrfs_test_inodes(u32 sectorsize, u32 nodesize)
set_bit(EXTENT_FLAG_COMPRESSED, &compressed_only);
set_bit(EXTENT_FLAG_PREALLOC, &prealloc_only);
- ret = test_btrfs_get_extent(sectorsize, nodesize);
+ ret = test_btrfs_get_extent(sectorsize, nodesize, incompat_flags);
if (ret)
return ret;
- ret = test_hole_first(sectorsize, nodesize);
+ ret = test_hole_first(sectorsize, nodesize, incompat_flags);
if (ret)
return ret;
- return test_extent_accounting(sectorsize, nodesize);
+ return test_extent_accounting(sectorsize, nodesize, incompat_flags);
}
@@ -434,14 +434,15 @@ static int test_multiple_refs(struct btrfs_root *root,
return 0;
}
-int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)
+int btrfs_test_qgroups(u32 sectorsize, u32 nodesize, u64 incompat_flags)
{
struct btrfs_fs_info *fs_info = NULL;
struct btrfs_root *root;
struct btrfs_root *tmp_root;
int ret = 0;
- fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
+ fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize,
+ incompat_flags);
if (!fs_info) {
test_std_err(TEST_ALLOC_FS_INFO);
return -ENOMEM;
With the btrfs header change I wanted to validate that the math worked out properly. To do this I modified the tests to also test with EXTENT_TREE_V2 set and without. This requires passing the incompat flags throughout the stack which is why this looks so churny. Finally with the flag set on the fs_info we can allocate dummy extent buffers with the HEADER_FLAG_V2 set on them to get the correct math. Signed-off-by: Josef Bacik <josef@toxicpanda.com> with '#' will be ignored, and an empty message aborts the commit. --- fs/btrfs/extent_io.c | 2 + fs/btrfs/tests/btrfs-tests.c | 77 ++++++++++++++++---------- fs/btrfs/tests/btrfs-tests.h | 18 +++--- fs/btrfs/tests/extent-buffer-tests.c | 19 ++++--- fs/btrfs/tests/extent-io-tests.c | 9 +-- fs/btrfs/tests/extent-map-tests.c | 2 +- fs/btrfs/tests/free-space-tests.c | 6 +- fs/btrfs/tests/free-space-tree-tests.c | 21 ++++--- fs/btrfs/tests/inode-tests.c | 25 +++++---- fs/btrfs/tests/qgroup-tests.c | 5 +- 10 files changed, 115 insertions(+), 69 deletions(-)