mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
btrfs: introduce more accurate usebackuproot options
Previously we had no way to tell btrfs to use which backup slot, but always use the newest backup, and retry until all backup roots are exhausted. This doesn't give any control to the end user, even if the end user wants to use a specific backup slot. To address this problem, allow more fine-control on usebackuproot rescue option by introducing the following 4 rescue mount options: - rescue=usebackuproot_0 - rescue=usebackuproot_1 - rescue=usebackuproot_2 - rescue=usebackuproot_3 The number 0 means the newest slot, which should be the same as the one recorded in the super block and no need to load any backup root. 1/2/3 means the second/third/fourth(oldest) backup slot to use. The existing "rescue=usebackuproot" is just an alias of "rescue=usebackuproot_1". This will allow users to choose which backup root to use, thus can have a better control than blindly choose any slot that can pass the very basic root node checks. Reviewed-by: Boris Burkov <boris@bur.io> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
c73eb6f727
commit
9421d1897b
|
|
@ -2715,10 +2715,14 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
|
|||
int ret = 0;
|
||||
|
||||
if (use_backup) {
|
||||
ret = read_backup_root(fs_info, 1);
|
||||
ASSERT(fs_info->use_backup_slot >= 0 &&
|
||||
fs_info->use_backup_slot < BTRFS_NUM_BACKUP_ROOTS);
|
||||
|
||||
ret = read_backup_root(fs_info, fs_info->use_backup_slot);
|
||||
if (ret < 0) {
|
||||
btrfs_err(fs_info,
|
||||
"failed to load backup roots at slot %d", 1);
|
||||
"failed to load backup roots at slot %d",
|
||||
fs_info->use_backup_slot);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
|
|
@ -2727,7 +2731,8 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
|
|||
*/
|
||||
btrfs_set_super_log_root(sb, 0);
|
||||
backup_index = ret;
|
||||
btrfs_warn(fs_info, "loaded backup roots at slot %d", 1);
|
||||
btrfs_warn(fs_info, "loaded backup roots at slot %d",
|
||||
fs_info->use_backup_slot);
|
||||
}
|
||||
|
||||
ret = load_important_roots(fs_info);
|
||||
|
|
@ -2898,6 +2903,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
|
|||
init_waitqueue_head(&fs_info->async_submit_wait);
|
||||
init_waitqueue_head(&fs_info->delayed_iputs_wait);
|
||||
|
||||
fs_info->use_backup_slot = -1;
|
||||
/* Usable values until the real ones are cached from the superblock */
|
||||
fs_info->nodesize = 4096;
|
||||
fs_info->sectorsize = 4096;
|
||||
|
|
|
|||
|
|
@ -857,6 +857,7 @@ struct btrfs_fs_info {
|
|||
|
||||
/* Next backup root to be overwritten */
|
||||
int backup_root_index;
|
||||
int use_backup_slot;
|
||||
|
||||
/* Device replace state */
|
||||
struct btrfs_dev_replace dev_replace;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ struct btrfs_fs_context {
|
|||
unsigned long long mount_opt;
|
||||
unsigned long compress_type:4;
|
||||
int compress_level;
|
||||
int use_backup_slot;
|
||||
refcount_t refs;
|
||||
};
|
||||
|
||||
|
|
@ -175,6 +176,10 @@ static const struct constant_table btrfs_parameter_space_cache[] = {
|
|||
|
||||
enum {
|
||||
Opt_rescue_usebackuproot,
|
||||
Opt_rescue_usebackup_slot_0,
|
||||
Opt_rescue_usebackup_slot_1,
|
||||
Opt_rescue_usebackup_slot_2,
|
||||
Opt_rescue_usebackup_slot_3,
|
||||
Opt_rescue_nologreplay,
|
||||
Opt_rescue_ignorebadroots,
|
||||
Opt_rescue_ignoredatacsums,
|
||||
|
|
@ -185,6 +190,10 @@ enum {
|
|||
|
||||
static const struct constant_table btrfs_parameter_rescue[] = {
|
||||
{ "usebackuproot", Opt_rescue_usebackuproot },
|
||||
{ "usebackuproot_0", Opt_rescue_usebackup_slot_0},
|
||||
{ "usebackuproot_1", Opt_rescue_usebackup_slot_1},
|
||||
{ "usebackuproot_2", Opt_rescue_usebackup_slot_2},
|
||||
{ "usebackuproot_3", Opt_rescue_usebackup_slot_3},
|
||||
{ "nologreplay", Opt_rescue_nologreplay },
|
||||
{ "ignorebadroots", Opt_rescue_ignorebadroots },
|
||||
{ "ibadroots", Opt_rescue_ignorebadroots },
|
||||
|
|
@ -588,6 +597,14 @@ static int btrfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||
switch (result.uint_32) {
|
||||
case Opt_rescue_usebackuproot:
|
||||
btrfs_set_opt(ctx->mount_opt, USEBACKUPROOT);
|
||||
ctx->use_backup_slot = 1;
|
||||
break;
|
||||
case Opt_rescue_usebackup_slot_0:
|
||||
case Opt_rescue_usebackup_slot_1:
|
||||
case Opt_rescue_usebackup_slot_2:
|
||||
case Opt_rescue_usebackup_slot_3:
|
||||
btrfs_set_opt(ctx->mount_opt, USEBACKUPROOT);
|
||||
ctx->use_backup_slot = result.uint_32 - Opt_rescue_usebackup_slot_0;
|
||||
break;
|
||||
case Opt_rescue_nologreplay:
|
||||
btrfs_set_opt(ctx->mount_opt, NOLOGREPLAY);
|
||||
|
|
@ -611,6 +628,7 @@ static int btrfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||
btrfs_set_opt(ctx->mount_opt, IGNOREBADROOTS);
|
||||
btrfs_set_opt(ctx->mount_opt, NOLOGREPLAY);
|
||||
btrfs_set_opt(ctx->mount_opt, USEBACKUPROOT);
|
||||
ctx->use_backup_slot = 1;
|
||||
break;
|
||||
default:
|
||||
btrfs_info(NULL, "unrecognized rescue option '%s'",
|
||||
|
|
@ -1089,8 +1107,11 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
|
|||
seq_puts(seq, ",notreelog");
|
||||
if (btrfs_test_opt(info, NOLOGREPLAY))
|
||||
print_rescue_option(seq, "nologreplay", &printed);
|
||||
if (btrfs_test_opt(info, USEBACKUPROOT))
|
||||
print_rescue_option(seq, "usebackuproot", &printed);
|
||||
if (btrfs_test_opt(info, USEBACKUPROOT)) {
|
||||
seq_printf(seq, "%susebackuproot_%d", printed ? ":" : ",rescue=",
|
||||
info->use_backup_slot);
|
||||
printed = true;
|
||||
}
|
||||
if (btrfs_test_opt(info, IGNOREBADROOTS))
|
||||
print_rescue_option(seq, "ignorebadroots", &printed);
|
||||
if (btrfs_test_opt(info, IGNOREDATACSUMS))
|
||||
|
|
@ -1406,6 +1427,7 @@ static void btrfs_ctx_to_info(struct btrfs_fs_info *fs_info, struct btrfs_fs_con
|
|||
fs_info->mount_opt = ctx->mount_opt;
|
||||
fs_info->compress_type = ctx->compress_type;
|
||||
fs_info->compress_level = ctx->compress_level;
|
||||
fs_info->use_backup_slot = ctx->use_backup_slot;
|
||||
}
|
||||
|
||||
static void btrfs_info_to_ctx(struct btrfs_fs_info *fs_info, struct btrfs_fs_context *ctx)
|
||||
|
|
@ -1417,6 +1439,7 @@ static void btrfs_info_to_ctx(struct btrfs_fs_info *fs_info, struct btrfs_fs_con
|
|||
ctx->mount_opt = fs_info->mount_opt;
|
||||
ctx->compress_type = fs_info->compress_type;
|
||||
ctx->compress_level = fs_info->compress_level;
|
||||
ctx->use_backup_slot = fs_info->use_backup_slot;
|
||||
}
|
||||
|
||||
#define btrfs_info_if_set(fs_info, old_ctx, opt, fmt, args...) \
|
||||
|
|
@ -2209,6 +2232,7 @@ static int btrfs_init_fs_context(struct fs_context *fc)
|
|||
if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
|
||||
btrfs_info_to_ctx(btrfs_sb(fc->root->d_sb), ctx);
|
||||
} else {
|
||||
ctx->use_backup_slot = -1;
|
||||
ctx->thread_pool_size =
|
||||
min_t(unsigned long, num_online_cpus() + 2, 8);
|
||||
ctx->max_inline = BTRFS_DEFAULT_MAX_INLINE;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user