.. | .. |
---|
10 | 10 | #include "locking.h" |
---|
11 | 11 | #include "free-space-tree.h" |
---|
12 | 12 | #include "transaction.h" |
---|
| 13 | +#include "block-group.h" |
---|
13 | 14 | |
---|
14 | 15 | static int __add_block_group_free_space(struct btrfs_trans_handle *trans, |
---|
15 | | - struct btrfs_block_group_cache *block_group, |
---|
| 16 | + struct btrfs_block_group *block_group, |
---|
16 | 17 | struct btrfs_path *path); |
---|
17 | 18 | |
---|
18 | | -void set_free_space_tree_thresholds(struct btrfs_block_group_cache *cache) |
---|
| 19 | +void set_free_space_tree_thresholds(struct btrfs_block_group *cache) |
---|
19 | 20 | { |
---|
20 | 21 | u32 bitmap_range; |
---|
21 | 22 | size_t bitmap_size; |
---|
22 | 23 | u64 num_bitmaps, total_bitmap_size; |
---|
| 24 | + |
---|
| 25 | + if (WARN_ON(cache->length == 0)) |
---|
| 26 | + btrfs_warn(cache->fs_info, "block group %llu length is zero", |
---|
| 27 | + cache->start); |
---|
23 | 28 | |
---|
24 | 29 | /* |
---|
25 | 30 | * We convert to bitmaps when the disk space required for using extents |
---|
26 | 31 | * exceeds that required for using bitmaps. |
---|
27 | 32 | */ |
---|
28 | 33 | bitmap_range = cache->fs_info->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS; |
---|
29 | | - num_bitmaps = div_u64(cache->key.offset + bitmap_range - 1, |
---|
30 | | - bitmap_range); |
---|
| 34 | + num_bitmaps = div_u64(cache->length + bitmap_range - 1, bitmap_range); |
---|
31 | 35 | bitmap_size = sizeof(struct btrfs_item) + BTRFS_FREE_SPACE_BITMAP_SIZE; |
---|
32 | 36 | total_bitmap_size = num_bitmaps * bitmap_size; |
---|
33 | 37 | cache->bitmap_high_thresh = div_u64(total_bitmap_size, |
---|
.. | .. |
---|
44 | 48 | } |
---|
45 | 49 | |
---|
46 | 50 | static int add_new_free_space_info(struct btrfs_trans_handle *trans, |
---|
47 | | - struct btrfs_block_group_cache *block_group, |
---|
| 51 | + struct btrfs_block_group *block_group, |
---|
48 | 52 | struct btrfs_path *path) |
---|
49 | 53 | { |
---|
50 | 54 | struct btrfs_root *root = trans->fs_info->free_space_root; |
---|
.. | .. |
---|
53 | 57 | struct extent_buffer *leaf; |
---|
54 | 58 | int ret; |
---|
55 | 59 | |
---|
56 | | - key.objectid = block_group->key.objectid; |
---|
| 60 | + key.objectid = block_group->start; |
---|
57 | 61 | key.type = BTRFS_FREE_SPACE_INFO_KEY; |
---|
58 | | - key.offset = block_group->key.offset; |
---|
| 62 | + key.offset = block_group->length; |
---|
59 | 63 | |
---|
60 | 64 | ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(*info)); |
---|
61 | 65 | if (ret) |
---|
.. | .. |
---|
74 | 78 | return ret; |
---|
75 | 79 | } |
---|
76 | 80 | |
---|
77 | | -struct btrfs_free_space_info * |
---|
78 | | -search_free_space_info(struct btrfs_trans_handle *trans, |
---|
79 | | - struct btrfs_fs_info *fs_info, |
---|
80 | | - struct btrfs_block_group_cache *block_group, |
---|
81 | | - struct btrfs_path *path, int cow) |
---|
| 81 | +EXPORT_FOR_TESTS |
---|
| 82 | +struct btrfs_free_space_info *search_free_space_info( |
---|
| 83 | + struct btrfs_trans_handle *trans, |
---|
| 84 | + struct btrfs_block_group *block_group, |
---|
| 85 | + struct btrfs_path *path, int cow) |
---|
82 | 86 | { |
---|
| 87 | + struct btrfs_fs_info *fs_info = block_group->fs_info; |
---|
83 | 88 | struct btrfs_root *root = fs_info->free_space_root; |
---|
84 | 89 | struct btrfs_key key; |
---|
85 | 90 | int ret; |
---|
86 | 91 | |
---|
87 | | - key.objectid = block_group->key.objectid; |
---|
| 92 | + key.objectid = block_group->start; |
---|
88 | 93 | key.type = BTRFS_FREE_SPACE_INFO_KEY; |
---|
89 | | - key.offset = block_group->key.offset; |
---|
| 94 | + key.offset = block_group->length; |
---|
90 | 95 | |
---|
91 | 96 | ret = btrfs_search_slot(trans, root, &key, path, 0, cow); |
---|
92 | 97 | if (ret < 0) |
---|
93 | 98 | return ERR_PTR(ret); |
---|
94 | 99 | if (ret != 0) { |
---|
95 | 100 | btrfs_warn(fs_info, "missing free space info for %llu", |
---|
96 | | - block_group->key.objectid); |
---|
| 101 | + block_group->start); |
---|
97 | 102 | ASSERT(0); |
---|
98 | 103 | return ERR_PTR(-ENOENT); |
---|
99 | 104 | } |
---|
.. | .. |
---|
176 | 181 | } |
---|
177 | 182 | } |
---|
178 | 183 | |
---|
| 184 | +EXPORT_FOR_TESTS |
---|
179 | 185 | int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans, |
---|
180 | | - struct btrfs_block_group_cache *block_group, |
---|
| 186 | + struct btrfs_block_group *block_group, |
---|
181 | 187 | struct btrfs_path *path) |
---|
182 | 188 | { |
---|
183 | 189 | struct btrfs_fs_info *fs_info = trans->fs_info; |
---|
.. | .. |
---|
194 | 200 | int done = 0, nr; |
---|
195 | 201 | int ret; |
---|
196 | 202 | |
---|
197 | | - bitmap_size = free_space_bitmap_size(block_group->key.offset, |
---|
| 203 | + bitmap_size = free_space_bitmap_size(block_group->length, |
---|
198 | 204 | fs_info->sectorsize); |
---|
199 | 205 | bitmap = alloc_bitmap(bitmap_size); |
---|
200 | 206 | if (!bitmap) { |
---|
.. | .. |
---|
202 | 208 | goto out; |
---|
203 | 209 | } |
---|
204 | 210 | |
---|
205 | | - start = block_group->key.objectid; |
---|
206 | | - end = block_group->key.objectid + block_group->key.offset; |
---|
| 211 | + start = block_group->start; |
---|
| 212 | + end = block_group->start + block_group->length; |
---|
207 | 213 | |
---|
208 | 214 | key.objectid = end - 1; |
---|
209 | 215 | key.type = (u8)-1; |
---|
.. | .. |
---|
221 | 227 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1); |
---|
222 | 228 | |
---|
223 | 229 | if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) { |
---|
224 | | - ASSERT(found_key.objectid == block_group->key.objectid); |
---|
225 | | - ASSERT(found_key.offset == block_group->key.offset); |
---|
| 230 | + ASSERT(found_key.objectid == block_group->start); |
---|
| 231 | + ASSERT(found_key.offset == block_group->length); |
---|
226 | 232 | done = 1; |
---|
227 | 233 | break; |
---|
228 | 234 | } else if (found_key.type == BTRFS_FREE_SPACE_EXTENT_KEY) { |
---|
.. | .. |
---|
252 | 258 | btrfs_release_path(path); |
---|
253 | 259 | } |
---|
254 | 260 | |
---|
255 | | - info = search_free_space_info(trans, fs_info, block_group, path, 1); |
---|
| 261 | + info = search_free_space_info(trans, block_group, path, 1); |
---|
256 | 262 | if (IS_ERR(info)) { |
---|
257 | 263 | ret = PTR_ERR(info); |
---|
258 | 264 | goto out; |
---|
.. | .. |
---|
268 | 274 | if (extent_count != expected_extent_count) { |
---|
269 | 275 | btrfs_err(fs_info, |
---|
270 | 276 | "incorrect extent count for %llu; counted %u, expected %u", |
---|
271 | | - block_group->key.objectid, extent_count, |
---|
| 277 | + block_group->start, extent_count, |
---|
272 | 278 | expected_extent_count); |
---|
273 | 279 | ASSERT(0); |
---|
274 | 280 | ret = -EIO; |
---|
.. | .. |
---|
315 | 321 | return ret; |
---|
316 | 322 | } |
---|
317 | 323 | |
---|
| 324 | +EXPORT_FOR_TESTS |
---|
318 | 325 | int convert_free_space_to_extents(struct btrfs_trans_handle *trans, |
---|
319 | | - struct btrfs_block_group_cache *block_group, |
---|
| 326 | + struct btrfs_block_group *block_group, |
---|
320 | 327 | struct btrfs_path *path) |
---|
321 | 328 | { |
---|
322 | 329 | struct btrfs_fs_info *fs_info = trans->fs_info; |
---|
.. | .. |
---|
332 | 339 | int done = 0, nr; |
---|
333 | 340 | int ret; |
---|
334 | 341 | |
---|
335 | | - bitmap_size = free_space_bitmap_size(block_group->key.offset, |
---|
| 342 | + bitmap_size = free_space_bitmap_size(block_group->length, |
---|
336 | 343 | fs_info->sectorsize); |
---|
337 | 344 | bitmap = alloc_bitmap(bitmap_size); |
---|
338 | 345 | if (!bitmap) { |
---|
.. | .. |
---|
340 | 347 | goto out; |
---|
341 | 348 | } |
---|
342 | 349 | |
---|
343 | | - start = block_group->key.objectid; |
---|
344 | | - end = block_group->key.objectid + block_group->key.offset; |
---|
| 350 | + start = block_group->start; |
---|
| 351 | + end = block_group->start + block_group->length; |
---|
345 | 352 | |
---|
346 | 353 | key.objectid = end - 1; |
---|
347 | 354 | key.type = (u8)-1; |
---|
.. | .. |
---|
359 | 366 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1); |
---|
360 | 367 | |
---|
361 | 368 | if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) { |
---|
362 | | - ASSERT(found_key.objectid == block_group->key.objectid); |
---|
363 | | - ASSERT(found_key.offset == block_group->key.offset); |
---|
| 369 | + ASSERT(found_key.objectid == block_group->start); |
---|
| 370 | + ASSERT(found_key.offset == block_group->length); |
---|
364 | 371 | done = 1; |
---|
365 | 372 | break; |
---|
366 | 373 | } else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) { |
---|
.. | .. |
---|
396 | 403 | btrfs_release_path(path); |
---|
397 | 404 | } |
---|
398 | 405 | |
---|
399 | | - info = search_free_space_info(trans, fs_info, block_group, path, 1); |
---|
| 406 | + info = search_free_space_info(trans, block_group, path, 1); |
---|
400 | 407 | if (IS_ERR(info)) { |
---|
401 | 408 | ret = PTR_ERR(info); |
---|
402 | 409 | goto out; |
---|
.. | .. |
---|
409 | 416 | btrfs_mark_buffer_dirty(leaf); |
---|
410 | 417 | btrfs_release_path(path); |
---|
411 | 418 | |
---|
412 | | - nrbits = div_u64(block_group->key.offset, block_group->fs_info->sectorsize); |
---|
| 419 | + nrbits = div_u64(block_group->length, block_group->fs_info->sectorsize); |
---|
413 | 420 | start_bit = find_next_bit_le(bitmap, nrbits, 0); |
---|
414 | 421 | |
---|
415 | 422 | while (start_bit < nrbits) { |
---|
.. | .. |
---|
433 | 440 | if (extent_count != expected_extent_count) { |
---|
434 | 441 | btrfs_err(fs_info, |
---|
435 | 442 | "incorrect extent count for %llu; counted %u, expected %u", |
---|
436 | | - block_group->key.objectid, extent_count, |
---|
| 443 | + block_group->start, extent_count, |
---|
437 | 444 | expected_extent_count); |
---|
438 | 445 | ASSERT(0); |
---|
439 | 446 | ret = -EIO; |
---|
.. | .. |
---|
449 | 456 | } |
---|
450 | 457 | |
---|
451 | 458 | static int update_free_space_extent_count(struct btrfs_trans_handle *trans, |
---|
452 | | - struct btrfs_block_group_cache *block_group, |
---|
| 459 | + struct btrfs_block_group *block_group, |
---|
453 | 460 | struct btrfs_path *path, |
---|
454 | 461 | int new_extents) |
---|
455 | 462 | { |
---|
.. | .. |
---|
461 | 468 | if (new_extents == 0) |
---|
462 | 469 | return 0; |
---|
463 | 470 | |
---|
464 | | - info = search_free_space_info(trans, trans->fs_info, block_group, path, |
---|
465 | | - 1); |
---|
| 471 | + info = search_free_space_info(trans, block_group, path, 1); |
---|
466 | 472 | if (IS_ERR(info)) { |
---|
467 | 473 | ret = PTR_ERR(info); |
---|
468 | 474 | goto out; |
---|
.. | .. |
---|
487 | 493 | return ret; |
---|
488 | 494 | } |
---|
489 | 495 | |
---|
490 | | -int free_space_test_bit(struct btrfs_block_group_cache *block_group, |
---|
| 496 | +EXPORT_FOR_TESTS |
---|
| 497 | +int free_space_test_bit(struct btrfs_block_group *block_group, |
---|
491 | 498 | struct btrfs_path *path, u64 offset) |
---|
492 | 499 | { |
---|
493 | 500 | struct extent_buffer *leaf; |
---|
.. | .. |
---|
509 | 516 | return !!extent_buffer_test_bit(leaf, ptr, i); |
---|
510 | 517 | } |
---|
511 | 518 | |
---|
512 | | -static void free_space_set_bits(struct btrfs_block_group_cache *block_group, |
---|
| 519 | +static void free_space_set_bits(struct btrfs_block_group *block_group, |
---|
513 | 520 | struct btrfs_path *path, u64 *start, u64 *size, |
---|
514 | 521 | int bit) |
---|
515 | 522 | { |
---|
.. | .. |
---|
577 | 584 | * the bitmap. |
---|
578 | 585 | */ |
---|
579 | 586 | static int modify_free_space_bitmap(struct btrfs_trans_handle *trans, |
---|
580 | | - struct btrfs_block_group_cache *block_group, |
---|
| 587 | + struct btrfs_block_group *block_group, |
---|
581 | 588 | struct btrfs_path *path, |
---|
582 | 589 | u64 start, u64 size, int remove) |
---|
583 | 590 | { |
---|
.. | .. |
---|
593 | 600 | * Read the bit for the block immediately before the extent of space if |
---|
594 | 601 | * that block is within the block group. |
---|
595 | 602 | */ |
---|
596 | | - if (start > block_group->key.objectid) { |
---|
| 603 | + if (start > block_group->start) { |
---|
597 | 604 | u64 prev_block = start - block_group->fs_info->sectorsize; |
---|
598 | 605 | |
---|
599 | 606 | key.objectid = prev_block; |
---|
.. | .. |
---|
645 | 652 | * Read the bit for the block immediately after the extent of space if |
---|
646 | 653 | * that block is within the block group. |
---|
647 | 654 | */ |
---|
648 | | - if (end < block_group->key.objectid + block_group->key.offset) { |
---|
| 655 | + if (end < block_group->start + block_group->length) { |
---|
649 | 656 | /* The next block may be in the next bitmap. */ |
---|
650 | 657 | btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); |
---|
651 | 658 | if (end >= key.objectid + key.offset) { |
---|
.. | .. |
---|
690 | 697 | } |
---|
691 | 698 | |
---|
692 | 699 | static int remove_free_space_extent(struct btrfs_trans_handle *trans, |
---|
693 | | - struct btrfs_block_group_cache *block_group, |
---|
| 700 | + struct btrfs_block_group *block_group, |
---|
694 | 701 | struct btrfs_path *path, |
---|
695 | 702 | u64 start, u64 size) |
---|
696 | 703 | { |
---|
.. | .. |
---|
775 | 782 | return ret; |
---|
776 | 783 | } |
---|
777 | 784 | |
---|
| 785 | +EXPORT_FOR_TESTS |
---|
778 | 786 | int __remove_from_free_space_tree(struct btrfs_trans_handle *trans, |
---|
779 | | - struct btrfs_block_group_cache *block_group, |
---|
| 787 | + struct btrfs_block_group *block_group, |
---|
780 | 788 | struct btrfs_path *path, u64 start, u64 size) |
---|
781 | 789 | { |
---|
782 | 790 | struct btrfs_free_space_info *info; |
---|
.. | .. |
---|
789 | 797 | return ret; |
---|
790 | 798 | } |
---|
791 | 799 | |
---|
792 | | - info = search_free_space_info(NULL, trans->fs_info, block_group, path, |
---|
793 | | - 0); |
---|
| 800 | + info = search_free_space_info(NULL, block_group, path, 0); |
---|
794 | 801 | if (IS_ERR(info)) |
---|
795 | 802 | return PTR_ERR(info); |
---|
796 | 803 | flags = btrfs_free_space_flags(path->nodes[0], info); |
---|
.. | .. |
---|
808 | 815 | int remove_from_free_space_tree(struct btrfs_trans_handle *trans, |
---|
809 | 816 | u64 start, u64 size) |
---|
810 | 817 | { |
---|
811 | | - struct btrfs_block_group_cache *block_group; |
---|
| 818 | + struct btrfs_block_group *block_group; |
---|
812 | 819 | struct btrfs_path *path; |
---|
813 | 820 | int ret; |
---|
814 | 821 | |
---|
.. | .. |
---|
842 | 849 | } |
---|
843 | 850 | |
---|
844 | 851 | static int add_free_space_extent(struct btrfs_trans_handle *trans, |
---|
845 | | - struct btrfs_block_group_cache *block_group, |
---|
| 852 | + struct btrfs_block_group *block_group, |
---|
846 | 853 | struct btrfs_path *path, |
---|
847 | 854 | u64 start, u64 size) |
---|
848 | 855 | { |
---|
.. | .. |
---|
876 | 883 | new_key.offset = size; |
---|
877 | 884 | |
---|
878 | 885 | /* Search for a neighbor on the left. */ |
---|
879 | | - if (start == block_group->key.objectid) |
---|
| 886 | + if (start == block_group->start) |
---|
880 | 887 | goto right; |
---|
881 | 888 | key.objectid = start - 1; |
---|
882 | 889 | key.type = (u8)-1; |
---|
.. | .. |
---|
896 | 903 | |
---|
897 | 904 | found_start = key.objectid; |
---|
898 | 905 | found_end = key.objectid + key.offset; |
---|
899 | | - ASSERT(found_start >= block_group->key.objectid && |
---|
900 | | - found_end > block_group->key.objectid); |
---|
| 906 | + ASSERT(found_start >= block_group->start && |
---|
| 907 | + found_end > block_group->start); |
---|
901 | 908 | ASSERT(found_start < start && found_end <= start); |
---|
902 | 909 | |
---|
903 | 910 | /* |
---|
.. | .. |
---|
916 | 923 | |
---|
917 | 924 | right: |
---|
918 | 925 | /* Search for a neighbor on the right. */ |
---|
919 | | - if (end == block_group->key.objectid + block_group->key.offset) |
---|
| 926 | + if (end == block_group->start + block_group->length) |
---|
920 | 927 | goto insert; |
---|
921 | 928 | key.objectid = end; |
---|
922 | 929 | key.type = (u8)-1; |
---|
.. | .. |
---|
936 | 943 | |
---|
937 | 944 | found_start = key.objectid; |
---|
938 | 945 | found_end = key.objectid + key.offset; |
---|
939 | | - ASSERT(found_start >= block_group->key.objectid && |
---|
940 | | - found_end > block_group->key.objectid); |
---|
| 946 | + ASSERT(found_start >= block_group->start && |
---|
| 947 | + found_end > block_group->start); |
---|
941 | 948 | ASSERT((found_start < start && found_end <= start) || |
---|
942 | 949 | (found_start >= end && found_end > end)); |
---|
943 | 950 | |
---|
.. | .. |
---|
968 | 975 | return ret; |
---|
969 | 976 | } |
---|
970 | 977 | |
---|
| 978 | +EXPORT_FOR_TESTS |
---|
971 | 979 | int __add_to_free_space_tree(struct btrfs_trans_handle *trans, |
---|
972 | | - struct btrfs_block_group_cache *block_group, |
---|
| 980 | + struct btrfs_block_group *block_group, |
---|
973 | 981 | struct btrfs_path *path, u64 start, u64 size) |
---|
974 | 982 | { |
---|
975 | | - struct btrfs_fs_info *fs_info = trans->fs_info; |
---|
976 | 983 | struct btrfs_free_space_info *info; |
---|
977 | 984 | u32 flags; |
---|
978 | 985 | int ret; |
---|
.. | .. |
---|
983 | 990 | return ret; |
---|
984 | 991 | } |
---|
985 | 992 | |
---|
986 | | - info = search_free_space_info(NULL, fs_info, block_group, path, 0); |
---|
| 993 | + info = search_free_space_info(NULL, block_group, path, 0); |
---|
987 | 994 | if (IS_ERR(info)) |
---|
988 | 995 | return PTR_ERR(info); |
---|
989 | 996 | flags = btrfs_free_space_flags(path->nodes[0], info); |
---|
.. | .. |
---|
1001 | 1008 | int add_to_free_space_tree(struct btrfs_trans_handle *trans, |
---|
1002 | 1009 | u64 start, u64 size) |
---|
1003 | 1010 | { |
---|
1004 | | - struct btrfs_block_group_cache *block_group; |
---|
| 1011 | + struct btrfs_block_group *block_group; |
---|
1005 | 1012 | struct btrfs_path *path; |
---|
1006 | 1013 | int ret; |
---|
1007 | 1014 | |
---|
.. | .. |
---|
1039 | 1046 | * through the normal add/remove hooks. |
---|
1040 | 1047 | */ |
---|
1041 | 1048 | static int populate_free_space_tree(struct btrfs_trans_handle *trans, |
---|
1042 | | - struct btrfs_block_group_cache *block_group) |
---|
| 1049 | + struct btrfs_block_group *block_group) |
---|
1043 | 1050 | { |
---|
1044 | 1051 | struct btrfs_root *extent_root = trans->fs_info->extent_root; |
---|
1045 | 1052 | struct btrfs_path *path, *path2; |
---|
.. | .. |
---|
1071 | 1078 | * BLOCK_GROUP_ITEM, so an extent may precede the block group that it's |
---|
1072 | 1079 | * contained in. |
---|
1073 | 1080 | */ |
---|
1074 | | - key.objectid = block_group->key.objectid; |
---|
| 1081 | + key.objectid = block_group->start; |
---|
1075 | 1082 | key.type = BTRFS_EXTENT_ITEM_KEY; |
---|
1076 | 1083 | key.offset = 0; |
---|
1077 | 1084 | |
---|
.. | .. |
---|
1080 | 1087 | goto out_locked; |
---|
1081 | 1088 | ASSERT(ret == 0); |
---|
1082 | 1089 | |
---|
1083 | | - start = block_group->key.objectid; |
---|
1084 | | - end = block_group->key.objectid + block_group->key.offset; |
---|
| 1090 | + start = block_group->start; |
---|
| 1091 | + end = block_group->start + block_group->length; |
---|
1085 | 1092 | while (1) { |
---|
1086 | 1093 | btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); |
---|
1087 | 1094 | |
---|
.. | .. |
---|
1105 | 1112 | else |
---|
1106 | 1113 | start += key.offset; |
---|
1107 | 1114 | } else if (key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) { |
---|
1108 | | - if (key.objectid != block_group->key.objectid) |
---|
| 1115 | + if (key.objectid != block_group->start) |
---|
1109 | 1116 | break; |
---|
1110 | 1117 | } |
---|
1111 | 1118 | |
---|
.. | .. |
---|
1136 | 1143 | struct btrfs_trans_handle *trans; |
---|
1137 | 1144 | struct btrfs_root *tree_root = fs_info->tree_root; |
---|
1138 | 1145 | struct btrfs_root *free_space_root; |
---|
1139 | | - struct btrfs_block_group_cache *block_group; |
---|
| 1146 | + struct btrfs_block_group *block_group; |
---|
1140 | 1147 | struct rb_node *node; |
---|
1141 | 1148 | int ret; |
---|
1142 | 1149 | |
---|
.. | .. |
---|
1145 | 1152 | return PTR_ERR(trans); |
---|
1146 | 1153 | |
---|
1147 | 1154 | set_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags); |
---|
1148 | | - free_space_root = btrfs_create_tree(trans, fs_info, |
---|
| 1155 | + set_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags); |
---|
| 1156 | + free_space_root = btrfs_create_tree(trans, |
---|
1149 | 1157 | BTRFS_FREE_SPACE_TREE_OBJECTID); |
---|
1150 | 1158 | if (IS_ERR(free_space_root)) { |
---|
1151 | 1159 | ret = PTR_ERR(free_space_root); |
---|
.. | .. |
---|
1155 | 1163 | |
---|
1156 | 1164 | node = rb_first(&fs_info->block_group_cache_tree); |
---|
1157 | 1165 | while (node) { |
---|
1158 | | - block_group = rb_entry(node, struct btrfs_block_group_cache, |
---|
| 1166 | + block_group = rb_entry(node, struct btrfs_block_group, |
---|
1159 | 1167 | cache_node); |
---|
1160 | 1168 | ret = populate_free_space_tree(trans, block_group); |
---|
1161 | 1169 | if (ret) |
---|
.. | .. |
---|
1166 | 1174 | btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE); |
---|
1167 | 1175 | btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID); |
---|
1168 | 1176 | clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags); |
---|
| 1177 | + ret = btrfs_commit_transaction(trans); |
---|
1169 | 1178 | |
---|
1170 | | - return btrfs_commit_transaction(trans); |
---|
| 1179 | + /* |
---|
| 1180 | + * Now that we've committed the transaction any reading of our commit |
---|
| 1181 | + * root will be safe, so we can cache from the free space tree now. |
---|
| 1182 | + */ |
---|
| 1183 | + clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags); |
---|
| 1184 | + return ret; |
---|
1171 | 1185 | |
---|
1172 | 1186 | abort: |
---|
1173 | 1187 | clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags); |
---|
| 1188 | + clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags); |
---|
1174 | 1189 | btrfs_abort_transaction(trans, ret); |
---|
1175 | 1190 | btrfs_end_transaction(trans); |
---|
1176 | 1191 | return ret; |
---|
.. | .. |
---|
1243 | 1258 | list_del(&free_space_root->dirty_list); |
---|
1244 | 1259 | |
---|
1245 | 1260 | btrfs_tree_lock(free_space_root->node); |
---|
1246 | | - clean_tree_block(fs_info, free_space_root->node); |
---|
| 1261 | + btrfs_clean_tree_block(free_space_root->node); |
---|
1247 | 1262 | btrfs_tree_unlock(free_space_root->node); |
---|
1248 | 1263 | btrfs_free_tree_block(trans, free_space_root, free_space_root->node, |
---|
1249 | 1264 | 0, 1); |
---|
1250 | 1265 | |
---|
1251 | | - free_extent_buffer(free_space_root->node); |
---|
1252 | | - free_extent_buffer(free_space_root->commit_root); |
---|
1253 | | - kfree(free_space_root); |
---|
| 1266 | + btrfs_put_root(free_space_root); |
---|
1254 | 1267 | |
---|
1255 | 1268 | return btrfs_commit_transaction(trans); |
---|
1256 | 1269 | |
---|
.. | .. |
---|
1261 | 1274 | } |
---|
1262 | 1275 | |
---|
1263 | 1276 | static int __add_block_group_free_space(struct btrfs_trans_handle *trans, |
---|
1264 | | - struct btrfs_block_group_cache *block_group, |
---|
| 1277 | + struct btrfs_block_group *block_group, |
---|
1265 | 1278 | struct btrfs_path *path) |
---|
1266 | 1279 | { |
---|
1267 | 1280 | int ret; |
---|
.. | .. |
---|
1273 | 1286 | return ret; |
---|
1274 | 1287 | |
---|
1275 | 1288 | return __add_to_free_space_tree(trans, block_group, path, |
---|
1276 | | - block_group->key.objectid, |
---|
1277 | | - block_group->key.offset); |
---|
| 1289 | + block_group->start, |
---|
| 1290 | + block_group->length); |
---|
1278 | 1291 | } |
---|
1279 | 1292 | |
---|
1280 | 1293 | int add_block_group_free_space(struct btrfs_trans_handle *trans, |
---|
1281 | | - struct btrfs_block_group_cache *block_group) |
---|
| 1294 | + struct btrfs_block_group *block_group) |
---|
1282 | 1295 | { |
---|
1283 | 1296 | struct btrfs_fs_info *fs_info = trans->fs_info; |
---|
1284 | 1297 | struct btrfs_path *path = NULL; |
---|
.. | .. |
---|
1308 | 1321 | } |
---|
1309 | 1322 | |
---|
1310 | 1323 | int remove_block_group_free_space(struct btrfs_trans_handle *trans, |
---|
1311 | | - struct btrfs_block_group_cache *block_group) |
---|
| 1324 | + struct btrfs_block_group *block_group) |
---|
1312 | 1325 | { |
---|
1313 | 1326 | struct btrfs_root *root = trans->fs_info->free_space_root; |
---|
1314 | 1327 | struct btrfs_path *path; |
---|
.. | .. |
---|
1332 | 1345 | goto out; |
---|
1333 | 1346 | } |
---|
1334 | 1347 | |
---|
1335 | | - start = block_group->key.objectid; |
---|
1336 | | - end = block_group->key.objectid + block_group->key.offset; |
---|
| 1348 | + start = block_group->start; |
---|
| 1349 | + end = block_group->start + block_group->length; |
---|
1337 | 1350 | |
---|
1338 | 1351 | key.objectid = end - 1; |
---|
1339 | 1352 | key.type = (u8)-1; |
---|
.. | .. |
---|
1351 | 1364 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1); |
---|
1352 | 1365 | |
---|
1353 | 1366 | if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) { |
---|
1354 | | - ASSERT(found_key.objectid == block_group->key.objectid); |
---|
1355 | | - ASSERT(found_key.offset == block_group->key.offset); |
---|
| 1367 | + ASSERT(found_key.objectid == block_group->start); |
---|
| 1368 | + ASSERT(found_key.offset == block_group->length); |
---|
1356 | 1369 | done = 1; |
---|
1357 | 1370 | nr++; |
---|
1358 | 1371 | path->slots[0]--; |
---|
.. | .. |
---|
1387 | 1400 | struct btrfs_path *path, |
---|
1388 | 1401 | u32 expected_extent_count) |
---|
1389 | 1402 | { |
---|
1390 | | - struct btrfs_block_group_cache *block_group; |
---|
| 1403 | + struct btrfs_block_group *block_group; |
---|
1391 | 1404 | struct btrfs_fs_info *fs_info; |
---|
1392 | 1405 | struct btrfs_root *root; |
---|
1393 | 1406 | struct btrfs_key key; |
---|
.. | .. |
---|
1403 | 1416 | fs_info = block_group->fs_info; |
---|
1404 | 1417 | root = fs_info->free_space_root; |
---|
1405 | 1418 | |
---|
1406 | | - end = block_group->key.objectid + block_group->key.offset; |
---|
| 1419 | + end = block_group->start + block_group->length; |
---|
1407 | 1420 | |
---|
1408 | 1421 | while (1) { |
---|
1409 | 1422 | ret = btrfs_next_item(root, path); |
---|
.. | .. |
---|
1450 | 1463 | if (extent_count != expected_extent_count) { |
---|
1451 | 1464 | btrfs_err(fs_info, |
---|
1452 | 1465 | "incorrect extent count for %llu; counted %u, expected %u", |
---|
1453 | | - block_group->key.objectid, extent_count, |
---|
| 1466 | + block_group->start, extent_count, |
---|
1454 | 1467 | expected_extent_count); |
---|
1455 | 1468 | ASSERT(0); |
---|
1456 | 1469 | ret = -EIO; |
---|
.. | .. |
---|
1468 | 1481 | struct btrfs_path *path, |
---|
1469 | 1482 | u32 expected_extent_count) |
---|
1470 | 1483 | { |
---|
1471 | | - struct btrfs_block_group_cache *block_group; |
---|
| 1484 | + struct btrfs_block_group *block_group; |
---|
1472 | 1485 | struct btrfs_fs_info *fs_info; |
---|
1473 | 1486 | struct btrfs_root *root; |
---|
1474 | 1487 | struct btrfs_key key; |
---|
.. | .. |
---|
1481 | 1494 | fs_info = block_group->fs_info; |
---|
1482 | 1495 | root = fs_info->free_space_root; |
---|
1483 | 1496 | |
---|
1484 | | - end = block_group->key.objectid + block_group->key.offset; |
---|
| 1497 | + end = block_group->start + block_group->length; |
---|
1485 | 1498 | |
---|
1486 | 1499 | while (1) { |
---|
1487 | 1500 | ret = btrfs_next_item(root, path); |
---|
.. | .. |
---|
1512 | 1525 | if (extent_count != expected_extent_count) { |
---|
1513 | 1526 | btrfs_err(fs_info, |
---|
1514 | 1527 | "incorrect extent count for %llu; counted %u, expected %u", |
---|
1515 | | - block_group->key.objectid, extent_count, |
---|
| 1528 | + block_group->start, extent_count, |
---|
1516 | 1529 | expected_extent_count); |
---|
1517 | 1530 | ASSERT(0); |
---|
1518 | 1531 | ret = -EIO; |
---|
.. | .. |
---|
1528 | 1541 | |
---|
1529 | 1542 | int load_free_space_tree(struct btrfs_caching_control *caching_ctl) |
---|
1530 | 1543 | { |
---|
1531 | | - struct btrfs_block_group_cache *block_group; |
---|
1532 | | - struct btrfs_fs_info *fs_info; |
---|
| 1544 | + struct btrfs_block_group *block_group; |
---|
1533 | 1545 | struct btrfs_free_space_info *info; |
---|
1534 | 1546 | struct btrfs_path *path; |
---|
1535 | 1547 | u32 extent_count, flags; |
---|
1536 | 1548 | int ret; |
---|
1537 | 1549 | |
---|
1538 | 1550 | block_group = caching_ctl->block_group; |
---|
1539 | | - fs_info = block_group->fs_info; |
---|
1540 | 1551 | |
---|
1541 | 1552 | path = btrfs_alloc_path(); |
---|
1542 | 1553 | if (!path) |
---|
.. | .. |
---|
1550 | 1561 | path->search_commit_root = 1; |
---|
1551 | 1562 | path->reada = READA_FORWARD; |
---|
1552 | 1563 | |
---|
1553 | | - info = search_free_space_info(NULL, fs_info, block_group, path, 0); |
---|
| 1564 | + info = search_free_space_info(NULL, block_group, path, 0); |
---|
1554 | 1565 | if (IS_ERR(info)) { |
---|
1555 | 1566 | ret = PTR_ERR(info); |
---|
1556 | 1567 | goto out; |
---|