mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 22:54:05 +08:00
btrfs: clear free space tree on ro->rw remount
A user might want to revert to v1 or nospace_cache on a root filesystem, and much like turning on the free space tree, that can only be done remounting from ro->rw. Support clearing the free space tree on such mounts by moving it into the shared remount logic. Since the CLEAR_CACHE option sticks around across remounts, this change would result in clearing the tree for ever on every remount, which is not desirable. To fix that, add CLEAR_CACHE to the oneshot options we clear at mount end, which has the other bonus of not cluttering the /proc/mounts output with clear_cache. 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:
parent
8cd2908846
commit
8b228324a8
@ -2878,6 +2878,7 @@ static int btrfs_check_uuid_tree(struct btrfs_fs_info *fs_info)
|
||||
void btrfs_clear_oneshot_options(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
btrfs_clear_opt(fs_info->mount_opt, USEBACKUPROOT);
|
||||
btrfs_clear_opt(fs_info->mount_opt, CLEAR_CACHE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2887,6 +2888,26 @@ void btrfs_clear_oneshot_options(struct btrfs_fs_info *fs_info)
|
||||
int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
int ret;
|
||||
bool clear_free_space_tree = false;
|
||||
|
||||
if (btrfs_test_opt(fs_info, CLEAR_CACHE) &&
|
||||
btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
|
||||
clear_free_space_tree = true;
|
||||
} else if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
|
||||
!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID)) {
|
||||
btrfs_warn(fs_info, "free space tree is invalid");
|
||||
clear_free_space_tree = true;
|
||||
}
|
||||
|
||||
if (clear_free_space_tree) {
|
||||
btrfs_info(fs_info, "clearing free space tree");
|
||||
ret = btrfs_clear_free_space_tree(fs_info);
|
||||
if (ret) {
|
||||
btrfs_warn(fs_info,
|
||||
"failed to clear free space tree: %d", ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = btrfs_cleanup_fs_roots(fs_info);
|
||||
if (ret)
|
||||
@ -2960,7 +2981,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
|
||||
struct btrfs_root *chunk_root;
|
||||
int ret;
|
||||
int err = -EINVAL;
|
||||
int clear_free_space_tree = 0;
|
||||
int level;
|
||||
|
||||
ret = init_mount_fs_info(fs_info, sb);
|
||||
@ -3371,26 +3391,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
|
||||
if (sb_rdonly(sb))
|
||||
goto clear_oneshot;
|
||||
|
||||
if (btrfs_test_opt(fs_info, CLEAR_CACHE) &&
|
||||
btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
|
||||
clear_free_space_tree = 1;
|
||||
} else if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
|
||||
!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID)) {
|
||||
btrfs_warn(fs_info, "free space tree is invalid");
|
||||
clear_free_space_tree = 1;
|
||||
}
|
||||
|
||||
if (clear_free_space_tree) {
|
||||
btrfs_info(fs_info, "clearing free space tree");
|
||||
ret = btrfs_clear_free_space_tree(fs_info);
|
||||
if (ret) {
|
||||
btrfs_warn(fs_info,
|
||||
"failed to clear free space tree: %d", ret);
|
||||
close_ctree(fs_info);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = btrfs_start_pre_rw_mount(fs_info);
|
||||
if (ret) {
|
||||
close_ctree(fs_info);
|
||||
|
Loading…
Reference in New Issue
Block a user