Commit 9c54e80d authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: add code to support the block group root

This code adds the on disk structures for the block group root, which
will hold the block group items for extent tree v2.
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent bd676446
...@@ -274,8 +274,14 @@ struct btrfs_super_block { ...@@ -274,8 +274,14 @@ struct btrfs_super_block {
/* the UUID written into btree blocks */ /* the UUID written into btree blocks */
u8 metadata_uuid[BTRFS_FSID_SIZE]; u8 metadata_uuid[BTRFS_FSID_SIZE];
/* Extent tree v2 */
__le64 block_group_root;
__le64 block_group_root_generation;
u8 block_group_root_level;
/* future expansion */ /* future expansion */
__le64 reserved[28]; u8 reserved8[7];
__le64 reserved[25];
u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE]; u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS]; struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
...@@ -657,6 +663,7 @@ struct btrfs_fs_info { ...@@ -657,6 +663,7 @@ struct btrfs_fs_info {
struct btrfs_root *quota_root; struct btrfs_root *quota_root;
struct btrfs_root *uuid_root; struct btrfs_root *uuid_root;
struct btrfs_root *data_reloc_root; struct btrfs_root *data_reloc_root;
struct btrfs_root *block_group_root;
/* the log root tree is a directory of all the other log roots */ /* the log root tree is a directory of all the other log roots */
struct btrfs_root *log_root_tree; struct btrfs_root *log_root_tree;
...@@ -2349,6 +2356,17 @@ BTRFS_SETGET_STACK_FUNCS(backup_bytes_used, struct btrfs_root_backup, ...@@ -2349,6 +2356,17 @@ BTRFS_SETGET_STACK_FUNCS(backup_bytes_used, struct btrfs_root_backup,
BTRFS_SETGET_STACK_FUNCS(backup_num_devices, struct btrfs_root_backup, BTRFS_SETGET_STACK_FUNCS(backup_num_devices, struct btrfs_root_backup,
num_devices, 64); num_devices, 64);
/*
* For extent tree v2 we overload the extent root with the block group root, as
* we will have multiple extent roots.
*/
BTRFS_SETGET_STACK_FUNCS(backup_block_group_root, struct btrfs_root_backup,
extent_root, 64);
BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_gen, struct btrfs_root_backup,
extent_root_gen, 64);
BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_level,
struct btrfs_root_backup, extent_root_level, 8);
/* struct btrfs_balance_item */ /* struct btrfs_balance_item */
BTRFS_SETGET_FUNCS(balance_flags, struct btrfs_balance_item, flags, 64); BTRFS_SETGET_FUNCS(balance_flags, struct btrfs_balance_item, flags, 64);
...@@ -2483,6 +2501,13 @@ BTRFS_SETGET_STACK_FUNCS(super_cache_generation, struct btrfs_super_block, ...@@ -2483,6 +2501,13 @@ BTRFS_SETGET_STACK_FUNCS(super_cache_generation, struct btrfs_super_block,
BTRFS_SETGET_STACK_FUNCS(super_magic, struct btrfs_super_block, magic, 64); BTRFS_SETGET_STACK_FUNCS(super_magic, struct btrfs_super_block, magic, 64);
BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block, BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block,
uuid_tree_generation, 64); uuid_tree_generation, 64);
BTRFS_SETGET_STACK_FUNCS(super_block_group_root, struct btrfs_super_block,
block_group_root, 64);
BTRFS_SETGET_STACK_FUNCS(super_block_group_root_generation,
struct btrfs_super_block,
block_group_root_generation, 64);
BTRFS_SETGET_STACK_FUNCS(super_block_group_root_level, struct btrfs_super_block,
block_group_root_level, 8);
int btrfs_super_csum_size(const struct btrfs_super_block *s); int btrfs_super_csum_size(const struct btrfs_super_block *s);
const char *btrfs_super_csum_name(u16 csum_type); const char *btrfs_super_csum_name(u16 csum_type);
......
...@@ -1727,6 +1727,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info) ...@@ -1727,6 +1727,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
btrfs_put_root(fs_info->uuid_root); btrfs_put_root(fs_info->uuid_root);
btrfs_put_root(fs_info->fs_root); btrfs_put_root(fs_info->fs_root);
btrfs_put_root(fs_info->data_reloc_root); btrfs_put_root(fs_info->data_reloc_root);
btrfs_put_root(fs_info->block_group_root);
btrfs_check_leaked_roots(fs_info); btrfs_check_leaked_roots(fs_info);
btrfs_extent_buffer_leak_debug_check(fs_info); btrfs_extent_buffer_leak_debug_check(fs_info);
kfree(fs_info->super_copy); kfree(fs_info->super_copy);
...@@ -2095,7 +2096,6 @@ static void backup_super_roots(struct btrfs_fs_info *info) ...@@ -2095,7 +2096,6 @@ static void backup_super_roots(struct btrfs_fs_info *info)
{ {
const int next_backup = info->backup_root_index; const int next_backup = info->backup_root_index;
struct btrfs_root_backup *root_backup; struct btrfs_root_backup *root_backup;
struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
struct btrfs_root *csum_root = btrfs_csum_root(info, 0); struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
root_backup = info->super_for_commit->super_roots + next_backup; root_backup = info->super_for_commit->super_roots + next_backup;
...@@ -2121,11 +2121,23 @@ static void backup_super_roots(struct btrfs_fs_info *info) ...@@ -2121,11 +2121,23 @@ static void backup_super_roots(struct btrfs_fs_info *info)
btrfs_set_backup_chunk_root_level(root_backup, btrfs_set_backup_chunk_root_level(root_backup,
btrfs_header_level(info->chunk_root->node)); btrfs_header_level(info->chunk_root->node));
btrfs_set_backup_extent_root(root_backup, extent_root->node->start); if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) {
btrfs_set_backup_extent_root_gen(root_backup, btrfs_set_backup_block_group_root(root_backup,
btrfs_header_generation(extent_root->node)); info->block_group_root->node->start);
btrfs_set_backup_extent_root_level(root_backup, btrfs_set_backup_block_group_root_gen(root_backup,
btrfs_header_level(extent_root->node)); btrfs_header_generation(info->block_group_root->node));
btrfs_set_backup_block_group_root_level(root_backup,
btrfs_header_level(info->block_group_root->node));
} else {
struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
btrfs_set_backup_extent_root(root_backup,
extent_root->node->start);
btrfs_set_backup_extent_root_gen(root_backup,
btrfs_header_generation(extent_root->node));
btrfs_set_backup_extent_root_level(root_backup,
btrfs_header_level(extent_root->node));
}
/* /*
* we might commit during log recovery, which happens before we set * 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) ...@@ -2269,6 +2281,7 @@ static void free_root_pointers(struct btrfs_fs_info *info, bool free_chunk_root)
free_root_extent_buffers(info->uuid_root); free_root_extent_buffers(info->uuid_root);
free_root_extent_buffers(info->fs_root); free_root_extent_buffers(info->fs_root);
free_root_extent_buffers(info->data_reloc_root); free_root_extent_buffers(info->data_reloc_root);
free_root_extent_buffers(info->block_group_root);
if (free_chunk_root) if (free_chunk_root)
free_root_extent_buffers(info->chunk_root); free_root_extent_buffers(info->chunk_root);
} }
...@@ -2964,8 +2977,20 @@ static int load_important_roots(struct btrfs_fs_info *fs_info) ...@@ -2964,8 +2977,20 @@ static int load_important_roots(struct btrfs_fs_info *fs_info)
gen = btrfs_super_generation(sb); gen = btrfs_super_generation(sb);
level = btrfs_super_root_level(sb); level = btrfs_super_root_level(sb);
ret = load_super_root(fs_info->tree_root, bytenr, gen, level); ret = load_super_root(fs_info->tree_root, bytenr, gen, level);
if (ret) if (ret) {
btrfs_warn(fs_info, "couldn't read tree root"); btrfs_warn(fs_info, "couldn't read tree root");
return ret;
}
if (!btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
return 0;
bytenr = btrfs_super_block_group_root(sb);
gen = btrfs_super_block_group_root_generation(sb);
level = btrfs_super_block_group_root_level(sb);
ret = load_super_root(fs_info->block_group_root, bytenr, gen, level);
if (ret)
btrfs_warn(fs_info, "couldn't read block group root");
return ret; return ret;
} }
...@@ -2978,6 +3003,16 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info) ...@@ -2978,6 +3003,16 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
int ret = 0; int ret = 0;
int i; int i;
if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
struct btrfs_root *root;
root = btrfs_alloc_root(fs_info, BTRFS_BLOCK_GROUP_TREE_OBJECTID,
GFP_KERNEL);
if (!root)
return -ENOMEM;
fs_info->block_group_root = root;
}
for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) { for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
if (handle_error) { if (handle_error) {
if (!IS_ERR(tree_root->node)) if (!IS_ERR(tree_root->node))
......
...@@ -111,6 +111,8 @@ static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root) ...@@ -111,6 +111,8 @@ static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root)
static inline struct btrfs_root *btrfs_block_group_root(struct btrfs_fs_info *fs_info) static inline struct btrfs_root *btrfs_block_group_root(struct btrfs_fs_info *fs_info)
{ {
if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
return fs_info->block_group_root;
return btrfs_extent_root(fs_info, 0); return btrfs_extent_root(fs_info, 0);
} }
......
...@@ -23,6 +23,7 @@ static const struct root_name_map root_map[] = { ...@@ -23,6 +23,7 @@ static const struct root_name_map root_map[] = {
{ BTRFS_QUOTA_TREE_OBJECTID, "QUOTA_TREE" }, { BTRFS_QUOTA_TREE_OBJECTID, "QUOTA_TREE" },
{ BTRFS_UUID_TREE_OBJECTID, "UUID_TREE" }, { BTRFS_UUID_TREE_OBJECTID, "UUID_TREE" },
{ BTRFS_FREE_SPACE_TREE_OBJECTID, "FREE_SPACE_TREE" }, { BTRFS_FREE_SPACE_TREE_OBJECTID, "FREE_SPACE_TREE" },
{ BTRFS_BLOCK_GROUP_TREE_OBJECTID, "BLOCK_GROUP_TREE" },
{ BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" }, { BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" },
}; };
......
...@@ -53,6 +53,7 @@ struct btrfs_space_info; ...@@ -53,6 +53,7 @@ struct btrfs_space_info;
{ BTRFS_TREE_RELOC_OBJECTID, "TREE_RELOC" }, \ { BTRFS_TREE_RELOC_OBJECTID, "TREE_RELOC" }, \
{ BTRFS_UUID_TREE_OBJECTID, "UUID_TREE" }, \ { BTRFS_UUID_TREE_OBJECTID, "UUID_TREE" }, \
{ BTRFS_FREE_SPACE_TREE_OBJECTID, "FREE_SPACE_TREE" }, \ { BTRFS_FREE_SPACE_TREE_OBJECTID, "FREE_SPACE_TREE" }, \
{ BTRFS_BLOCK_GROUP_TREE_OBJECTID, "BLOCK_GROUP_TREE" },\
{ BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" }) { BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" })
#define show_root_type(obj) \ #define show_root_type(obj) \
......
...@@ -53,6 +53,9 @@ ...@@ -53,6 +53,9 @@
/* tracks free space in block groups. */ /* tracks free space in block groups. */
#define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL #define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL
/* Holds the block group items for extent tree v2. */
#define BTRFS_BLOCK_GROUP_TREE_OBJECTID 11ULL
/* device stats in the device tree */ /* device stats in the device tree */
#define BTRFS_DEV_STATS_OBJECTID 0ULL #define BTRFS_DEV_STATS_OBJECTID 0ULL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment