Skip to content

Commit faa2dbf

Browse files
Josef Bacikmasoncl
authored andcommitted
Btrfs: add sanity tests for new qgroup accounting code
This exercises the various parts of the new qgroup accounting code. We do some basic stuff and do some things with the shared refs to make sure all that code works. I had to add a bunch of infrastructure because I needed to be able to insert items into a fake tree without having to do all the hard work myself, hopefully this will be usefull in the future. Thanks, Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: Chris Mason <[email protected]>
1 parent fcebe45 commit faa2dbf

File tree

16 files changed

+700
-37
lines changed

16 files changed

+700
-37
lines changed

fs/btrfs/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o
1616

1717
btrfs-$(CONFIG_BTRFS_FS_RUN_SANITY_TESTS) += tests/free-space-tests.o \
1818
tests/extent-buffer-tests.o tests/btrfs-tests.o \
19-
tests/extent-io-tests.o tests/inode-tests.o
19+
tests/extent-io-tests.o tests/inode-tests.o tests/qgroup-tests.o

fs/btrfs/backref.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,11 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
900900
goto out;
901901
BUG_ON(ret == 0);
902902

903+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
904+
if (trans && likely(trans->type != __TRANS_DUMMY)) {
905+
#else
903906
if (trans) {
907+
#endif
904908
/*
905909
* look if there are updates for this ref queued and lock the
906910
* head

fs/btrfs/ctree.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,10 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
15061506
struct btrfs_root *root,
15071507
struct extent_buffer *buf)
15081508
{
1509+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
1510+
if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state)))
1511+
return 0;
1512+
#endif
15091513
/* ensure we can see the force_cow */
15101514
smp_rmb();
15111515

fs/btrfs/ctree.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,6 +1798,10 @@ struct btrfs_root {
17981798

17991799
u64 highest_objectid;
18001800

1801+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
1802+
u64 alloc_bytenr;
1803+
#endif
1804+
18011805
u64 defrag_trans_start;
18021806
struct btrfs_key defrag_progress;
18031807
struct btrfs_key defrag_max;
@@ -4111,6 +4115,8 @@ static inline int btrfs_defrag_cancelled(struct btrfs_fs_info *fs_info)
41114115
/* Sanity test specific functions */
41124116
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
41134117
void btrfs_test_destroy_inode(struct inode *inode);
4118+
int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid,
4119+
u64 rfer, u64 excl);
41144120
#endif
41154121

41164122
#endif

fs/btrfs/disk-io.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,11 @@ struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
11101110
struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
11111111
u64 bytenr, u32 blocksize)
11121112
{
1113+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
1114+
if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state)))
1115+
return alloc_test_extent_buffer(root->fs_info, bytenr,
1116+
blocksize);
1117+
#endif
11131118
return alloc_extent_buffer(root->fs_info, bytenr, blocksize);
11141119
}
11151120

@@ -1288,6 +1293,7 @@ struct btrfs_root *btrfs_alloc_dummy_root(void)
12881293
return ERR_PTR(-ENOMEM);
12891294
__setup_root(4096, 4096, 4096, 4096, root, NULL, 1);
12901295
set_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state);
1296+
root->alloc_bytenr = 0;
12911297

12921298
return root;
12931299
}
@@ -2089,7 +2095,7 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root)
20892095
free_root_extent_buffers(info->chunk_root);
20902096
}
20912097

2092-
static void del_fs_roots(struct btrfs_fs_info *fs_info)
2098+
void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info)
20932099
{
20942100
int ret;
20952101
struct btrfs_root *gang[8];
@@ -2969,7 +2975,7 @@ int open_ctree(struct super_block *sb,
29692975
fail_trans_kthread:
29702976
kthread_stop(fs_info->transaction_kthread);
29712977
btrfs_cleanup_transaction(fs_info->tree_root);
2972-
del_fs_roots(fs_info);
2978+
btrfs_free_fs_roots(fs_info);
29732979
fail_cleaner:
29742980
kthread_stop(fs_info->cleaner_kthread);
29752981

@@ -3504,8 +3510,10 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
35043510
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
35053511
btrfs_free_log(NULL, root);
35063512

3507-
__btrfs_remove_free_space_cache(root->free_ino_pinned);
3508-
__btrfs_remove_free_space_cache(root->free_ino_ctl);
3513+
if (root->free_ino_pinned)
3514+
__btrfs_remove_free_space_cache(root->free_ino_pinned);
3515+
if (root->free_ino_ctl)
3516+
__btrfs_remove_free_space_cache(root->free_ino_ctl);
35093517
free_fs_root(root);
35103518
}
35113519

@@ -3655,7 +3663,7 @@ int close_ctree(struct btrfs_root *root)
36553663

36563664
btrfs_sysfs_remove_one(fs_info);
36573665

3658-
del_fs_roots(fs_info);
3666+
btrfs_free_fs_roots(fs_info);
36593667

36603668
btrfs_put_block_group_cache(fs_info);
36613669

fs/btrfs/disk-io.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
6868
int btrfs_init_fs_root(struct btrfs_root *root);
6969
int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
7070
struct btrfs_root *root);
71+
void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info);
7172

7273
struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
7374
struct btrfs_key *key,

