/* * Since the test trans doesn't have the complicated delayed refs, * we can only call btrfs_qgroup_account_extent() directly to test * quota.
*/
ret = btrfs_find_all_roots(&ctx, false); if (ret) {
test_err("couldn't find old roots: %d", ret); return ret;
}
old_roots = ctx.roots;
ctx.roots = NULL;
ret = insert_normal_tree_ref(root, nodesize, nodesize, 0,
BTRFS_FS_TREE_OBJECTID); if (ret) {
ulist_free(old_roots); return ret;
}
ret = btrfs_find_all_roots(&ctx, false); if (ret) {
ulist_free(old_roots);
test_err("couldn't find old roots: %d", ret); return ret;
}
new_roots = ctx.roots;
ctx.roots = NULL;
ret = btrfs_qgroup_account_extent(&trans, nodesize, nodesize, old_roots,
new_roots); if (ret) {
test_err("couldn't account space for a qgroup %d", ret); return ret;
}
/* btrfs_qgroup_account_extent() always frees the ulists passed to it. */
old_roots = NULL;
new_roots = NULL;
if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID,
nodesize, nodesize)) {
test_err("qgroup counts didn't match expected values"); return -EINVAL;
}
ret = btrfs_find_all_roots(&ctx, false); if (ret) {
test_err("couldn't find old roots: %d", ret); return ret;
}
old_roots = ctx.roots;
ctx.roots = NULL;
ret = remove_extent_item(root, nodesize, nodesize); if (ret) {
ulist_free(old_roots); return -EINVAL;
}
ret = btrfs_find_all_roots(&ctx, false); if (ret) {
ulist_free(old_roots);
test_err("couldn't find old roots: %d", ret); return ret;
}
new_roots = ctx.roots;
ctx.roots = NULL;
ret = btrfs_qgroup_account_extent(&trans, nodesize, nodesize, old_roots,
new_roots); if (ret) {
test_err("couldn't account space for a qgroup %d", ret); return -EINVAL;
}
if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, 0, 0)) {
test_err("qgroup counts didn't match expected values"); return -EINVAL;
}
return 0;
}
/* * Add a ref for two different roots to make sure the shared value comes out * right, also remove one of the roots and make sure the exclusive count is * adjusted properly.
*/ staticint test_multiple_refs(struct btrfs_root *root,
u32 sectorsize, u32 nodesize)
{ struct btrfs_backref_walk_ctx ctx = { 0 }; struct btrfs_trans_handle trans; struct btrfs_fs_info *fs_info = root->fs_info; struct ulist *old_roots = NULL; struct ulist *new_roots = NULL; int ret;
btrfs_init_dummy_trans(&trans, fs_info);
test_msg("running qgroup multiple refs test");
/* * We have BTRFS_FS_TREE_OBJECTID created already from the * previous test.
*/
ret = btrfs_create_qgroup(&trans, BTRFS_FIRST_FREE_OBJECTID); if (ret) {
test_err("couldn't create a qgroup %d", ret); return ret;
}
ret = btrfs_find_all_roots(&ctx, false); if (ret) {
test_err("couldn't find old roots: %d", ret); return ret;
}
old_roots = ctx.roots;
ctx.roots = NULL;
ret = insert_normal_tree_ref(root, nodesize, nodesize, 0,
BTRFS_FS_TREE_OBJECTID); if (ret) {
ulist_free(old_roots); return ret;
}
ret = btrfs_find_all_roots(&ctx, false); if (ret) {
ulist_free(old_roots);
test_err("couldn't find old roots: %d", ret); return ret;
}
new_roots = ctx.roots;
ctx.roots = NULL;
ret = btrfs_qgroup_account_extent(&trans, nodesize, nodesize, old_roots,
new_roots); if (ret) {
test_err("couldn't account space for a qgroup %d", ret); return ret;
}
if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID,
nodesize, nodesize)) {
test_err("qgroup counts didn't match expected values"); return -EINVAL;
}
ret = btrfs_find_all_roots(&ctx, false); if (ret) {
test_err("couldn't find old roots: %d", ret); return ret;
}
old_roots = ctx.roots;
ctx.roots = NULL;
ret = add_tree_ref(root, nodesize, nodesize, 0,
BTRFS_FIRST_FREE_OBJECTID); if (ret) {
ulist_free(old_roots); return ret;
}
ret = btrfs_find_all_roots(&ctx, false); if (ret) {
ulist_free(old_roots);
test_err("couldn't find old roots: %d", ret); return ret;
}
new_roots = ctx.roots;
ctx.roots = NULL;
ret = btrfs_qgroup_account_extent(&trans, nodesize, nodesize, old_roots,
new_roots); if (ret) {
test_err("couldn't account space for a qgroup %d", ret); return ret;
}
if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID,
nodesize, 0)) {
test_err("qgroup counts didn't match expected values"); return -EINVAL;
}
if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FIRST_FREE_OBJECTID,
nodesize, 0)) {
test_err("qgroup counts didn't match expected values"); return -EINVAL;
}
ret = btrfs_find_all_roots(&ctx, false); if (ret) {
test_err("couldn't find old roots: %d", ret); return ret;
}
old_roots = ctx.roots;
ctx.roots = NULL;
ret = remove_extent_ref(root, nodesize, nodesize, 0,
BTRFS_FIRST_FREE_OBJECTID); if (ret) {
ulist_free(old_roots); return ret;
}
ret = btrfs_find_all_roots(&ctx, false); if (ret) {
ulist_free(old_roots);
test_err("couldn't find old roots: %d", ret); return ret;
}
new_roots = ctx.roots;
ctx.roots = NULL;
ret = btrfs_qgroup_account_extent(&trans, nodesize, nodesize, old_roots,
new_roots); if (ret) {
test_err("couldn't account space for a qgroup %d", ret); return ret;
}
if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FIRST_FREE_OBJECTID,
0, 0)) {
test_err("qgroup counts didn't match expected values"); return -EINVAL;
}
if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID,
nodesize, nodesize)) {
test_err("qgroup counts didn't match expected values"); return -EINVAL;
}
return 0;
}
int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)
{ struct btrfs_fs_info *fs_info = NULL; struct btrfs_root *root; struct btrfs_root *tmp_root; int ret = 0;
root = btrfs_alloc_dummy_root(fs_info); if (IS_ERR(root)) {
test_std_err(TEST_ALLOC_ROOT);
ret = PTR_ERR(root); goto out;
}
/* We are using this root as our extent 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 * just need to add the root in there so we don't panic.
*/
root->fs_info->tree_root = root;
root->fs_info->quota_root = root;
set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
/* * Can't use bytenr 0, some things freak out * *cough*backref walking code*cough*
*/
root->node = alloc_test_extent_buffer(root->fs_info, nodesize); if (IS_ERR(root->node)) {
test_err("couldn't allocate dummy buffer");
ret = PTR_ERR(root->node); goto out;
}
btrfs_set_header_level(root->node, 0);
btrfs_set_header_nritems(root->node, 0);
root->alloc_bytenr += 2 * nodesize;
tmp_root = btrfs_alloc_dummy_root(fs_info); if (IS_ERR(tmp_root)) {
test_std_err(TEST_ALLOC_ROOT);
ret = PTR_ERR(tmp_root); goto out;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.