diff options
Diffstat (limited to 'fs/btrfs/tests')
| -rw-r--r-- | fs/btrfs/tests/btrfs-tests.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/tests/extent-buffer-tests.c | 17 | ||||
| -rw-r--r-- | fs/btrfs/tests/extent-io-tests.c | 52 | ||||
| -rw-r--r-- | fs/btrfs/tests/free-space-tests.c | 186 | ||||
| -rw-r--r-- | fs/btrfs/tests/free-space-tree-tests.c | 5 | ||||
| -rw-r--r-- | fs/btrfs/tests/qgroup-tests.c | 5 | 
6 files changed, 251 insertions, 15 deletions
| diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c index 3a4099a2bf05..d8e56edd6991 100644 --- a/fs/btrfs/tests/btrfs-tests.c +++ b/fs/btrfs/tests/btrfs-tests.c @@ -204,6 +204,7 @@ void btrfs_free_dummy_root(struct btrfs_root *root)  	/* Will be freed by btrfs_free_fs_roots */  	if (WARN_ON(test_bit(BTRFS_ROOT_IN_RADIX, &root->state)))  		return; +	btrfs_global_root_delete(root);  	btrfs_put_root(root);  } diff --git a/fs/btrfs/tests/extent-buffer-tests.c b/fs/btrfs/tests/extent-buffer-tests.c index 2a95f7224e18..51a8b075c259 100644 --- a/fs/btrfs/tests/extent-buffer-tests.c +++ b/fs/btrfs/tests/extent-buffer-tests.c @@ -15,7 +15,6 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)  	struct btrfs_path *path = NULL;  	struct btrfs_root *root = NULL;  	struct extent_buffer *eb; -	struct btrfs_item *item;  	char *value = "mary had a little lamb";  	char *split1 = "mary had a little";  	char *split2 = " lamb"; @@ -61,7 +60,6 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)  	key.offset = 0;  	btrfs_setup_item_for_insert(root, path, &key, value_len); -	item = btrfs_item_nr(0);  	write_extent_buffer(eb, value, btrfs_item_ptr_offset(eb, 0),  			    value_len); @@ -90,8 +88,7 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)  		goto out;  	} -	item = btrfs_item_nr(0); -	if (btrfs_item_size(eb, item) != strlen(split1)) { +	if (btrfs_item_size(eb, 0) != strlen(split1)) {  		test_err("invalid len in the first split");  		ret = -EINVAL;  		goto out; @@ -115,8 +112,7 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)  		goto out;  	} -	item = btrfs_item_nr(1); -	if (btrfs_item_size(eb, item) != strlen(split2)) { +	if (btrfs_item_size(eb, 1) != strlen(split2)) {  		test_err("invalid len in the second split");  		ret = -EINVAL;  		goto out; @@ -147,8 +143,7 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)  		goto out;  	} -	item = btrfs_item_nr(0); -	if (btrfs_item_size(eb, item) != strlen(split3)) { +	if (btrfs_item_size(eb, 0) != strlen(split3)) {  		test_err("invalid len in the first split");  		ret = -EINVAL;  		goto out; @@ -171,8 +166,7 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)  		goto out;  	} -	item = btrfs_item_nr(1); -	if (btrfs_item_size(eb, item) != strlen(split4)) { +	if (btrfs_item_size(eb, 1) != strlen(split4)) {  		test_err("invalid len in the second split");  		ret = -EINVAL;  		goto out; @@ -195,8 +189,7 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)  		goto out;  	} -	item = btrfs_item_nr(2); -	if (btrfs_item_size(eb, item) != strlen(split2)) { +	if (btrfs_item_size(eb, 2) != strlen(split2)) {  		test_err("invalid len in the second split");  		ret = -EINVAL;  		goto out; diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c index c2e72e7a8ff0..a232b15b8021 100644 --- a/fs/btrfs/tests/extent-io-tests.c +++ b/fs/btrfs/tests/extent-io-tests.c @@ -56,6 +56,54 @@ static noinline int process_page_range(struct inode *inode, u64 start, u64 end,  	return count;  } +#define STATE_FLAG_STR_LEN			256 + +#define PRINT_ONE_FLAG(state, dest, cur, name)				\ +({									\ +	if (state->state & EXTENT_##name)				\ +		cur += scnprintf(dest + cur, STATE_FLAG_STR_LEN - cur,	\ +				 "%s" #name, cur == 0 ? "" : "|");	\ +}) + +static void extent_flag_to_str(const struct extent_state *state, char *dest) +{ +	int cur = 0; + +	dest[0] = 0; +	PRINT_ONE_FLAG(state, dest, cur, DIRTY); +	PRINT_ONE_FLAG(state, dest, cur, UPTODATE); +	PRINT_ONE_FLAG(state, dest, cur, LOCKED); +	PRINT_ONE_FLAG(state, dest, cur, NEW); +	PRINT_ONE_FLAG(state, dest, cur, DELALLOC); +	PRINT_ONE_FLAG(state, dest, cur, DEFRAG); +	PRINT_ONE_FLAG(state, dest, cur, BOUNDARY); +	PRINT_ONE_FLAG(state, dest, cur, NODATASUM); +	PRINT_ONE_FLAG(state, dest, cur, CLEAR_META_RESV); +	PRINT_ONE_FLAG(state, dest, cur, NEED_WAIT); +	PRINT_ONE_FLAG(state, dest, cur, DAMAGED); +	PRINT_ONE_FLAG(state, dest, cur, NORESERVE); +	PRINT_ONE_FLAG(state, dest, cur, QGROUP_RESERVED); +	PRINT_ONE_FLAG(state, dest, cur, CLEAR_DATA_RESV); +} + +static void dump_extent_io_tree(const struct extent_io_tree *tree) +{ +	struct rb_node *node; +	char flags_str[STATE_FLAG_STR_LEN]; + +	node = rb_first(&tree->state); +	test_msg("io tree content:"); +	while (node) { +		struct extent_state *state; + +		state = rb_entry(node, struct extent_state, rb_node); +		extent_flag_to_str(state, flags_str); +		test_msg("  start=%llu len=%llu flags=%s", state->start, +			 state->end + 1 - state->start, flags_str); +		node = rb_next(node); +	} +} +  static int test_find_delalloc(u32 sectorsize)  {  	struct inode *inode; @@ -258,6 +306,8 @@ static int test_find_delalloc(u32 sectorsize)  	}  	ret = 0;  out_bits: +	if (ret) +		dump_extent_io_tree(tmp);  	clear_extent_bits(tmp, 0, total_dirty - 1, (unsigned)-1);  out:  	if (locked_page) @@ -534,6 +584,8 @@ static int test_find_first_clear_extent_bit(void)  	ret = 0;  out: +	if (ret) +		dump_extent_io_tree(&tree);  	clear_extent_bits(&tree, 0, (u64)-1, CHUNK_TRIMMED | CHUNK_ALLOCATED);  	return ret; diff --git a/fs/btrfs/tests/free-space-tests.c b/fs/btrfs/tests/free-space-tests.c index 8f05c1eb833f..5930cdcae5cb 100644 --- a/fs/btrfs/tests/free-space-tests.c +++ b/fs/btrfs/tests/free-space-tests.c @@ -824,6 +824,184 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group *cache,  	return 0;  } +static bool bytes_index_use_bitmap(struct btrfs_free_space_ctl *ctl, +				   struct btrfs_free_space *info) +{ +	return true; +} + +static int test_bytes_index(struct btrfs_block_group *cache, u32 sectorsize) +{ +	const struct btrfs_free_space_op test_free_space_ops = { +		.use_bitmap = bytes_index_use_bitmap, +	}; +	const struct btrfs_free_space_op *orig_free_space_ops; +	struct btrfs_free_space_ctl *ctl = cache->free_space_ctl; +	struct btrfs_free_space *entry; +	struct rb_node *node; +	u64 offset, max_extent_size, bytes; +	int ret, i; + +	test_msg("running bytes index tests"); + +	/* First just validate that it does everything in order. */ +	offset = 0; +	for (i = 0; i < 10; i++) { +		bytes = (i + 1) * SZ_1M; +		ret = test_add_free_space_entry(cache, offset, bytes, 0); +		if (ret) { +			test_err("couldn't add extent entry %d\n", ret); +			return ret; +		} +		offset += bytes + sectorsize; +	} + +	for (node = rb_first_cached(&ctl->free_space_bytes), i = 9; node; +	     node = rb_next(node), i--) { +		entry = rb_entry(node, struct btrfs_free_space, bytes_index); +		bytes = (i + 1) * SZ_1M; +		if (entry->bytes != bytes) { +			test_err("invalid bytes index order, found %llu expected %llu", +				 entry->bytes, bytes); +			return -EINVAL; +		} +	} + +	/* Now validate bitmaps do the correct thing. */ +	__btrfs_remove_free_space_cache(cache->free_space_ctl); +	for (i = 0; i < 2; i++) { +		offset = i * BITS_PER_BITMAP * sectorsize; +		bytes = (i + 1) * SZ_1M; +		ret = test_add_free_space_entry(cache, offset, bytes, 1); +		if (ret) { +			test_err("couldn't add bitmap entry"); +			return ret; +		} +	} + +	for (node = rb_first_cached(&ctl->free_space_bytes), i = 1; node; +	     node = rb_next(node), i--) { +		entry = rb_entry(node, struct btrfs_free_space, bytes_index); +		bytes = (i + 1) * SZ_1M; +		if (entry->bytes != bytes) { +			test_err("invalid bytes index order, found %llu expected %llu", +				 entry->bytes, bytes); +			return -EINVAL; +		} +	} + +	/* Now validate bitmaps with different ->max_extent_size. */ +	__btrfs_remove_free_space_cache(cache->free_space_ctl); +	orig_free_space_ops = cache->free_space_ctl->op; +	cache->free_space_ctl->op = &test_free_space_ops; + +	ret = test_add_free_space_entry(cache, 0, sectorsize, 1); +	if (ret) { +		test_err("couldn't add bitmap entry"); +		return ret; +	} + +	offset = BITS_PER_BITMAP * sectorsize; +	ret = test_add_free_space_entry(cache, offset, sectorsize, 1); +	if (ret) { +		test_err("couldn't add bitmap_entry"); +		return ret; +	} + +	/* +	 * Now set a bunch of sectorsize extents in the first entry so it's +	 * ->bytes is large. +	 */ +	for (i = 2; i < 20; i += 2) { +		offset = sectorsize * i; +		ret = btrfs_add_free_space(cache, offset, sectorsize); +		if (ret) { +			test_err("error populating sparse bitmap %d", ret); +			return ret; +		} +	} + +	/* +	 * Now set a contiguous extent in the second bitmap so its +	 * ->max_extent_size is larger than the first bitmaps. +	 */ +	offset = (BITS_PER_BITMAP * sectorsize) + sectorsize; +	ret = btrfs_add_free_space(cache, offset, sectorsize); +	if (ret) { +		test_err("error adding contiguous extent %d", ret); +		return ret; +	} + +	/* +	 * Since we don't set ->max_extent_size unless we search everything +	 * should be indexed on bytes. +	 */ +	entry = rb_entry(rb_first_cached(&ctl->free_space_bytes), +			 struct btrfs_free_space, bytes_index); +	if (entry->bytes != (10 * sectorsize)) { +		test_err("error, wrong entry in the first slot in bytes_index"); +		return -EINVAL; +	} + +	max_extent_size = 0; +	offset = btrfs_find_space_for_alloc(cache, cache->start, sectorsize * 3, +					    0, &max_extent_size); +	if (offset != 0) { +		test_err("found space to alloc even though we don't have enough space"); +		return -EINVAL; +	} + +	if (max_extent_size != (2 * sectorsize)) { +		test_err("got the wrong max_extent size %llu expected %llu", +			 max_extent_size, (unsigned long long)(2 * sectorsize)); +		return -EINVAL; +	} + +	/* +	 * The search should have re-arranged the bytes index to use the +	 * ->max_extent_size, validate it's now what we expect it to be. +	 */ +	entry = rb_entry(rb_first_cached(&ctl->free_space_bytes), +			 struct btrfs_free_space, bytes_index); +	if (entry->bytes != (2 * sectorsize)) { +		test_err("error, the bytes index wasn't recalculated properly"); +		return -EINVAL; +	} + +	/* Add another sectorsize to re-arrange the tree back to ->bytes. */ +	offset = (BITS_PER_BITMAP * sectorsize) - sectorsize; +	ret = btrfs_add_free_space(cache, offset, sectorsize); +	if (ret) { +		test_err("error adding extent to the sparse entry %d", ret); +		return ret; +	} + +	entry = rb_entry(rb_first_cached(&ctl->free_space_bytes), +			 struct btrfs_free_space, bytes_index); +	if (entry->bytes != (11 * sectorsize)) { +		test_err("error, wrong entry in the first slot in bytes_index"); +		return -EINVAL; +	} + +	/* +	 * Now make sure we find our correct entry after searching that will +	 * result in a re-arranging of the tree. +	 */ +	max_extent_size = 0; +	offset = btrfs_find_space_for_alloc(cache, cache->start, sectorsize * 2, +					    0, &max_extent_size); +	if (offset != (BITS_PER_BITMAP * sectorsize)) { +		test_err("error, found %llu instead of %llu for our alloc", +			 offset, +			 (unsigned long long)(BITS_PER_BITMAP * sectorsize)); +		return -EINVAL; +	} + +	cache->free_space_ctl->op = orig_free_space_ops; +	__btrfs_remove_free_space_cache(cache->free_space_ctl); +	return 0; +} +  int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)  {  	struct btrfs_fs_info *fs_info; @@ -858,7 +1036,10 @@ int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)  		goto out;  	} -	root->fs_info->extent_root = root; +	root->root_key.objectid = BTRFS_EXTENT_TREE_OBJECTID; +	root->root_key.type = BTRFS_ROOT_ITEM_KEY; +	root->root_key.offset = 0; +	btrfs_global_root_insert(root);  	ret = test_extents(cache);  	if (ret) @@ -871,6 +1052,9 @@ int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)  		goto out;  	ret = test_steal_space_from_bitmap_to_extent(cache, sectorsize); +	if (ret) +		goto out; +	ret = test_bytes_index(cache, sectorsize);  out:  	btrfs_free_dummy_block_group(cache);  	btrfs_free_dummy_root(root); diff --git a/fs/btrfs/tests/free-space-tree-tests.c b/fs/btrfs/tests/free-space-tree-tests.c index 2c783d2f5228..13734ed43bfc 100644 --- a/fs/btrfs/tests/free-space-tree-tests.c +++ b/fs/btrfs/tests/free-space-tree-tests.c @@ -446,7 +446,10 @@ static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,  	btrfs_set_super_compat_ro_flags(root->fs_info->super_copy,  					BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE); -	root->fs_info->free_space_root = root; +	root->root_key.objectid = BTRFS_FREE_SPACE_TREE_OBJECTID; +	root->root_key.type = BTRFS_ROOT_ITEM_KEY; +	root->root_key.offset = 0; +	btrfs_global_root_insert(root);  	root->fs_info->tree_root = root;  	root->node = alloc_test_extent_buffer(root->fs_info, nodesize); diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c index 19ba7d5b7d8f..eee1e4459541 100644 --- a/fs/btrfs/tests/qgroup-tests.c +++ b/fs/btrfs/tests/qgroup-tests.c @@ -455,7 +455,10 @@ int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)  	}  	/* We are using this root as our extent root */ -	root->fs_info->extent_root = root; +	root->root_key.objectid = BTRFS_EXTENT_TREE_OBJECTID; +	root->root_key.type = BTRFS_ROOT_ITEM_KEY; +	root->root_key.offset = 0; +	btrfs_global_root_insert(root);  	/*  	 * Some of the paths we test assume we have a filled out fs_info, so we |