fs/btrfs/extent-tree.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2992,6 +2992,10 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
29922992
int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *,
29932993
u64, u64, u64, u64, u64, u64, int);
29942994

2995+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
2996+
if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state)))
2997+
return 0;
2998+
#endif
29952999
ref_root = btrfs_header_owner(buf);
29963000
nritems = btrfs_header_nritems(buf);
29973001
level = btrfs_header_level(buf);
@@ -6151,6 +6155,10 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root,
61516155
int ret;
61526156
struct btrfs_fs_info *fs_info = root->fs_info;
61536157

6158+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
6159+
if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state)))
6160+
return 0;
6161+
#endif
61546162
add_pinned_bytes(root->fs_info, num_bytes, owner, root_objectid);
61556163

61566164
/*
@@ -7157,6 +7165,15 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
71577165
bool skinny_metadata = btrfs_fs_incompat(root->fs_info,
71587166
SKINNY_METADATA);
71597167

7168+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
7169+
if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state))) {
7170+
buf = btrfs_init_new_buffer(trans, root, root->alloc_bytenr,
7171+
blocksize, level);
7172+
if (!IS_ERR(buf))
7173+
root->alloc_bytenr += blocksize;
7174+
return buf;
7175+
}
7176+
#endif
71607177
block_rsv = use_block_rsv(trans, root, blocksize);
71617178
if (IS_ERR(block_rsv))
71627179
return ERR_CAST(block_rsv);

fs/btrfs/extent_io.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4549,6 +4549,53 @@ struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info,
45494549
return NULL;
45504550
}
45514551

4552+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
4553+
struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info,
4554+
u64 start, unsigned long len)
4555+
{
4556+
struct extent_buffer *eb, *exists = NULL;
4557+
int ret;
4558+
4559+
eb = find_extent_buffer(fs_info, start);
4560+
if (eb)
4561+
return eb;
4562+
eb = alloc_dummy_extent_buffer(start, len);
4563+
if (!eb)
4564+
return NULL;
4565+
eb->fs_info = fs_info;
4566+
again:
4567+
ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
4568+
if (ret)
4569+
goto free_eb;
4570+
spin_lock(&fs_info->buffer_lock);
4571+
ret = radix_tree_insert(&fs_info->buffer_radix,
4572+
start >> PAGE_CACHE_SHIFT, eb);
4573+
spin_unlock(&fs_info->buffer_lock);
4574+
radix_tree_preload_end();
4575+
if (ret == -EEXIST) {
4576+
exists = find_extent_buffer(fs_info, start);
4577+
if (exists)
4578+
goto free_eb;
4579+
else
4580+
goto again;
4581+
}
4582+
check_buffer_tree_ref(eb);
4583+
set_bit(EXTENT_BUFFER_IN_TREE, &eb->bflags);
4584+
4585+
/*
4586+
* We will free dummy extent buffer's if they come into
4587+
* free_extent_buffer with a ref count of 2, but if we are using this we
4588+
* want the buffers to stay in memory until we're done with them, so
4589+
* bump the ref count again.
4590+
*/
4591+
atomic_inc(&eb->refs);
4592+
return eb;
4593+
free_eb:
4594+
btrfs_release_extent_buffer(eb);
4595+
return exists;
4596+
}
4597+
#endif
4598+
45524599
struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
45534600
u64 start, unsigned long len)
45544601
{

fs/btrfs/extent_io.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,5 +350,7 @@ noinline u64 find_lock_delalloc_range(struct inode *inode,
350350
struct extent_io_tree *tree,
351351
struct page *locked_page, u64 *start,
352352
u64 *end, u64 max_bytes);
353+
struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info,
354+
u64 start, unsigned long len);
353355
#endif
354356
#endif

fs/btrfs/qgroup.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,21 @@ static int del_relation_rb(struct btrfs_fs_info *fs_info,
246246
return -ENOENT;
247247
}
248248

249+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
250+
int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid,
251+
u64 rfer, u64 excl)
252+
{
253+
struct btrfs_qgroup *qgroup;
254+
255+
qgroup = find_qgroup_rb(fs_info, qgroupid);
256+
if (!qgroup)
257+
return -EINVAL;
258+
if (qgroup->rfer != rfer || qgroup->excl != excl)
259+
return -EINVAL;
260+
return 0;
261+
}
262+
#endif
263+
249264
/*
250265
* The full config is read in one go, only called from open_ctree()
251266
* It doesn't use any locking, as at this point we're still single-threaded
@@ -524,6 +539,10 @@ static int add_qgroup_item(struct btrfs_trans_handle *trans,
524539
struct extent_buffer *leaf;
525540
struct btrfs_key key;
526541

542+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
543+
if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &quota_root->state)))
544+
return 0;
545+
#endif
527546
path = btrfs_alloc_path();
528547
if (!path)
529548
return -ENOMEM;
@@ -673,6 +692,10 @@ static int update_qgroup_info_item(struct btrfs_trans_handle *trans,
673692
int ret;
674693
int slot;
675694

695+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
696+
if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state)))
697+
return 0;
698+
#endif
676699
key.objectid = 0;
677700
key.type = BTRFS_QGROUP_INFO_KEY;
678701
key.offset = qgroup->qgroupid;

0 commit comments

Comments
 (0)