Commit | Line | Data |
---|---|---|
faa2dbf0 JB |
1 | /* |
2 | * Copyright (C) 2013 Facebook. All rights reserved. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public | |
6 | * License v2 as published by the Free Software Foundation. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
11 | * General Public License for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU General Public | |
14 | * License along with this program; if not, write to the | |
15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
16 | * Boston, MA 021110-1307, USA. | |
17 | */ | |
18 | ||
b9ef22de | 19 | #include <linux/types.h> |
faa2dbf0 JB |
20 | #include "btrfs-tests.h" |
21 | #include "../ctree.h" | |
22 | #include "../transaction.h" | |
23 | #include "../disk-io.h" | |
24 | #include "../qgroup.h" | |
442244c9 | 25 | #include "../backref.h" |
faa2dbf0 | 26 | |
faa2dbf0 JB |
27 | static int insert_normal_tree_ref(struct btrfs_root *root, u64 bytenr, |
28 | u64 num_bytes, u64 parent, u64 root_objectid) | |
29 | { | |
30 | struct btrfs_trans_handle trans; | |
31 | struct btrfs_extent_item *item; | |
32 | struct btrfs_extent_inline_ref *iref; | |
33 | struct btrfs_tree_block_info *block_info; | |
34 | struct btrfs_path *path; | |
35 | struct extent_buffer *leaf; | |
36 | struct btrfs_key ins; | |
37 | u32 size = sizeof(*item) + sizeof(*iref) + sizeof(*block_info); | |
38 | int ret; | |
39 | ||
7c55ee0c | 40 | btrfs_init_dummy_trans(&trans); |
faa2dbf0 JB |
41 | |
42 | ins.objectid = bytenr; | |
43 | ins.type = BTRFS_EXTENT_ITEM_KEY; | |
44 | ins.offset = num_bytes; | |
45 | ||
46 | path = btrfs_alloc_path(); | |
47 | if (!path) { | |
48 | test_msg("Couldn't allocate path\n"); | |
49 | return -ENOMEM; | |
50 | } | |
51 | ||
52 | path->leave_spinning = 1; | |
53 | ret = btrfs_insert_empty_item(&trans, root, path, &ins, size); | |
54 | if (ret) { | |
55 | test_msg("Couldn't insert ref %d\n", ret); | |
56 | btrfs_free_path(path); | |
57 | return ret; | |
58 | } | |
59 | ||
60 | leaf = path->nodes[0]; | |
61 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); | |
62 | btrfs_set_extent_refs(leaf, item, 1); | |
63 | btrfs_set_extent_generation(leaf, item, 1); | |
64 | btrfs_set_extent_flags(leaf, item, BTRFS_EXTENT_FLAG_TREE_BLOCK); | |
65 | block_info = (struct btrfs_tree_block_info *)(item + 1); | |
66 | btrfs_set_tree_block_level(leaf, block_info, 1); | |
67 | iref = (struct btrfs_extent_inline_ref *)(block_info + 1); | |
68 | if (parent > 0) { | |
69 | btrfs_set_extent_inline_ref_type(leaf, iref, | |
70 | BTRFS_SHARED_BLOCK_REF_KEY); | |
71 | btrfs_set_extent_inline_ref_offset(leaf, iref, parent); | |
72 | } else { | |
73 | btrfs_set_extent_inline_ref_type(leaf, iref, BTRFS_TREE_BLOCK_REF_KEY); | |
74 | btrfs_set_extent_inline_ref_offset(leaf, iref, root_objectid); | |
75 | } | |
76 | btrfs_free_path(path); | |
77 | return 0; | |
78 | } | |
79 | ||
80 | static int add_tree_ref(struct btrfs_root *root, u64 bytenr, u64 num_bytes, | |
81 | u64 parent, u64 root_objectid) | |
82 | { | |
83 | struct btrfs_trans_handle trans; | |
84 | struct btrfs_extent_item *item; | |
85 | struct btrfs_path *path; | |
86 | struct btrfs_key key; | |
87 | u64 refs; | |
88 | int ret; | |
89 | ||
7c55ee0c | 90 | btrfs_init_dummy_trans(&trans); |
faa2dbf0 JB |
91 | |
92 | key.objectid = bytenr; | |
93 | key.type = BTRFS_EXTENT_ITEM_KEY; | |
94 | key.offset = num_bytes; | |
95 | ||
96 | path = btrfs_alloc_path(); | |
97 | if (!path) { | |
98 | test_msg("Couldn't allocate path\n"); | |
99 | return -ENOMEM; | |
100 | } | |
101 | ||
102 | path->leave_spinning = 1; | |
103 | ret = btrfs_search_slot(&trans, root, &key, path, 0, 1); | |
104 | if (ret) { | |
105 | test_msg("Couldn't find extent ref\n"); | |
106 | btrfs_free_path(path); | |
107 | return ret; | |
108 | } | |
109 | ||
110 | item = btrfs_item_ptr(path->nodes[0], path->slots[0], | |
111 | struct btrfs_extent_item); | |
112 | refs = btrfs_extent_refs(path->nodes[0], item); | |
113 | btrfs_set_extent_refs(path->nodes[0], item, refs + 1); | |
114 | btrfs_release_path(path); | |
115 | ||
116 | key.objectid = bytenr; | |
117 | if (parent) { | |
118 | key.type = BTRFS_SHARED_BLOCK_REF_KEY; | |
119 | key.offset = parent; | |
120 | } else { | |
121 | key.type = BTRFS_TREE_BLOCK_REF_KEY; | |
122 | key.offset = root_objectid; | |
123 | } | |
124 | ||
125 | ret = btrfs_insert_empty_item(&trans, root, path, &key, 0); | |
126 | if (ret) | |
127 | test_msg("Failed to insert backref\n"); | |
128 | btrfs_free_path(path); | |
129 | return ret; | |
130 | } | |
131 | ||
132 | static int remove_extent_item(struct btrfs_root *root, u64 bytenr, | |
133 | u64 num_bytes) | |
134 | { | |
135 | struct btrfs_trans_handle trans; | |
136 | struct btrfs_key key; | |
137 | struct btrfs_path *path; | |
138 | int ret; | |
139 | ||
7c55ee0c | 140 | btrfs_init_dummy_trans(&trans); |
faa2dbf0 JB |
141 | |
142 | key.objectid = bytenr; | |
143 | key.type = BTRFS_EXTENT_ITEM_KEY; | |
144 | key.offset = num_bytes; | |
145 | ||
146 | path = btrfs_alloc_path(); | |
147 | if (!path) { | |
148 | test_msg("Couldn't allocate path\n"); | |
149 | return -ENOMEM; | |
150 | } | |
151 | path->leave_spinning = 1; | |
152 | ||
153 | ret = btrfs_search_slot(&trans, root, &key, path, -1, 1); | |
154 | if (ret) { | |
155 | test_msg("Didn't find our key %d\n", ret); | |
156 | btrfs_free_path(path); | |
157 | return ret; | |
158 | } | |
159 | btrfs_del_item(&trans, root, path); | |
160 | btrfs_free_path(path); | |
161 | return 0; | |
162 | } | |
163 | ||
164 | static int remove_extent_ref(struct btrfs_root *root, u64 bytenr, | |
165 | u64 num_bytes, u64 parent, u64 root_objectid) | |
166 | { | |
167 | struct btrfs_trans_handle trans; | |
168 | struct btrfs_extent_item *item; | |
169 | struct btrfs_path *path; | |
170 | struct btrfs_key key; | |
171 | u64 refs; | |
172 | int ret; | |
173 | ||
7c55ee0c | 174 | btrfs_init_dummy_trans(&trans); |
faa2dbf0 JB |
175 | |
176 | key.objectid = bytenr; | |
177 | key.type = BTRFS_EXTENT_ITEM_KEY; | |
178 | key.offset = num_bytes; | |
179 | ||
180 | path = btrfs_alloc_path(); | |
181 | if (!path) { | |
182 | test_msg("Couldn't allocate path\n"); | |
183 | return -ENOMEM; | |
184 | } | |
185 | ||
186 | path->leave_spinning = 1; | |
187 | ret = btrfs_search_slot(&trans, root, &key, path, 0, 1); | |
188 | if (ret) { | |
189 | test_msg("Couldn't find extent ref\n"); | |
190 | btrfs_free_path(path); | |
191 | return ret; | |
192 | } | |
193 | ||
194 | item = btrfs_item_ptr(path->nodes[0], path->slots[0], | |
195 | struct btrfs_extent_item); | |
196 | refs = btrfs_extent_refs(path->nodes[0], item); | |
197 | btrfs_set_extent_refs(path->nodes[0], item, refs - 1); | |
198 | btrfs_release_path(path); | |
199 | ||
200 | key.objectid = bytenr; | |
201 | if (parent) { | |
202 | key.type = BTRFS_SHARED_BLOCK_REF_KEY; | |
203 | key.offset = parent; | |
204 | } else { | |
205 | key.type = BTRFS_TREE_BLOCK_REF_KEY; | |
206 | key.offset = root_objectid; | |
207 | } | |
208 | ||
209 | ret = btrfs_search_slot(&trans, root, &key, path, -1, 1); | |
210 | if (ret) { | |
211 | test_msg("Couldn't find backref %d\n", ret); | |
212 | btrfs_free_path(path); | |
213 | return ret; | |
214 | } | |
215 | btrfs_del_item(&trans, root, path); | |
216 | btrfs_free_path(path); | |
217 | return ret; | |
218 | } | |
219 | ||
b9ef22de FX |
220 | static int test_no_shared_qgroup(struct btrfs_root *root, |
221 | u32 sectorsize, u32 nodesize) | |
faa2dbf0 JB |
222 | { |
223 | struct btrfs_trans_handle trans; | |
224 | struct btrfs_fs_info *fs_info = root->fs_info; | |
442244c9 QW |
225 | struct ulist *old_roots = NULL; |
226 | struct ulist *new_roots = NULL; | |
faa2dbf0 JB |
227 | int ret; |
228 | ||
7c55ee0c | 229 | btrfs_init_dummy_trans(&trans); |
faa2dbf0 JB |
230 | |
231 | test_msg("Qgroup basic add\n"); | |
4087cf24 | 232 | ret = btrfs_create_qgroup(NULL, fs_info, 5); |
faa2dbf0 JB |
233 | if (ret) { |
234 | test_msg("Couldn't create a qgroup %d\n", ret); | |
235 | return ret; | |
236 | } | |
237 | ||
442244c9 | 238 | /* |
01327610 | 239 | * Since the test trans doesn't have the complicated delayed refs, |
442244c9 QW |
240 | * we can only call btrfs_qgroup_account_extent() directly to test |
241 | * quota. | |
242 | */ | |
b9ef22de | 243 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
faa2dbf0 | 244 | if (ret) { |
442244c9 QW |
245 | ulist_free(old_roots); |
246 | test_msg("Couldn't find old roots: %d\n", ret); | |
faa2dbf0 JB |
247 | return ret; |
248 | } | |
249 | ||
b9ef22de | 250 | ret = insert_normal_tree_ref(root, nodesize, nodesize, 0, 5); |
faa2dbf0 JB |
251 | if (ret) |
252 | return ret; | |
253 | ||
b9ef22de | 254 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
faa2dbf0 | 255 | if (ret) { |
442244c9 QW |
256 | ulist_free(old_roots); |
257 | ulist_free(new_roots); | |
258 | test_msg("Couldn't find old roots: %d\n", ret); | |
259 | return ret; | |
260 | } | |
261 | ||
b9ef22de FX |
262 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
263 | nodesize, old_roots, new_roots); | |
442244c9 QW |
264 | if (ret) { |
265 | test_msg("Couldn't account space for a qgroup %d\n", ret); | |
faa2dbf0 JB |
266 | return ret; |
267 | } | |
268 | ||
b9ef22de | 269 | if (btrfs_verify_qgroup_counts(fs_info, 5, nodesize, nodesize)) { |
faa2dbf0 JB |
270 | test_msg("Qgroup counts didn't match expected values\n"); |
271 | return -EINVAL; | |
272 | } | |
442244c9 QW |
273 | old_roots = NULL; |
274 | new_roots = NULL; | |
275 | ||
b9ef22de | 276 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
442244c9 QW |
277 | if (ret) { |
278 | ulist_free(old_roots); | |
279 | test_msg("Couldn't find old roots: %d\n", ret); | |
280 | return ret; | |
281 | } | |
faa2dbf0 | 282 | |
b9ef22de | 283 | ret = remove_extent_item(root, nodesize, nodesize); |
faa2dbf0 JB |
284 | if (ret) |
285 | return -EINVAL; | |
286 | ||
b9ef22de | 287 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
faa2dbf0 | 288 | if (ret) { |
442244c9 QW |
289 | ulist_free(old_roots); |
290 | ulist_free(new_roots); | |
291 | test_msg("Couldn't find old roots: %d\n", ret); | |
292 | return ret; | |
faa2dbf0 JB |
293 | } |
294 | ||
b9ef22de FX |
295 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
296 | nodesize, old_roots, new_roots); | |
faa2dbf0 | 297 | if (ret) { |
442244c9 | 298 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
faa2dbf0 JB |
299 | return -EINVAL; |
300 | } | |
301 | ||
302 | if (btrfs_verify_qgroup_counts(fs_info, 5, 0, 0)) { | |
303 | test_msg("Qgroup counts didn't match expected values\n"); | |
304 | return -EINVAL; | |
305 | } | |
306 | ||
307 | return 0; | |
308 | } | |
309 | ||
310 | /* | |
311 | * Add a ref for two different roots to make sure the shared value comes out | |
312 | * right, also remove one of the roots and make sure the exclusive count is | |
313 | * adjusted properly. | |
314 | */ | |
b9ef22de FX |
315 | static int test_multiple_refs(struct btrfs_root *root, |
316 | u32 sectorsize, u32 nodesize) | |
faa2dbf0 JB |
317 | { |
318 | struct btrfs_trans_handle trans; | |
319 | struct btrfs_fs_info *fs_info = root->fs_info; | |
442244c9 QW |
320 | struct ulist *old_roots = NULL; |
321 | struct ulist *new_roots = NULL; | |
faa2dbf0 JB |
322 | int ret; |
323 | ||
7c55ee0c | 324 | btrfs_init_dummy_trans(&trans); |
faa2dbf0 JB |
325 | |
326 | test_msg("Qgroup multiple refs test\n"); | |
327 | ||
328 | /* We have 5 created already from the previous test */ | |
4087cf24 | 329 | ret = btrfs_create_qgroup(NULL, fs_info, 256); |
faa2dbf0 JB |
330 | if (ret) { |
331 | test_msg("Couldn't create a qgroup %d\n", ret); | |
332 | return ret; | |
333 | } | |
334 | ||
b9ef22de | 335 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
442244c9 QW |
336 | if (ret) { |
337 | ulist_free(old_roots); | |
338 | test_msg("Couldn't find old roots: %d\n", ret); | |
339 | return ret; | |
340 | } | |
341 | ||
b9ef22de | 342 | ret = insert_normal_tree_ref(root, nodesize, nodesize, 0, 5); |
faa2dbf0 JB |
343 | if (ret) |
344 | return ret; | |
345 | ||
b9ef22de | 346 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
faa2dbf0 | 347 | if (ret) { |
442244c9 QW |
348 | ulist_free(old_roots); |
349 | ulist_free(new_roots); | |
350 | test_msg("Couldn't find old roots: %d\n", ret); | |
faa2dbf0 JB |
351 | return ret; |
352 | } | |
353 | ||
b9ef22de FX |
354 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
355 | nodesize, old_roots, new_roots); | |
faa2dbf0 | 356 | if (ret) { |
442244c9 | 357 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
faa2dbf0 JB |
358 | return ret; |
359 | } | |
360 | ||
b9ef22de FX |
361 | if (btrfs_verify_qgroup_counts(fs_info, 5, |
362 | nodesize, nodesize)) { | |
faa2dbf0 JB |
363 | test_msg("Qgroup counts didn't match expected values\n"); |
364 | return -EINVAL; | |
365 | } | |
366 | ||
b9ef22de | 367 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
442244c9 QW |
368 | if (ret) { |
369 | ulist_free(old_roots); | |
370 | test_msg("Couldn't find old roots: %d\n", ret); | |
371 | return ret; | |
372 | } | |
373 | ||
b9ef22de | 374 | ret = add_tree_ref(root, nodesize, nodesize, 0, 256); |
faa2dbf0 JB |
375 | if (ret) |
376 | return ret; | |
377 | ||
b9ef22de | 378 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
faa2dbf0 | 379 | if (ret) { |
442244c9 QW |
380 | ulist_free(old_roots); |
381 | ulist_free(new_roots); | |
382 | test_msg("Couldn't find old roots: %d\n", ret); | |
faa2dbf0 JB |
383 | return ret; |
384 | } | |
385 | ||
b9ef22de FX |
386 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
387 | nodesize, old_roots, new_roots); | |
faa2dbf0 | 388 | if (ret) { |
442244c9 | 389 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
faa2dbf0 JB |
390 | return ret; |
391 | } | |
392 | ||
b9ef22de | 393 | if (btrfs_verify_qgroup_counts(fs_info, 5, nodesize, 0)) { |
faa2dbf0 JB |
394 | test_msg("Qgroup counts didn't match expected values\n"); |
395 | return -EINVAL; | |
396 | } | |
397 | ||
b9ef22de | 398 | if (btrfs_verify_qgroup_counts(fs_info, 256, nodesize, 0)) { |
faa2dbf0 JB |
399 | test_msg("Qgroup counts didn't match expected values\n"); |
400 | return -EINVAL; | |
401 | } | |
402 | ||
b9ef22de | 403 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
442244c9 QW |
404 | if (ret) { |
405 | ulist_free(old_roots); | |
406 | test_msg("Couldn't find old roots: %d\n", ret); | |
407 | return ret; | |
408 | } | |
409 | ||
b9ef22de | 410 | ret = remove_extent_ref(root, nodesize, nodesize, 0, 256); |
faa2dbf0 JB |
411 | if (ret) |
412 | return ret; | |
413 | ||
b9ef22de | 414 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
faa2dbf0 | 415 | if (ret) { |
442244c9 QW |
416 | ulist_free(old_roots); |
417 | ulist_free(new_roots); | |
418 | test_msg("Couldn't find old roots: %d\n", ret); | |
faa2dbf0 JB |
419 | return ret; |
420 | } | |
421 | ||
b9ef22de FX |
422 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
423 | nodesize, old_roots, new_roots); | |
faa2dbf0 | 424 | if (ret) { |
442244c9 | 425 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
faa2dbf0 JB |
426 | return ret; |
427 | } | |
428 | ||
429 | if (btrfs_verify_qgroup_counts(fs_info, 256, 0, 0)) { | |
430 | test_msg("Qgroup counts didn't match expected values\n"); | |
431 | return -EINVAL; | |
432 | } | |
433 | ||
b9ef22de | 434 | if (btrfs_verify_qgroup_counts(fs_info, 5, nodesize, nodesize)) { |
faa2dbf0 JB |
435 | test_msg("Qgroup counts didn't match expected values\n"); |
436 | return -EINVAL; | |
437 | } | |
438 | ||
439 | return 0; | |
440 | } | |
441 | ||
b9ef22de | 442 | int btrfs_test_qgroups(u32 sectorsize, u32 nodesize) |
faa2dbf0 JB |
443 | { |
444 | struct btrfs_root *root; | |
445 | struct btrfs_root *tmp_root; | |
446 | int ret = 0; | |
447 | ||
b9ef22de | 448 | root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
faa2dbf0 JB |
449 | if (IS_ERR(root)) { |
450 | test_msg("Couldn't allocate root\n"); | |
451 | return PTR_ERR(root); | |
452 | } | |
453 | ||
454 | root->fs_info = btrfs_alloc_dummy_fs_info(); | |
455 | if (!root->fs_info) { | |
456 | test_msg("Couldn't allocate dummy fs info\n"); | |
457 | ret = -ENOMEM; | |
458 | goto out; | |
459 | } | |
3f556f78 DS |
460 | /* We are using this root as our extent root */ |
461 | root->fs_info->extent_root = root; | |
462 | ||
463 | /* | |
464 | * Some of the paths we test assume we have a filled out fs_info, so we | |
465 | * just need to add the root in there so we don't panic. | |
466 | */ | |
467 | root->fs_info->tree_root = root; | |
468 | root->fs_info->quota_root = root; | |
469 | root->fs_info->quota_enabled = 1; | |
faa2dbf0 JB |
470 | |
471 | /* | |
472 | * Can't use bytenr 0, some things freak out | |
473 | * *cough*backref walking code*cough* | |
474 | */ | |
b9ef22de FX |
475 | root->node = alloc_test_extent_buffer(root->fs_info, nodesize, |
476 | nodesize); | |
faa2dbf0 JB |
477 | if (!root->node) { |
478 | test_msg("Couldn't allocate dummy buffer\n"); | |
479 | ret = -ENOMEM; | |
480 | goto out; | |
481 | } | |
b050f9f6 FM |
482 | btrfs_set_header_level(root->node, 0); |
483 | btrfs_set_header_nritems(root->node, 0); | |
b9ef22de | 484 | root->alloc_bytenr += 2 * nodesize; |
faa2dbf0 | 485 | |
b9ef22de | 486 | tmp_root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
faa2dbf0 JB |
487 | if (IS_ERR(tmp_root)) { |
488 | test_msg("Couldn't allocate a fs root\n"); | |
489 | ret = PTR_ERR(tmp_root); | |
490 | goto out; | |
491 | } | |
492 | ||
493 | tmp_root->root_key.objectid = 5; | |
494 | root->fs_info->fs_root = tmp_root; | |
495 | ret = btrfs_insert_fs_root(root->fs_info, tmp_root); | |
496 | if (ret) { | |
497 | test_msg("Couldn't insert fs root %d\n", ret); | |
498 | goto out; | |
499 | } | |
500 | ||
b9ef22de | 501 | tmp_root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
faa2dbf0 JB |
502 | if (IS_ERR(tmp_root)) { |
503 | test_msg("Couldn't allocate a fs root\n"); | |
504 | ret = PTR_ERR(tmp_root); | |
505 | goto out; | |
506 | } | |
507 | ||
508 | tmp_root->root_key.objectid = 256; | |
509 | ret = btrfs_insert_fs_root(root->fs_info, tmp_root); | |
510 | if (ret) { | |
511 | test_msg("Couldn't insert fs root %d\n", ret); | |
512 | goto out; | |
513 | } | |
514 | ||
faa2dbf0 | 515 | test_msg("Running qgroup tests\n"); |
b9ef22de | 516 | ret = test_no_shared_qgroup(root, sectorsize, nodesize); |
faa2dbf0 JB |
517 | if (ret) |
518 | goto out; | |
b9ef22de | 519 | ret = test_multiple_refs(root, sectorsize, nodesize); |
faa2dbf0 JB |
520 | out: |
521 | btrfs_free_dummy_root(root); | |
522 | return ret; | |
523 | } |