This code adds the on disk structures for the block group root, which will hold the block group items for extent tree v2.
Unified · Split
| @@ -274,8 +274,14 @@ struct btrfs_super_block { · 273 unmodified lines | ||
| 274 | 274 | /* the UUID written into btree blocks */ |
| 275 | 275 | u8 metadata_uuid[BTRFS_FSID_SIZE]; |
| 276 | 276 | |
| 277 | + /* Extent tree v2 */ | |
| 278 | + __le64 block_group_root; | |
| 279 | + __le64 block_group_root_generation; | |
| 280 | + u8 block_group_root_level; | |
| 281 | + | |
| 277 | 282 | /* future expansion */ |
| 278 | − __le64 reserved[28]; | |
| 283 | + u8 reserved8[7]; | |
| 284 | + __le64 reserved[25]; | |
| 279 | 285 | u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE]; |
| 280 | 286 | struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS]; |
| 281 | 287 | |
| @@ -657,6 +663,7 @@ struct btrfs_fs_info { · 375 unmodified lines | ||
| 657 | 663 | struct btrfs_root *quota_root; |
| 658 | 664 | struct btrfs_root *uuid_root; |
| 659 | 665 | struct btrfs_root *data_reloc_root; |
| 666 | + struct btrfs_root *block_group_root; | |
| 660 | 667 | |
| 661 | 668 | /* the log root tree is a directory of all the other log roots */ |
| 662 | 669 | struct btrfs_root *log_root_tree; |
| @@ -2349,6 +2356,17 @@ BTRFS_SETGET_STACK_FUNCS(backup_bytes_used, struct btrfs_root_backup, · 1686 unmodified lines | ||
| 2349 | 2356 | BTRFS_SETGET_STACK_FUNCS(backup_num_devices, struct btrfs_root_backup, |
| 2350 | 2357 | num_devices, 64); |
| 2351 | 2358 | |
| 2359 | +/* | |
| 2360 | + * For extent tree v2 we overload the extent root with the block group root, as | |
| 2361 | + * we will have multiple extent roots. | |
| 2362 | + */ | |
| 2363 | +BTRFS_SETGET_STACK_FUNCS(backup_block_group_root, struct btrfs_root_backup, | |
| 2364 | + extent_root, 64); | |
| 2365 | +BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_gen, struct btrfs_root_backup, | |
| 2366 | + extent_root_gen, 64); | |
| 2367 | +BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_level, | |
| 2368 | + struct btrfs_root_backup, extent_root_level, 8); | |
| 2369 | + | |
| 2352 | 2370 | /* struct btrfs_balance_item */ |
| 2353 | 2371 | BTRFS_SETGET_FUNCS(balance_flags, struct btrfs_balance_item, flags, 64); |
| 2354 | 2372 | |
| @@ -2483,6 +2501,13 @@ BTRFS_SETGET_STACK_FUNCS(super_cache_generation, struct btrfs_super_block, · 128 unmodified lines | ||
| 2483 | 2501 | BTRFS_SETGET_STACK_FUNCS(super_magic, struct btrfs_super_block, magic, 64); |
| 2484 | 2502 | BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block, |
| 2485 | 2503 | uuid_tree_generation, 64); |
| 2504 | +BTRFS_SETGET_STACK_FUNCS(super_block_group_root, struct btrfs_super_block, | |
| 2505 | + block_group_root, 64); | |
| 2506 | +BTRFS_SETGET_STACK_FUNCS(super_block_group_root_generation, | |
| 2507 | + struct btrfs_super_block, | |
| 2508 | + block_group_root_generation, 64); | |
| 2509 | +BTRFS_SETGET_STACK_FUNCS(super_block_group_root_level, struct btrfs_super_block, | |
| 2510 | + block_group_root_level, 8); | |
| 2486 | 2511 | |
| 2487 | 2512 | int btrfs_super_csum_size(const struct btrfs_super_block *s); |
| 2488 | 2513 | const char *btrfs_super_csum_name(u16 csum_type); |
| @@ -1727,6 +1727,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info) · 1726 unmodified lines | ||
| 1727 | 1727 | btrfs_put_root(fs_info->uuid_root); |
| 1728 | 1728 | btrfs_put_root(fs_info->fs_root); |
| 1729 | 1729 | btrfs_put_root(fs_info->data_reloc_root); |
| 1730 | + btrfs_put_root(fs_info->block_group_root); | |
| 1730 | 1731 | btrfs_check_leaked_roots(fs_info); |
| 1731 | 1732 | btrfs_extent_buffer_leak_debug_check(fs_info); |
| 1732 | 1733 | kfree(fs_info->super_copy); |
| @@ -2095,7 +2096,6 @@ static void backup_super_roots(struct btrfs_fs_info *info) · 362 unmodified lines | ||
| 2095 | 2096 | { |
| 2096 | 2097 | const int next_backup = info->backup_root_index; |
| 2097 | 2098 | struct btrfs_root_backup *root_backup; |
| 2098 | − struct btrfs_root *extent_root = btrfs_extent_root(info, 0); | |
| 2099 | 2099 | struct btrfs_root *csum_root = btrfs_csum_root(info, 0); |
| 2100 | 2100 | |
| 2101 | 2101 | root_backup = info->super_for_commit->super_roots + next_backup; |
| @@ -2121,11 +2121,23 @@ static void backup_super_roots(struct btrfs_fs_info *info) · 19 unmodified lines | ||
| 2121 | 2121 | btrfs_set_backup_chunk_root_level(root_backup, |
| 2122 | 2122 | btrfs_header_level(info->chunk_root->node)); |
| 2123 | 2123 | |
| 2124 | − btrfs_set_backup_extent_root(root_backup, extent_root->node->start); | |
| 2125 | − btrfs_set_backup_extent_root_gen(root_backup, | |
| 2126 | − btrfs_header_generation(extent_root->node)); | |
| 2127 | − btrfs_set_backup_extent_root_level(root_backup, | |
| 2128 | − btrfs_header_level(extent_root->node)); | |
| 2124 | + if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) { | |
| 2125 | + btrfs_set_backup_block_group_root(root_backup, | |
| 2126 | + info->block_group_root->node->start); | |
| 2127 | + btrfs_set_backup_block_group_root_gen(root_backup, | |
| 2128 | + btrfs_header_generation(info->block_group_root->node)); | |
| 2129 | + btrfs_set_backup_block_group_root_level(root_backup, | |
| 2130 | + btrfs_header_level(info->block_group_root->node)); | |
| 2131 | + } else { | |
| 2132 | + struct btrfs_root *extent_root = btrfs_extent_root(info, 0); | |
| 2133 | + | |
| 2134 | + btrfs_set_backup_extent_root(root_backup, | |
| 2135 | + extent_root->node->start); | |
| 2136 | + btrfs_set_backup_extent_root_gen(root_backup, | |
| 2137 | + btrfs_header_generation(extent_root->node)); | |
| 2138 | + btrfs_set_backup_extent_root_level(root_backup, | |
| 2139 | + btrfs_header_level(extent_root->node)); | |
| 2140 | + } | |
| 2129 | 2141 | |
| 2130 | 2142 | /* |
| 2131 | 2143 | * we might commit during log recovery, which happens before we set |
| @@ -2269,6 +2281,7 @@ static void free_root_pointers(struct btrfs_fs_info *info, bool free_chunk_root) · 137 unmodified lines | ||
| 2269 | 2281 | free_root_extent_buffers(info->uuid_root); |
| 2270 | 2282 | free_root_extent_buffers(info->fs_root); |
| 2271 | 2283 | free_root_extent_buffers(info->data_reloc_root); |
| 2284 | + free_root_extent_buffers(info->block_group_root); | |
| 2272 | 2285 | if (free_chunk_root) |
| 2273 | 2286 | free_root_extent_buffers(info->chunk_root); |
| 2274 | 2287 | } |
| @@ -2964,8 +2977,20 @@ static int load_important_roots(struct btrfs_fs_info *fs_info) · 689 unmodified lines | ||
| 2964 | 2977 | gen = btrfs_super_generation(sb); |
| 2965 | 2978 | level = btrfs_super_root_level(sb); |
| 2966 | 2979 | ret = load_super_root(fs_info->tree_root, bytenr, gen, level); |
| 2967 | − if (ret) | |
| 2980 | + if (ret) { | |
| 2968 | 2981 | btrfs_warn(fs_info, "couldn't read tree root"); |
| 2982 | + return ret; | |
| 2983 | + } | |
| 2984 | + | |
| 2985 | + if (!btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) | |
| 2986 | + return 0; | |
| 2987 | + | |
| 2988 | + bytenr = btrfs_super_block_group_root(sb); | |
| 2989 | + gen = btrfs_super_block_group_root_generation(sb); | |
| 2990 | + level = btrfs_super_block_group_root_level(sb); | |
| 2991 | + ret = load_super_root(fs_info->block_group_root, bytenr, gen, level); | |
| 2992 | + if (ret) | |
| 2993 | + btrfs_warn(fs_info, "couldn't read block group root"); | |
| 2969 | 2994 | return ret; |
| 2970 | 2995 | } |
| 2971 | 2996 | |
| @@ -2978,6 +3003,16 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info) · 6 unmodified lines | ||
| 2978 | 3003 | int ret = 0; |
| 2979 | 3004 | int i; |
| 2980 | 3005 | |
| 3006 | + if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) { | |
| 3007 | + struct btrfs_root *root; | |
| 3008 | + | |
| 3009 | + root = btrfs_alloc_root(fs_info, BTRFS_BLOCK_GROUP_TREE_OBJECTID, | |
| 3010 | + GFP_KERNEL); | |
| 3011 | + if (!root) | |
| 3012 | + return -ENOMEM; | |
| 3013 | + fs_info->block_group_root = root; | |
| 3014 | + } | |
| 3015 | + | |
| 2981 | 3016 | for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) { |
| 2982 | 3017 | if (handle_error) { |
| 2983 | 3018 | if (!IS_ERR(tree_root->node)) |
| @@ -111,6 +111,8 @@ static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root) · 110 unmodified lines | ||
| 111 | 111 | |
| 112 | 112 | static inline struct btrfs_root *btrfs_block_group_root(struct btrfs_fs_info *fs_info) |
| 113 | 113 | { |
| 114 | + if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) | |
| 115 | + return fs_info->block_group_root; | |
| 114 | 116 | return btrfs_extent_root(fs_info, 0); |
| 115 | 117 | } |
| 116 | 118 | |
| @@ -23,6 +23,7 @@ static const struct root_name_map root_map[] = { · 22 unmodified lines | ||
| 23 | 23 | { BTRFS_QUOTA_TREE_OBJECTID, "QUOTA_TREE" }, |
| 24 | 24 | { BTRFS_UUID_TREE_OBJECTID, "UUID_TREE" }, |
| 25 | 25 | { BTRFS_FREE_SPACE_TREE_OBJECTID, "FREE_SPACE_TREE" }, |
| 26 | + { BTRFS_BLOCK_GROUP_TREE_OBJECTID, "BLOCK_GROUP_TREE" }, | |
| 26 | 27 | { BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" }, |
| 27 | 28 | }; |
| 28 | 29 | |
| @@ -53,6 +53,7 @@ struct btrfs_space_info; · 52 unmodified lines | ||
| 53 | 53 | { BTRFS_TREE_RELOC_OBJECTID, "TREE_RELOC" }, \ |
| 54 | 54 | { BTRFS_UUID_TREE_OBJECTID, "UUID_TREE" }, \ |
| 55 | 55 | { BTRFS_FREE_SPACE_TREE_OBJECTID, "FREE_SPACE_TREE" }, \ |
| 56 | + { BTRFS_BLOCK_GROUP_TREE_OBJECTID, "BLOCK_GROUP_TREE" },\ | |
| 56 | 57 | { BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" }) |
| 57 | 58 | |
| 58 | 59 | #define show_root_type(obj) \ |
| @@ -53,6 +53,9 @@ · 52 unmodified lines | ||
| 53 | 53 | /* tracks free space in block groups. */ |
| 54 | 54 | #define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL |
| 55 | 55 | |
| 56 | +/* Holds the block group items for extent tree v2. */ | |
| 57 | +#define BTRFS_BLOCK_GROUP_TREE_OBJECTID 11ULL | |
| 58 | + | |
| 56 | 59 | /* device stats in the device tree */ |
| 57 | 60 | #define BTRFS_DEV_STATS_OBJECTID 0ULL |
| 58 | 61 | |