Merge tag 'for-5.2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs updates from David Sterba: "This time the majority of changes are cleanups, though there's still a number of changes of user interest. User visible changes: - better read time and write checks to catch errors early and before writing data to disk (to catch potential memory corruption on data that get checksummed) - qgroups + metadata relocation: last speed up patch int the series to address the slowness, there should be no overhead comparing balance with and without qgroups - FIEMAP ioctl does not start a transaction unnecessarily, this can result in a speed up and less blocking due to IO - LOGICAL_INO (v1, v2) does not start transaction unnecessarily, this can speed up the mentioned ioctl and scrub as well - fsync on files with many (but not too many) hardlinks is faster, finer decision if the links should be fsynced individually or completely - send tries harder to find ranges to clone - trim/discard will skip unallocated chunks that haven't been touched since the last mount Fixes: - send flushes delayed allocation before start, otherwise it could miss some changes in case of a very recent rw->ro switch of a subvolume - fix fallocate with qgroups that could lead to space accounting underflow, reported as a warning - trim/discard ioctl honours the requested range - starting send and dedupe on a subvolume at the same time will let only one of them succeed, this is to prevent changes that send could miss due to dedupe; both operations are restartable Core changes: - more tree-checker validations, errors reported by fuzzing tools: - device item - inode item - block group profiles - tracepoints for extent buffer locking - async cow preallocates memory to avoid errors happening too deep in the call chain - metadata reservations for delalloc reworked to better adapt in many-writers/low-space scenarios - improved space flushing logic for intense DIO vs buffered workloads - lots of cleanups - removed unused struct members - redundant argument removal - properties and xattrs - extent buffer locking - selftests - use common file type conversions - many-argument functions reduction" * tag 'for-5.2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: (227 commits) btrfs: Use kvmalloc for allocating compressed path context btrfs: Factor out common extent locking code in submit_compressed_extents btrfs: Set io_tree only once in submit_compressed_extents btrfs: Replace clear_extent_bit with unlock_extent btrfs: Make compress_file_range take only struct async_chunk btrfs: Remove fs_info from struct async_chunk btrfs: Rename async_cow to async_chunk btrfs: Preallocate chunks in cow_file_range_async btrfs: reserve delalloc metadata differently btrfs: track DIO bytes in flight btrfs: merge calls of btrfs_setxattr and btrfs_setxattr_trans in btrfs_set_prop btrfs: delete unused function btrfs_set_prop_trans btrfs: start transaction in xattr_handler_set_prop btrfs: drop local copy of inode i_mode btrfs: drop old_fsflags in btrfs_ioctl_setflags btrfs: modify local copy of btrfs_inode flags btrfs: drop useless inode i_flags copy and restore btrfs: start transaction in btrfs_ioctl_setflags() btrfs: export btrfs_set_prop btrfs: refactor btrfs_set_props to validate externally ...
This commit is contained in:
@@ -17,6 +17,16 @@
|
||||
|
||||
static struct vfsmount *test_mnt = NULL;
|
||||
|
||||
const char *test_error[] = {
|
||||
[TEST_ALLOC_FS_INFO] = "cannot allocate fs_info",
|
||||
[TEST_ALLOC_ROOT] = "cannot allocate root",
|
||||
[TEST_ALLOC_EXTENT_BUFFER] = "cannot extent buffer",
|
||||
[TEST_ALLOC_PATH] = "cannot allocate path",
|
||||
[TEST_ALLOC_INODE] = "cannot allocate inode",
|
||||
[TEST_ALLOC_BLOCK_GROUP] = "cannot allocate block group",
|
||||
[TEST_ALLOC_EXTENT_MAP] = "cannot allocate extent map",
|
||||
};
|
||||
|
||||
static const struct super_operations btrfs_test_super_ops = {
|
||||
.alloc_inode = btrfs_alloc_inode,
|
||||
.destroy_inode = btrfs_test_destroy_inode,
|
||||
@@ -99,7 +109,6 @@ struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize)
|
||||
|
||||
spin_lock_init(&fs_info->buffer_lock);
|
||||
spin_lock_init(&fs_info->qgroup_lock);
|
||||
spin_lock_init(&fs_info->qgroup_op_lock);
|
||||
spin_lock_init(&fs_info->super_lock);
|
||||
spin_lock_init(&fs_info->fs_roots_radix_lock);
|
||||
spin_lock_init(&fs_info->tree_mod_seq_lock);
|
||||
@@ -115,8 +124,10 @@ struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize)
|
||||
INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
|
||||
INIT_RADIX_TREE(&fs_info->buffer_radix, GFP_ATOMIC);
|
||||
INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC);
|
||||
extent_io_tree_init(&fs_info->freed_extents[0], NULL);
|
||||
extent_io_tree_init(&fs_info->freed_extents[1], NULL);
|
||||
extent_io_tree_init(fs_info, &fs_info->freed_extents[0],
|
||||
IO_TREE_FS_INFO_FREED_EXTENTS0, NULL);
|
||||
extent_io_tree_init(fs_info, &fs_info->freed_extents[1],
|
||||
IO_TREE_FS_INFO_FREED_EXTENTS1, NULL);
|
||||
fs_info->pinned_extents = &fs_info->freed_extents[0];
|
||||
set_bit(BTRFS_FS_STATE_DUMMY_FS_INFO, &fs_info->fs_state);
|
||||
|
||||
|
@@ -10,7 +10,22 @@
|
||||
int btrfs_run_sanity_tests(void);
|
||||
|
||||
#define test_msg(fmt, ...) pr_info("BTRFS: selftest: " fmt "\n", ##__VA_ARGS__)
|
||||
#define test_err(fmt, ...) pr_err("BTRFS: selftest: " fmt "\n", ##__VA_ARGS__)
|
||||
#define test_err(fmt, ...) pr_err("BTRFS: selftest: %s:%d " fmt "\n", \
|
||||
__FILE__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
#define test_std_err(index) test_err("%s", test_error[index])
|
||||
|
||||
enum {
|
||||
TEST_ALLOC_FS_INFO,
|
||||
TEST_ALLOC_ROOT,
|
||||
TEST_ALLOC_EXTENT_BUFFER,
|
||||
TEST_ALLOC_PATH,
|
||||
TEST_ALLOC_INODE,
|
||||
TEST_ALLOC_BLOCK_GROUP,
|
||||
TEST_ALLOC_EXTENT_MAP,
|
||||
};
|
||||
|
||||
extern const char *test_error[];
|
||||
|
||||
struct btrfs_root;
|
||||
struct btrfs_trans_handle;
|
||||
|
@@ -30,27 +30,27 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)
|
||||
|
||||
fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
|
||||
if (!fs_info) {
|
||||
test_err("could not allocate fs_info");
|
||||
test_std_err(TEST_ALLOC_FS_INFO);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
root = btrfs_alloc_dummy_root(fs_info);
|
||||
if (IS_ERR(root)) {
|
||||
test_err("could not allocate root");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
ret = PTR_ERR(root);
|
||||
goto out;
|
||||
}
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path) {
|
||||
test_err("could not allocate path");
|
||||
test_std_err(TEST_ALLOC_PATH);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
path->nodes[0] = eb = alloc_dummy_extent_buffer(fs_info, nodesize);
|
||||
if (!eb) {
|
||||
test_err("could not allocate dummy buffer");
|
||||
test_std_err(TEST_ALLOC_EXTENT_BUFFER);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
@@ -73,11 +73,15 @@ static int test_find_delalloc(u32 sectorsize)
|
||||
|
||||
inode = btrfs_new_test_inode();
|
||||
if (!inode) {
|
||||
test_err("failed to allocate test inode");
|
||||
test_std_err(TEST_ALLOC_INODE);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
extent_io_tree_init(&tmp, NULL);
|
||||
/*
|
||||
* Passing NULL as we don't have fs_info but tracepoints are not used
|
||||
* at this point
|
||||
*/
|
||||
extent_io_tree_init(NULL, &tmp, IO_TREE_SELFTEST, NULL);
|
||||
|
||||
/*
|
||||
* First go through and create and mark all of our pages dirty, we pin
|
||||
@@ -374,8 +378,8 @@ static int test_eb_bitmaps(u32 sectorsize, u32 nodesize)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info;
|
||||
unsigned long len;
|
||||
unsigned long *bitmap;
|
||||
struct extent_buffer *eb;
|
||||
unsigned long *bitmap = NULL;
|
||||
struct extent_buffer *eb = NULL;
|
||||
int ret;
|
||||
|
||||
test_msg("running extent buffer bitmap tests");
|
||||
@@ -388,18 +392,23 @@ static int test_eb_bitmaps(u32 sectorsize, u32 nodesize)
|
||||
? sectorsize * 4 : sectorsize;
|
||||
|
||||
fs_info = btrfs_alloc_dummy_fs_info(len, len);
|
||||
if (!fs_info) {
|
||||
test_std_err(TEST_ALLOC_FS_INFO);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
bitmap = kmalloc(len, GFP_KERNEL);
|
||||
if (!bitmap) {
|
||||
test_err("couldn't allocate test bitmap");
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
eb = __alloc_dummy_extent_buffer(fs_info, 0, len);
|
||||
if (!eb) {
|
||||
test_err("couldn't allocate test extent buffer");
|
||||
kfree(bitmap);
|
||||
return -ENOMEM;
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = __test_eb_bitmaps(bitmap, eb, len);
|
||||
@@ -408,17 +417,18 @@ static int test_eb_bitmaps(u32 sectorsize, u32 nodesize)
|
||||
|
||||
/* Do it over again with an extent buffer which isn't page-aligned. */
|
||||
free_extent_buffer(eb);
|
||||
eb = __alloc_dummy_extent_buffer(NULL, nodesize / 2, len);
|
||||
eb = __alloc_dummy_extent_buffer(fs_info, nodesize / 2, len);
|
||||
if (!eb) {
|
||||
test_err("couldn't allocate test extent buffer");
|
||||
kfree(bitmap);
|
||||
return -ENOMEM;
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = __test_eb_bitmaps(bitmap, eb, len);
|
||||
out:
|
||||
free_extent_buffer(eb);
|
||||
kfree(bitmap);
|
||||
btrfs_free_dummy_fs_info(fs_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -434,6 +444,5 @@ int btrfs_test_extent_io(u32 sectorsize, u32 nodesize)
|
||||
|
||||
ret = test_eb_bitmaps(sectorsize, nodesize);
|
||||
out:
|
||||
test_msg("extent I/O tests finished");
|
||||
return ret;
|
||||
}
|
||||
|
@@ -47,7 +47,7 @@ static void free_extent_map_tree(struct extent_map_tree *em_tree)
|
||||
* ->add_extent_mapping(0, 16K)
|
||||
* -> #handle -EEXIST
|
||||
*/
|
||||
static void test_case_1(struct btrfs_fs_info *fs_info,
|
||||
static int test_case_1(struct btrfs_fs_info *fs_info,
|
||||
struct extent_map_tree *em_tree)
|
||||
{
|
||||
struct extent_map *em;
|
||||
@@ -56,9 +56,10 @@ static void test_case_1(struct btrfs_fs_info *fs_info,
|
||||
int ret;
|
||||
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
/* Skip the test on error. */
|
||||
return;
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Add [0, 16K) */
|
||||
em->start = 0;
|
||||
@@ -66,25 +67,37 @@ static void test_case_1(struct btrfs_fs_info *fs_info,
|
||||
em->block_start = 0;
|
||||
em->block_len = SZ_16K;
|
||||
ret = add_extent_mapping(em_tree, em, 0);
|
||||
ASSERT(ret == 0);
|
||||
if (ret < 0) {
|
||||
test_err("cannot add extent range [0, 16K)");
|
||||
goto out;
|
||||
}
|
||||
free_extent_map(em);
|
||||
|
||||
/* Add [16K, 20K) following [0, 16K) */
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
em->start = SZ_16K;
|
||||
em->len = SZ_4K;
|
||||
em->block_start = SZ_32K; /* avoid merging */
|
||||
em->block_len = SZ_4K;
|
||||
ret = add_extent_mapping(em_tree, em, 0);
|
||||
ASSERT(ret == 0);
|
||||
if (ret < 0) {
|
||||
test_err("cannot add extent range [16K, 20K)");
|
||||
goto out;
|
||||
}
|
||||
free_extent_map(em);
|
||||
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Add [0, 8K), should return [0, 16K) instead. */
|
||||
em->start = start;
|
||||
@@ -92,19 +105,24 @@ static void test_case_1(struct btrfs_fs_info *fs_info,
|
||||
em->block_start = start;
|
||||
em->block_len = len;
|
||||
ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
test_err("case1 [%llu %llu]: ret %d", start, start + len, ret);
|
||||
goto out;
|
||||
}
|
||||
if (em &&
|
||||
(em->start != 0 || extent_map_end(em) != SZ_16K ||
|
||||
em->block_start != 0 || em->block_len != SZ_16K))
|
||||
em->block_start != 0 || em->block_len != SZ_16K)) {
|
||||
test_err(
|
||||
"case1 [%llu %llu]: ret %d return a wrong em (start %llu len %llu block_start %llu block_len %llu",
|
||||
start, start + len, ret, em->start, em->len,
|
||||
em->block_start, em->block_len);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
free_extent_map(em);
|
||||
out:
|
||||
/* free memory */
|
||||
free_extent_map_tree(em_tree);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -113,16 +131,17 @@ out:
|
||||
* Reading the inline ending up with EEXIST, ie. read an inline
|
||||
* extent and discard page cache and read it again.
|
||||
*/
|
||||
static void test_case_2(struct btrfs_fs_info *fs_info,
|
||||
static int test_case_2(struct btrfs_fs_info *fs_info,
|
||||
struct extent_map_tree *em_tree)
|
||||
{
|
||||
struct extent_map *em;
|
||||
int ret;
|
||||
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
/* Skip the test on error. */
|
||||
return;
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Add [0, 1K) */
|
||||
em->start = 0;
|
||||
@@ -130,25 +149,37 @@ static void test_case_2(struct btrfs_fs_info *fs_info,
|
||||
em->block_start = EXTENT_MAP_INLINE;
|
||||
em->block_len = (u64)-1;
|
||||
ret = add_extent_mapping(em_tree, em, 0);
|
||||
ASSERT(ret == 0);
|
||||
if (ret < 0) {
|
||||
test_err("cannot add extent range [0, 1K)");
|
||||
goto out;
|
||||
}
|
||||
free_extent_map(em);
|
||||
|
||||
/* Add [4K, 4K) following [0, 1K) */
|
||||
/* Add [4K, 8K) following [0, 1K) */
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
em->start = SZ_4K;
|
||||
em->len = SZ_4K;
|
||||
em->block_start = SZ_4K;
|
||||
em->block_len = SZ_4K;
|
||||
ret = add_extent_mapping(em_tree, em, 0);
|
||||
ASSERT(ret == 0);
|
||||
if (ret < 0) {
|
||||
test_err("cannot add extent range [4K, 8K)");
|
||||
goto out;
|
||||
}
|
||||
free_extent_map(em);
|
||||
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Add [0, 1K) */
|
||||
em->start = 0;
|
||||
@@ -156,22 +187,27 @@ static void test_case_2(struct btrfs_fs_info *fs_info,
|
||||
em->block_start = EXTENT_MAP_INLINE;
|
||||
em->block_len = (u64)-1;
|
||||
ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
test_err("case2 [0 1K]: ret %d", ret);
|
||||
goto out;
|
||||
}
|
||||
if (em &&
|
||||
(em->start != 0 || extent_map_end(em) != SZ_1K ||
|
||||
em->block_start != EXTENT_MAP_INLINE || em->block_len != (u64)-1))
|
||||
em->block_start != EXTENT_MAP_INLINE || em->block_len != (u64)-1)) {
|
||||
test_err(
|
||||
"case2 [0 1K]: ret %d return a wrong em (start %llu len %llu block_start %llu block_len %llu",
|
||||
ret, em->start, em->len, em->block_start,
|
||||
em->block_len);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
free_extent_map(em);
|
||||
out:
|
||||
/* free memory */
|
||||
free_extent_map_tree(em_tree);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __test_case_3(struct btrfs_fs_info *fs_info,
|
||||
static int __test_case_3(struct btrfs_fs_info *fs_info,
|
||||
struct extent_map_tree *em_tree, u64 start)
|
||||
{
|
||||
struct extent_map *em;
|
||||
@@ -179,9 +215,10 @@ static void __test_case_3(struct btrfs_fs_info *fs_info,
|
||||
int ret;
|
||||
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
/* Skip this test on error. */
|
||||
return;
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Add [4K, 8K) */
|
||||
em->start = SZ_4K;
|
||||
@@ -189,12 +226,18 @@ static void __test_case_3(struct btrfs_fs_info *fs_info,
|
||||
em->block_start = SZ_4K;
|
||||
em->block_len = SZ_4K;
|
||||
ret = add_extent_mapping(em_tree, em, 0);
|
||||
ASSERT(ret == 0);
|
||||
if (ret < 0) {
|
||||
test_err("cannot add extent range [4K, 8K)");
|
||||
goto out;
|
||||
}
|
||||
free_extent_map(em);
|
||||
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Add [0, 16K) */
|
||||
em->start = 0;
|
||||
@@ -202,24 +245,29 @@ static void __test_case_3(struct btrfs_fs_info *fs_info,
|
||||
em->block_start = 0;
|
||||
em->block_len = SZ_16K;
|
||||
ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, start, len);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
test_err("case3 [0x%llx 0x%llx): ret %d",
|
||||
start, start + len, ret);
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Since bytes within em are contiguous, em->block_start is identical to
|
||||
* em->start.
|
||||
*/
|
||||
if (em &&
|
||||
(start < em->start || start + len > extent_map_end(em) ||
|
||||
em->start != em->block_start || em->len != em->block_len))
|
||||
em->start != em->block_start || em->len != em->block_len)) {
|
||||
test_err(
|
||||
"case3 [0x%llx 0x%llx): ret %d em (start 0x%llx len 0x%llx block_start 0x%llx block_len 0x%llx)",
|
||||
start, start + len, ret, em->start, em->len,
|
||||
em->block_start, em->block_len);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
free_extent_map(em);
|
||||
out:
|
||||
/* free memory */
|
||||
free_extent_map_tree(em_tree);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -238,15 +286,23 @@ out:
|
||||
* -> add_extent_mapping()
|
||||
* -> add_extent_mapping()
|
||||
*/
|
||||
static void test_case_3(struct btrfs_fs_info *fs_info,
|
||||
static int test_case_3(struct btrfs_fs_info *fs_info,
|
||||
struct extent_map_tree *em_tree)
|
||||
{
|
||||
__test_case_3(fs_info, em_tree, 0);
|
||||
__test_case_3(fs_info, em_tree, SZ_8K);
|
||||
__test_case_3(fs_info, em_tree, (12 * 1024ULL));
|
||||
int ret;
|
||||
|
||||
ret = __test_case_3(fs_info, em_tree, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = __test_case_3(fs_info, em_tree, SZ_8K);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = __test_case_3(fs_info, em_tree, (12 * SZ_1K));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __test_case_4(struct btrfs_fs_info *fs_info,
|
||||
static int __test_case_4(struct btrfs_fs_info *fs_info,
|
||||
struct extent_map_tree *em_tree, u64 start)
|
||||
{
|
||||
struct extent_map *em;
|
||||
@@ -254,9 +310,10 @@ static void __test_case_4(struct btrfs_fs_info *fs_info,
|
||||
int ret;
|
||||
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
/* Skip this test on error. */
|
||||
return;
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Add [0K, 8K) */
|
||||
em->start = 0;
|
||||
@@ -264,44 +321,60 @@ static void __test_case_4(struct btrfs_fs_info *fs_info,
|
||||
em->block_start = 0;
|
||||
em->block_len = SZ_8K;
|
||||
ret = add_extent_mapping(em_tree, em, 0);
|
||||
ASSERT(ret == 0);
|
||||
if (ret < 0) {
|
||||
test_err("cannot add extent range [0, 8K)");
|
||||
goto out;
|
||||
}
|
||||
free_extent_map(em);
|
||||
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Add [8K, 24K) */
|
||||
/* Add [8K, 32K) */
|
||||
em->start = SZ_8K;
|
||||
em->len = 24 * 1024ULL;
|
||||
em->len = 24 * SZ_1K;
|
||||
em->block_start = SZ_16K; /* avoid merging */
|
||||
em->block_len = 24 * 1024ULL;
|
||||
em->block_len = 24 * SZ_1K;
|
||||
ret = add_extent_mapping(em_tree, em, 0);
|
||||
ASSERT(ret == 0);
|
||||
if (ret < 0) {
|
||||
test_err("cannot add extent range [8K, 32K)");
|
||||
goto out;
|
||||
}
|
||||
free_extent_map(em);
|
||||
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
if (!em) {
|
||||
test_std_err(TEST_ALLOC_EXTENT_MAP);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
/* Add [0K, 32K) */
|
||||
em->start = 0;
|
||||
em->len = SZ_32K;
|
||||
em->block_start = 0;
|
||||
em->block_len = SZ_32K;
|
||||
ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, start, len);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
test_err("case4 [0x%llx 0x%llx): ret %d",
|
||||
start, len, ret);
|
||||
if (em &&
|
||||
(start < em->start || start + len > extent_map_end(em)))
|
||||
goto out;
|
||||
}
|
||||
if (em && (start < em->start || start + len > extent_map_end(em))) {
|
||||
test_err(
|
||||
"case4 [0x%llx 0x%llx): ret %d, added wrong em (start 0x%llx len 0x%llx block_start 0x%llx block_len 0x%llx)",
|
||||
start, len, ret, em->start, em->len, em->block_start,
|
||||
em->block_len);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
free_extent_map(em);
|
||||
out:
|
||||
/* free memory */
|
||||
free_extent_map_tree(em_tree);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -329,17 +402,24 @@ out:
|
||||
* # handle -EEXIST when adding
|
||||
* # [0, 32K)
|
||||
*/
|
||||
static void test_case_4(struct btrfs_fs_info *fs_info,
|
||||
static int test_case_4(struct btrfs_fs_info *fs_info,
|
||||
struct extent_map_tree *em_tree)
|
||||
{
|
||||
__test_case_4(fs_info, em_tree, 0);
|
||||
__test_case_4(fs_info, em_tree, SZ_4K);
|
||||
int ret;
|
||||
|
||||
ret = __test_case_4(fs_info, em_tree, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = __test_case_4(fs_info, em_tree, SZ_4K);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_test_extent_map(void)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = NULL;
|
||||
struct extent_map_tree *em_tree;
|
||||
int ret = 0;
|
||||
|
||||
test_msg("running extent_map tests");
|
||||
|
||||
@@ -349,25 +429,32 @@ int btrfs_test_extent_map(void)
|
||||
*/
|
||||
fs_info = btrfs_alloc_dummy_fs_info(PAGE_SIZE, PAGE_SIZE);
|
||||
if (!fs_info) {
|
||||
test_msg("Couldn't allocate dummy fs info");
|
||||
test_std_err(TEST_ALLOC_FS_INFO);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
em_tree = kzalloc(sizeof(*em_tree), GFP_KERNEL);
|
||||
if (!em_tree)
|
||||
/* Skip the test on error. */
|
||||
if (!em_tree) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
extent_map_tree_init(em_tree);
|
||||
|
||||
test_case_1(fs_info, em_tree);
|
||||
test_case_2(fs_info, em_tree);
|
||||
test_case_3(fs_info, em_tree);
|
||||
test_case_4(fs_info, em_tree);
|
||||
ret = test_case_1(fs_info, em_tree);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = test_case_2(fs_info, em_tree);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = test_case_3(fs_info, em_tree);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = test_case_4(fs_info, em_tree);
|
||||
|
||||
kfree(em_tree);
|
||||
out:
|
||||
kfree(em_tree);
|
||||
btrfs_free_dummy_fs_info(fs_info);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
@@ -404,7 +404,7 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache,
|
||||
};
|
||||
const struct btrfs_free_space_op *orig_free_space_ops;
|
||||
|
||||
test_msg("running space stealing from bitmap to extent");
|
||||
test_msg("running space stealing from bitmap to extent tests");
|
||||
|
||||
/*
|
||||
* For this test, we want to ensure we end up with an extent entry
|
||||
@@ -834,9 +834,10 @@ int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)
|
||||
|
||||
test_msg("running btrfs free space cache tests");
|
||||
fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
|
||||
if (!fs_info)
|
||||
if (!fs_info) {
|
||||
test_std_err(TEST_ALLOC_FS_INFO);
|
||||
return -ENOMEM;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* For ppc64 (with 64k page size), bytes per bitmap might be
|
||||
@@ -846,13 +847,14 @@ int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)
|
||||
cache = btrfs_alloc_dummy_block_group(fs_info,
|
||||
BITS_PER_BITMAP * sectorsize + PAGE_SIZE);
|
||||
if (!cache) {
|
||||
test_err("couldn't run the tests");
|
||||
test_std_err(TEST_ALLOC_BLOCK_GROUP);
|
||||
btrfs_free_dummy_fs_info(fs_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
root = btrfs_alloc_dummy_root(fs_info);
|
||||
if (IS_ERR(root)) {
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
ret = PTR_ERR(root);
|
||||
goto out;
|
||||
}
|
||||
@@ -874,6 +876,5 @@ out:
|
||||
btrfs_free_dummy_block_group(cache);
|
||||
btrfs_free_dummy_root(root);
|
||||
btrfs_free_dummy_fs_info(fs_info);
|
||||
test_msg("free space cache tests finished");
|
||||
return ret;
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ static int __check_free_space_extents(struct btrfs_trans_handle *trans,
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
info = search_free_space_info(trans, fs_info, cache, path, 0);
|
||||
info = search_free_space_info(trans, cache, path, 0);
|
||||
if (IS_ERR(info)) {
|
||||
test_err("could not find free space info");
|
||||
ret = PTR_ERR(info);
|
||||
@@ -115,7 +115,7 @@ static int check_free_space_extents(struct btrfs_trans_handle *trans,
|
||||
u32 flags;
|
||||
int ret;
|
||||
|
||||
info = search_free_space_info(trans, fs_info, cache, path, 0);
|
||||
info = search_free_space_info(trans, cache, path, 0);
|
||||
if (IS_ERR(info)) {
|
||||
test_err("could not find free space info");
|
||||
btrfs_release_path(path);
|
||||
@@ -444,14 +444,14 @@ static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
|
||||
|
||||
fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
|
||||
if (!fs_info) {
|
||||
test_err("couldn't allocate dummy fs info");
|
||||
test_std_err(TEST_ALLOC_FS_INFO);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
root = btrfs_alloc_dummy_root(fs_info);
|
||||
if (IS_ERR(root)) {
|
||||
test_err("couldn't allocate dummy root");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
ret = PTR_ERR(root);
|
||||
goto out;
|
||||
}
|
||||
@@ -463,7 +463,7 @@ static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
|
||||
|
||||
root->node = alloc_test_extent_buffer(root->fs_info, nodesize);
|
||||
if (!root->node) {
|
||||
test_err("couldn't allocate dummy buffer");
|
||||
test_std_err(TEST_ALLOC_EXTENT_BUFFER);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -473,7 +473,7 @@ static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
|
||||
|
||||
cache = btrfs_alloc_dummy_block_group(fs_info, 8 * alignment);
|
||||
if (!cache) {
|
||||
test_err("couldn't allocate dummy block group cache");
|
||||
test_std_err(TEST_ALLOC_BLOCK_GROUP);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -486,7 +486,7 @@ static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path) {
|
||||
test_err("couldn't allocate path");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
@@ -226,31 +226,34 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
|
||||
u64 offset;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
test_msg("running btrfs_get_extent tests");
|
||||
|
||||
inode = btrfs_new_test_inode();
|
||||
if (!inode) {
|
||||
test_err("couldn't allocate inode");
|
||||
test_std_err(TEST_ALLOC_INODE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inode->i_mode = S_IFREG;
|
||||
BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
|
||||
BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
|
||||
BTRFS_I(inode)->location.offset = 0;
|
||||
|
||||
fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
|
||||
if (!fs_info) {
|
||||
test_err("couldn't allocate dummy fs info");
|
||||
test_std_err(TEST_ALLOC_FS_INFO);
|
||||
goto out;
|
||||
}
|
||||
|
||||
root = btrfs_alloc_dummy_root(fs_info);
|
||||
if (IS_ERR(root)) {
|
||||
test_err("couldn't allocate root");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
goto out;
|
||||
}
|
||||
|
||||
root->node = alloc_dummy_extent_buffer(fs_info, nodesize);
|
||||
if (!root->node) {
|
||||
test_err("couldn't allocate dummy buffer");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -827,9 +830,11 @@ static int test_hole_first(u32 sectorsize, u32 nodesize)
|
||||
struct extent_map *em = NULL;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
test_msg("running hole first btrfs_get_extent test");
|
||||
|
||||
inode = btrfs_new_test_inode();
|
||||
if (!inode) {
|
||||
test_err("couldn't allocate inode");
|
||||
test_std_err(TEST_ALLOC_INODE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -839,19 +844,19 @@ static int test_hole_first(u32 sectorsize, u32 nodesize)
|
||||
|
||||
fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
|
||||
if (!fs_info) {
|
||||
test_err("couldn't allocate dummy fs info");
|
||||
test_std_err(TEST_ALLOC_FS_INFO);
|
||||
goto out;
|
||||
}
|
||||
|
||||
root = btrfs_alloc_dummy_root(fs_info);
|
||||
if (IS_ERR(root)) {
|
||||
test_err("couldn't allocate root");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
goto out;
|
||||
}
|
||||
|
||||
root->node = alloc_dummy_extent_buffer(fs_info, nodesize);
|
||||
if (!root->node) {
|
||||
test_err("couldn't allocate dummy buffer");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -927,21 +932,23 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
|
||||
struct btrfs_root *root = NULL;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
test_msg("running outstanding_extents tests");
|
||||
|
||||
inode = btrfs_new_test_inode();
|
||||
if (!inode) {
|
||||
test_err("couldn't allocate inode");
|
||||
test_std_err(TEST_ALLOC_INODE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
|
||||
if (!fs_info) {
|
||||
test_err("couldn't allocate dummy fs info");
|
||||
test_std_err(TEST_ALLOC_FS_INFO);
|
||||
goto out;
|
||||
}
|
||||
|
||||
root = btrfs_alloc_dummy_root(fs_info);
|
||||
if (IS_ERR(root)) {
|
||||
test_err("couldn't allocate root");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1110,17 +1117,16 @@ int btrfs_test_inodes(u32 sectorsize, u32 nodesize)
|
||||
{
|
||||
int ret;
|
||||
|
||||
test_msg("running inode tests");
|
||||
|
||||
set_bit(EXTENT_FLAG_COMPRESSED, &compressed_only);
|
||||
set_bit(EXTENT_FLAG_PREALLOC, &prealloc_only);
|
||||
|
||||
test_msg("running btrfs_get_extent tests");
|
||||
ret = test_btrfs_get_extent(sectorsize, nodesize);
|
||||
if (ret)
|
||||
return ret;
|
||||
test_msg("running hole first btrfs_get_extent test");
|
||||
ret = test_hole_first(sectorsize, nodesize);
|
||||
if (ret)
|
||||
return ret;
|
||||
test_msg("running outstanding_extents tests");
|
||||
return test_extent_accounting(sectorsize, nodesize);
|
||||
}
|
||||
|
@@ -32,7 +32,7 @@ static int insert_normal_tree_ref(struct btrfs_root *root, u64 bytenr,
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path) {
|
||||
test_err("couldn't allocate path");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ static int add_tree_ref(struct btrfs_root *root, u64 bytenr, u64 num_bytes,
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path) {
|
||||
test_err("couldn't allocate path");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ static int remove_extent_item(struct btrfs_root *root, u64 bytenr,
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path) {
|
||||
test_err("couldn't allocate path");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
return -ENOMEM;
|
||||
}
|
||||
path->leave_spinning = 1;
|
||||
@@ -166,7 +166,7 @@ static int remove_extent_ref(struct btrfs_root *root, u64 bytenr,
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path) {
|
||||
test_err("couldn't allocate path");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
|
||||
|
||||
btrfs_init_dummy_trans(&trans, fs_info);
|
||||
|
||||
test_msg("qgroup basic add");
|
||||
test_msg("running qgroup add/remove tests");
|
||||
ret = btrfs_create_qgroup(&trans, BTRFS_FS_TREE_OBJECTID);
|
||||
if (ret) {
|
||||
test_err("couldn't create a qgroup %d", ret);
|
||||
@@ -316,7 +316,7 @@ static int test_multiple_refs(struct btrfs_root *root,
|
||||
|
||||
btrfs_init_dummy_trans(&trans, fs_info);
|
||||
|
||||
test_msg("qgroup multiple refs test");
|
||||
test_msg("running qgroup multiple refs test");
|
||||
|
||||
/*
|
||||
* We have BTRFS_FS_TREE_OBJECTID created already from the
|
||||
@@ -457,13 +457,13 @@ int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)
|
||||
|
||||
fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
|
||||
if (!fs_info) {
|
||||
test_err("couldn't allocate dummy fs info");
|
||||
test_std_err(TEST_ALLOC_FS_INFO);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
root = btrfs_alloc_dummy_root(fs_info);
|
||||
if (IS_ERR(root)) {
|
||||
test_err("couldn't allocate root");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
ret = PTR_ERR(root);
|
||||
goto out;
|
||||
}
|
||||
@@ -495,7 +495,7 @@ int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)
|
||||
|
||||
tmp_root = btrfs_alloc_dummy_root(fs_info);
|
||||
if (IS_ERR(tmp_root)) {
|
||||
test_err("couldn't allocate a fs root");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
ret = PTR_ERR(tmp_root);
|
||||
goto out;
|
||||
}
|
||||
@@ -510,7 +510,7 @@ int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)
|
||||
|
||||
tmp_root = btrfs_alloc_dummy_root(fs_info);
|
||||
if (IS_ERR(tmp_root)) {
|
||||
test_err("couldn't allocate a fs root");
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
ret = PTR_ERR(tmp_root);
|
||||
goto out;
|
||||
}
|
||||
|
Reference in New Issue
Block a user