btrfs: lift read-write mount setup from mount and remount
Mounting rw and remounting from ro to rw naturally share invariants and functionality which result in a correctly setup rw filesystem. Luckily, there is even a strong unity in the code which implements them. In mount's open_ctree, these operations mostly happen after an early return for ro file systems, and in remount, they happen in a section devoted to remounting ro->rw, after some remount specific validation passes. However, there are unfortunately a few differences. There are small deviations in the order of some of the operations, remount does not start orphan cleanup in root_tree or fs_tree, remount does not create the free space tree, and remount does not handle "one-shot" mount options like clear_cache and uuid tree rescan. Since we want to add building the free space tree to remount, and also to start the same orphan cleanup process on a filesystem mounted as ro then remounted rw, we would benefit from unifying the logic between the two code paths. This patch only lifts the existing common functionality, and leaves a natural path for fixing the discrepancies. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Boris Burkov <boris@bur.io> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
committed by
David Sterba
parent
47876f7cef
commit
44c0ca211a
@@ -2870,6 +2870,52 @@ static int btrfs_check_uuid_tree(struct btrfs_fs_info *fs_info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mounting logic specific to read-write file systems. Shared by open_ctree
|
||||
* and btrfs_remount when remounting from read-only to read-write.
|
||||
*/
|
||||
int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = btrfs_cleanup_fs_roots(fs_info);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
mutex_lock(&fs_info->cleaner_mutex);
|
||||
ret = btrfs_recover_relocation(fs_info->tree_root);
|
||||
mutex_unlock(&fs_info->cleaner_mutex);
|
||||
if (ret < 0) {
|
||||
btrfs_warn(fs_info, "failed to recover relocation: %d", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = btrfs_resume_balance_async(fs_info);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = btrfs_resume_dev_replace_async(fs_info);
|
||||
if (ret) {
|
||||
btrfs_warn(fs_info, "failed to resume dev_replace");
|
||||
goto out;
|
||||
}
|
||||
|
||||
btrfs_qgroup_rescan_resume(fs_info);
|
||||
|
||||
if (!fs_info->uuid_root) {
|
||||
btrfs_info(fs_info, "creating UUID tree");
|
||||
ret = btrfs_create_uuid_tree(fs_info);
|
||||
if (ret) {
|
||||
btrfs_warn(fs_info,
|
||||
"failed to create the UUID tree %d", ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_devices,
|
||||
char *options)
|
||||
{
|
||||
@@ -3285,22 +3331,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
|
||||
if (ret)
|
||||
goto fail_qgroup;
|
||||
|
||||
if (!sb_rdonly(sb)) {
|
||||
ret = btrfs_cleanup_fs_roots(fs_info);
|
||||
if (ret)
|
||||
goto fail_qgroup;
|
||||
|
||||
mutex_lock(&fs_info->cleaner_mutex);
|
||||
ret = btrfs_recover_relocation(tree_root);
|
||||
mutex_unlock(&fs_info->cleaner_mutex);
|
||||
if (ret < 0) {
|
||||
btrfs_warn(fs_info, "failed to recover relocation: %d",
|
||||
ret);
|
||||
err = -EINVAL;
|
||||
goto fail_qgroup;
|
||||
}
|
||||
}
|
||||
|
||||
fs_info->fs_root = btrfs_get_fs_root(fs_info, BTRFS_FS_TREE_OBJECTID, true);
|
||||
if (IS_ERR(fs_info->fs_root)) {
|
||||
err = PTR_ERR(fs_info->fs_root);
|
||||
@@ -3353,35 +3383,16 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
|
||||
}
|
||||
up_read(&fs_info->cleanup_work_sem);
|
||||
|
||||
ret = btrfs_resume_balance_async(fs_info);
|
||||
ret = btrfs_start_pre_rw_mount(fs_info);
|
||||
if (ret) {
|
||||
btrfs_warn(fs_info, "failed to resume balance: %d", ret);
|
||||
close_ctree(fs_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = btrfs_resume_dev_replace_async(fs_info);
|
||||
if (ret) {
|
||||
btrfs_warn(fs_info, "failed to resume device replace: %d", ret);
|
||||
close_ctree(fs_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
btrfs_qgroup_rescan_resume(fs_info);
|
||||
btrfs_discard_resume(fs_info);
|
||||
|
||||
if (!fs_info->uuid_root) {
|
||||
btrfs_info(fs_info, "creating UUID tree");
|
||||
ret = btrfs_create_uuid_tree(fs_info);
|
||||
if (ret) {
|
||||
btrfs_warn(fs_info,
|
||||
"failed to create the UUID tree: %d", ret);
|
||||
close_ctree(fs_info);
|
||||
return ret;
|
||||
}
|
||||
} else if (btrfs_test_opt(fs_info, RESCAN_UUID_TREE) ||
|
||||
fs_info->generation !=
|
||||
btrfs_super_uuid_tree_generation(disk_super)) {
|
||||
if (fs_info->uuid_root &&
|
||||
(btrfs_test_opt(fs_info, RESCAN_UUID_TREE) ||
|
||||
fs_info->generation != btrfs_super_uuid_tree_generation(disk_super))) {
|
||||
btrfs_info(fs_info, "checking UUID tree");
|
||||
ret = btrfs_check_uuid_tree(fs_info);
|
||||
if (ret) {
|
||||
|
||||
Reference in New Issue
Block a user