mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 15:11:31 +00:00
btrfs: abstract out loading the tree root
We're going to be adding more roots that need to be loaded from the super block, so abstract out the code to read the tree_root from the super block, and use this helper for the chunk root as well. This will make it simpler to load the new trees in the future. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
c2fa821cc9
commit
bd676446c1
@ -2930,6 +2930,45 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int load_super_root(struct btrfs_root *root, u64 bytenr, u64 gen, int level)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
root->node = read_tree_block(root->fs_info, bytenr,
|
||||
root->root_key.objectid, gen, level, NULL);
|
||||
if (IS_ERR(root->node)) {
|
||||
ret = PTR_ERR(root->node);
|
||||
root->node = NULL;
|
||||
} else if (!extent_buffer_uptodate(root->node)) {
|
||||
free_extent_buffer(root->node);
|
||||
root->node = NULL;
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
btrfs_set_root_node(&root->root_item, root->node);
|
||||
root->commit_root = btrfs_root_node(root);
|
||||
btrfs_set_root_refs(&root->root_item, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int load_important_roots(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct btrfs_super_block *sb = fs_info->super_copy;
|
||||
u64 gen, bytenr;
|
||||
int level, ret;
|
||||
|
||||
bytenr = btrfs_super_root(sb);
|
||||
gen = btrfs_super_generation(sb);
|
||||
level = btrfs_super_root_level(sb);
|
||||
ret = load_super_root(fs_info->tree_root, bytenr, gen, level);
|
||||
if (ret)
|
||||
btrfs_warn(fs_info, "couldn't read tree root");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
int backup_index = find_newest_super_backup(fs_info);
|
||||
@ -2940,9 +2979,6 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
|
||||
u64 generation;
|
||||
int level;
|
||||
|
||||
if (handle_error) {
|
||||
if (!IS_ERR(tree_root->node))
|
||||
free_extent_buffer(tree_root->node);
|
||||
@ -2967,29 +3003,13 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
generation = btrfs_super_generation(sb);
|
||||
level = btrfs_super_root_level(sb);
|
||||
tree_root->node = read_tree_block(fs_info, btrfs_super_root(sb),
|
||||
BTRFS_ROOT_TREE_OBJECTID,
|
||||
generation, level, NULL);
|
||||
if (IS_ERR(tree_root->node)) {
|
||||
handle_error = true;
|
||||
ret = PTR_ERR(tree_root->node);
|
||||
tree_root->node = NULL;
|
||||
btrfs_warn(fs_info, "couldn't read tree root");
|
||||
continue;
|
||||
|
||||
} else if (!extent_buffer_uptodate(tree_root->node)) {
|
||||
ret = load_important_roots(fs_info);
|
||||
if (ret) {
|
||||
handle_error = true;
|
||||
ret = -EIO;
|
||||
btrfs_warn(fs_info, "error while reading tree root");
|
||||
continue;
|
||||
}
|
||||
|
||||
btrfs_set_root_node(&tree_root->root_item, tree_root->node);
|
||||
tree_root->commit_root = btrfs_root_node(tree_root);
|
||||
btrfs_set_root_refs(&tree_root->root_item, 1);
|
||||
|
||||
/*
|
||||
* No need to hold btrfs_root::objectid_mutex since the fs
|
||||
* hasn't been fully initialised and we are the only user
|
||||
@ -3009,8 +3029,8 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
|
||||
}
|
||||
|
||||
/* All successful */
|
||||
fs_info->generation = generation;
|
||||
fs_info->last_trans_committed = generation;
|
||||
fs_info->generation = btrfs_header_generation(tree_root->node);
|
||||
fs_info->last_trans_committed = fs_info->generation;
|
||||
fs_info->last_reloc_trans = 0;
|
||||
|
||||
/* Always begin writing backup roots after the one being used */
|
||||
@ -3594,21 +3614,12 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
|
||||
|
||||
generation = btrfs_super_chunk_root_generation(disk_super);
|
||||
level = btrfs_super_chunk_root_level(disk_super);
|
||||
|
||||
chunk_root->node = read_tree_block(fs_info,
|
||||
btrfs_super_chunk_root(disk_super),
|
||||
BTRFS_CHUNK_TREE_OBJECTID,
|
||||
generation, level, NULL);
|
||||
if (IS_ERR(chunk_root->node) ||
|
||||
!extent_buffer_uptodate(chunk_root->node)) {
|
||||
ret = load_super_root(chunk_root, btrfs_super_chunk_root(disk_super),
|
||||
generation, level);
|
||||
if (ret) {
|
||||
btrfs_err(fs_info, "failed to read chunk root");
|
||||
if (!IS_ERR(chunk_root->node))
|
||||
free_extent_buffer(chunk_root->node);
|
||||
chunk_root->node = NULL;
|
||||
goto fail_tree_roots;
|
||||
}
|
||||
btrfs_set_root_node(&chunk_root->root_item, chunk_root->node);
|
||||
chunk_root->commit_root = btrfs_root_node(chunk_root);
|
||||
|
||||
read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid,
|
||||
offsetof(struct btrfs_header, chunk_tree_uuid),
|
||||
|
Loading…
Reference in New Issue
Block a user