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"); | |
ef9f2db3 | 232 | ret = btrfs_create_qgroup(NULL, fs_info, BTRFS_FS_TREE_OBJECTID); |
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 | ||
ef9f2db3 FX |
250 | ret = insert_normal_tree_ref(root, nodesize, nodesize, 0, |
251 | BTRFS_FS_TREE_OBJECTID); | |
faa2dbf0 JB |
252 | if (ret) |
253 | return ret; | |
254 | ||
b9ef22de | 255 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
faa2dbf0 | 256 | if (ret) { |
442244c9 QW |
257 | ulist_free(old_roots); |
258 | ulist_free(new_roots); | |
259 | test_msg("Couldn't find old roots: %d\n", ret); | |
260 | return ret; | |
261 | } | |
262 | ||
b9ef22de FX |
263 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
264 | nodesize, old_roots, new_roots); | |
442244c9 QW |
265 | if (ret) { |
266 | test_msg("Couldn't account space for a qgroup %d\n", ret); | |
faa2dbf0 JB |
267 | return ret; |
268 | } | |
269 | ||
ef9f2db3 FX |
270 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, |
271 | nodesize, nodesize)) { | |
faa2dbf0 JB |
272 | test_msg("Qgroup counts didn't match expected values\n"); |
273 | return -EINVAL; | |
274 | } | |
442244c9 QW |
275 | old_roots = NULL; |
276 | new_roots = NULL; | |
277 | ||
b9ef22de | 278 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
442244c9 QW |
279 | if (ret) { |
280 | ulist_free(old_roots); | |
281 | test_msg("Couldn't find old roots: %d\n", ret); | |
282 | return ret; | |
283 | } | |
faa2dbf0 | 284 | |
b9ef22de | 285 | ret = remove_extent_item(root, nodesize, nodesize); |
faa2dbf0 JB |
286 | if (ret) |
287 | return -EINVAL; | |
288 | ||
b9ef22de | 289 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
faa2dbf0 | 290 | if (ret) { |
442244c9 QW |
291 | ulist_free(old_roots); |
292 | ulist_free(new_roots); | |
293 | test_msg("Couldn't find old roots: %d\n", ret); | |
294 | return ret; | |
faa2dbf0 JB |
295 | } |
296 | ||
b9ef22de FX |
297 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
298 | nodesize, old_roots, new_roots); | |
faa2dbf0 | 299 | if (ret) { |
442244c9 | 300 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
faa2dbf0 JB |
301 | return -EINVAL; |
302 | } | |
303 | ||
ef9f2db3 | 304 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, 0, 0)) { |
faa2dbf0 JB |
305 | test_msg("Qgroup counts didn't match expected values\n"); |
306 | return -EINVAL; | |
307 | } | |
308 | ||
309 | return 0; | |
310 | } | |
311 | ||
312 | /* | |
313 | * Add a ref for two different roots to make sure the shared value comes out | |
314 | * right, also remove one of the roots and make sure the exclusive count is | |
315 | * adjusted properly. | |
316 | */ | |
b9ef22de FX |
317 | static int test_multiple_refs(struct btrfs_root *root, |
318 | u32 sectorsize, u32 nodesize) | |
faa2dbf0 JB |
319 | { |
320 | struct btrfs_trans_handle trans; | |
321 | struct btrfs_fs_info *fs_info = root->fs_info; | |
442244c9 QW |
322 | struct ulist *old_roots = NULL; |
323 | struct ulist *new_roots = NULL; | |
faa2dbf0 JB |
324 | int ret; |
325 | ||
7c55ee0c | 326 | btrfs_init_dummy_trans(&trans); |
faa2dbf0 JB |
327 | |
328 | test_msg("Qgroup multiple refs test\n"); | |
329 | ||
ef9f2db3 FX |
330 | /* |
331 | * We have BTRFS_FS_TREE_OBJECTID created already from the | |
332 | * previous test. | |
333 | */ | |
334 | ret = btrfs_create_qgroup(NULL, fs_info, BTRFS_FIRST_FREE_OBJECTID); | |
faa2dbf0 JB |
335 | if (ret) { |
336 | test_msg("Couldn't create a qgroup %d\n", ret); | |
337 | return ret; | |
338 | } | |
339 | ||
b9ef22de | 340 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
442244c9 QW |
341 | if (ret) { |
342 | ulist_free(old_roots); | |
343 | test_msg("Couldn't find old roots: %d\n", ret); | |
344 | return ret; | |
345 | } | |
346 | ||
ef9f2db3 FX |
347 | ret = insert_normal_tree_ref(root, nodesize, nodesize, 0, |
348 | BTRFS_FS_TREE_OBJECTID); | |
faa2dbf0 JB |
349 | if (ret) |
350 | return ret; | |
351 | ||
b9ef22de | 352 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
faa2dbf0 | 353 | if (ret) { |
442244c9 QW |
354 | ulist_free(old_roots); |
355 | ulist_free(new_roots); | |
356 | test_msg("Couldn't find old roots: %d\n", ret); | |
faa2dbf0 JB |
357 | return ret; |
358 | } | |
359 | ||
b9ef22de FX |
360 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
361 | nodesize, old_roots, new_roots); | |
faa2dbf0 | 362 | if (ret) { |
442244c9 | 363 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
faa2dbf0 JB |
364 | return ret; |
365 | } | |
366 | ||
ef9f2db3 | 367 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, |
b9ef22de | 368 | nodesize, nodesize)) { |
faa2dbf0 JB |
369 | test_msg("Qgroup counts didn't match expected values\n"); |
370 | return -EINVAL; | |
371 | } | |
372 | ||
b9ef22de | 373 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
442244c9 QW |
374 | if (ret) { |
375 | ulist_free(old_roots); | |
376 | test_msg("Couldn't find old roots: %d\n", ret); | |
377 | return ret; | |
378 | } | |
379 | ||
ef9f2db3 FX |
380 | ret = add_tree_ref(root, nodesize, nodesize, 0, |
381 | BTRFS_FIRST_FREE_OBJECTID); | |
faa2dbf0 JB |
382 | if (ret) |
383 | return ret; | |
384 | ||
b9ef22de | 385 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
faa2dbf0 | 386 | if (ret) { |
442244c9 QW |
387 | ulist_free(old_roots); |
388 | ulist_free(new_roots); | |
389 | test_msg("Couldn't find old roots: %d\n", ret); | |
faa2dbf0 JB |
390 | return ret; |
391 | } | |
392 | ||
b9ef22de FX |
393 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
394 | nodesize, old_roots, new_roots); | |
faa2dbf0 | 395 | if (ret) { |
442244c9 | 396 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
faa2dbf0 JB |
397 | return ret; |
398 | } | |
399 | ||
ef9f2db3 FX |
400 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, |
401 | nodesize, 0)) { | |
faa2dbf0 JB |
402 | test_msg("Qgroup counts didn't match expected values\n"); |
403 | return -EINVAL; | |
404 | } | |
405 | ||
ef9f2db3 FX |
406 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FIRST_FREE_OBJECTID, |
407 | nodesize, 0)) { | |
faa2dbf0 JB |
408 | test_msg("Qgroup counts didn't match expected values\n"); |
409 | return -EINVAL; | |
410 | } | |
411 | ||
b9ef22de | 412 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
442244c9 QW |
413 | if (ret) { |
414 | ulist_free(old_roots); | |
415 | test_msg("Couldn't find old roots: %d\n", ret); | |
416 | return ret; | |
417 | } | |
418 | ||
ef9f2db3 FX |
419 | ret = remove_extent_ref(root, nodesize, nodesize, 0, |
420 | BTRFS_FIRST_FREE_OBJECTID); | |
faa2dbf0 JB |
421 | if (ret) |
422 | return ret; | |
423 | ||
b9ef22de | 424 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
faa2dbf0 | 425 | if (ret) { |
442244c9 QW |
426 | ulist_free(old_roots); |
427 | ulist_free(new_roots); | |
428 | test_msg("Couldn't find old roots: %d\n", ret); | |
faa2dbf0 JB |
429 | return ret; |
430 | } | |
431 | ||
b9ef22de FX |
432 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
433 | nodesize, old_roots, new_roots); | |
faa2dbf0 | 434 | if (ret) { |
442244c9 | 435 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
faa2dbf0 JB |
436 | return ret; |
437 | } | |
438 | ||
ef9f2db3 FX |
439 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FIRST_FREE_OBJECTID, |
440 | 0, 0)) { | |
faa2dbf0 JB |
441 | test_msg("Qgroup counts didn't match expected values\n"); |
442 | return -EINVAL; | |
443 | } | |
444 | ||
ef9f2db3 FX |
445 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, |
446 | nodesize, nodesize)) { | |
faa2dbf0 JB |
447 | test_msg("Qgroup counts didn't match expected values\n"); |
448 | return -EINVAL; | |
449 | } | |
450 | ||
451 | return 0; | |
452 | } | |
453 | ||
b9ef22de | 454 | int btrfs_test_qgroups(u32 sectorsize, u32 nodesize) |
faa2dbf0 | 455 | { |
7c0260ee | 456 | struct btrfs_fs_info *fs_info = NULL; |
faa2dbf0 JB |
457 | struct btrfs_root *root; |
458 | struct btrfs_root *tmp_root; | |
459 | int ret = 0; | |
460 | ||
da17066c | 461 | fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize); |
7c0260ee JM |
462 | if (!fs_info) { |
463 | test_msg("Couldn't allocate dummy fs info\n"); | |
464 | return -ENOMEM; | |
faa2dbf0 JB |
465 | } |
466 | ||
da17066c | 467 | root = btrfs_alloc_dummy_root(fs_info); |
7c0260ee JM |
468 | if (IS_ERR(root)) { |
469 | test_msg("Couldn't allocate root\n"); | |
470 | ret = PTR_ERR(root); | |
faa2dbf0 JB |
471 | goto out; |
472 | } | |
7c0260ee | 473 | |
3f556f78 DS |
474 | /* We are using this root as our extent root */ |
475 | root->fs_info->extent_root = root; | |
476 | ||
477 | /* | |
478 | * Some of the paths we test assume we have a filled out fs_info, so we | |
479 | * just need to add the root in there so we don't panic. | |
480 | */ | |
481 | root->fs_info->tree_root = root; | |
482 | root->fs_info->quota_root = root; | |
afcdd129 | 483 | set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags); |
faa2dbf0 JB |
484 | |
485 | /* | |
486 | * Can't use bytenr 0, some things freak out | |
487 | * *cough*backref walking code*cough* | |
488 | */ | |
da17066c | 489 | root->node = alloc_test_extent_buffer(root->fs_info, nodesize); |
faa2dbf0 JB |
490 | if (!root->node) { |
491 | test_msg("Couldn't allocate dummy buffer\n"); | |
492 | ret = -ENOMEM; | |
493 | goto out; | |
494 | } | |
b050f9f6 FM |
495 | btrfs_set_header_level(root->node, 0); |
496 | btrfs_set_header_nritems(root->node, 0); | |
b9ef22de | 497 | root->alloc_bytenr += 2 * nodesize; |
faa2dbf0 | 498 | |
da17066c | 499 | tmp_root = btrfs_alloc_dummy_root(fs_info); |
faa2dbf0 JB |
500 | if (IS_ERR(tmp_root)) { |
501 | test_msg("Couldn't allocate a fs root\n"); | |
502 | ret = PTR_ERR(tmp_root); | |
503 | goto out; | |
504 | } | |
505 | ||
ef9f2db3 | 506 | tmp_root->root_key.objectid = BTRFS_FS_TREE_OBJECTID; |
faa2dbf0 JB |
507 | root->fs_info->fs_root = tmp_root; |
508 | ret = btrfs_insert_fs_root(root->fs_info, tmp_root); | |
509 | if (ret) { | |
510 | test_msg("Couldn't insert fs root %d\n", ret); | |
511 | goto out; | |
512 | } | |
513 | ||
da17066c | 514 | tmp_root = btrfs_alloc_dummy_root(fs_info); |
faa2dbf0 JB |
515 | if (IS_ERR(tmp_root)) { |
516 | test_msg("Couldn't allocate a fs root\n"); | |
517 | ret = PTR_ERR(tmp_root); | |
518 | goto out; | |
519 | } | |
520 | ||
ef9f2db3 | 521 | tmp_root->root_key.objectid = BTRFS_FIRST_FREE_OBJECTID; |
faa2dbf0 JB |
522 | ret = btrfs_insert_fs_root(root->fs_info, tmp_root); |
523 | if (ret) { | |
524 | test_msg("Couldn't insert fs root %d\n", ret); | |
525 | goto out; | |
526 | } | |
527 | ||
faa2dbf0 | 528 | test_msg("Running qgroup tests\n"); |
b9ef22de | 529 | ret = test_no_shared_qgroup(root, sectorsize, nodesize); |
faa2dbf0 JB |
530 | if (ret) |
531 | goto out; | |
b9ef22de | 532 | ret = test_multiple_refs(root, sectorsize, nodesize); |
faa2dbf0 JB |
533 | out: |
534 | btrfs_free_dummy_root(root); | |
7c0260ee | 535 | btrfs_free_dummy_fs_info(fs_info); |
faa2dbf0 JB |
536 | return ret; |
537 | } |