summaryrefslogtreecommitdiff
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index e4fad777b034..1b0eb246b714 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1591,7 +1591,7 @@ static int find_newest_super_backup(struct btrfs_fs_info *info)
* this will bump the backup pointer by one when it is
* done
*/
-static void backup_super_roots(struct btrfs_fs_info *info)
+static int backup_super_roots(struct btrfs_fs_info *info)
{
const int next_backup = info->backup_root_index;
struct btrfs_root_backup *root_backup;
@@ -1623,6 +1623,15 @@ static void backup_super_roots(struct btrfs_fs_info *info)
struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
+ if (unlikely(!extent_root)) {
+ btrfs_err(info, "missing extent root for extent at bytenr 0");
+ return -EUCLEAN;
+ }
+ if (unlikely(!csum_root)) {
+ btrfs_err(info, "missing csum root for extent at bytenr 0");
+ return -EUCLEAN;
+ }
+
btrfs_set_backup_extent_root(root_backup,
extent_root->node->start);
btrfs_set_backup_extent_root_gen(root_backup,
@@ -1670,6 +1679,8 @@ static void backup_super_roots(struct btrfs_fs_info *info)
memcpy(&info->super_copy->super_roots,
&info->super_for_commit->super_roots,
sizeof(*root_backup) * BTRFS_NUM_BACKUP_ROOTS);
+
+ return 0;
}
/*
@@ -2520,8 +2531,8 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
if (mirror_num >= 0 &&
btrfs_super_bytenr(sb) != btrfs_sb_offset(mirror_num)) {
- btrfs_err(fs_info, "super offset mismatch %llu != %u",
- btrfs_super_bytenr(sb), BTRFS_SUPER_INFO_OFFSET);
+ btrfs_err(fs_info, "super offset mismatch %llu != %llu",
+ btrfs_super_bytenr(sb), btrfs_sb_offset(mirror_num));
ret = -EINVAL;
}
@@ -3594,7 +3605,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
}
}
- btrfs_zoned_reserve_data_reloc_bg(fs_info);
btrfs_free_zone_cache(fs_info);
btrfs_check_active_zone_reservation(fs_info);
@@ -3622,6 +3632,12 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
goto fail_cleaner;
}
+ /*
+ * Starts a transaction, must be called after the transaction kthread
+ * is initialized.
+ */
+ btrfs_zoned_reserve_data_reloc_bg(fs_info);
+
ret = btrfs_read_qgroup_config(fs_info);
if (ret)
goto fail_trans_kthread;
@@ -4046,8 +4062,11 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
* not from fsync where the tree roots in fs_info have not
* been consistent on disk.
*/
- if (max_mirrors == 0)
- backup_super_roots(fs_info);
+ if (max_mirrors == 0) {
+ ret = backup_super_roots(fs_info);
+ if (ret < 0)
+ return ret;
+ }
sb = fs_info->super_for_commit;
dev_item = &sb->dev_item;