Skip to content

Commit

Permalink
btrfs: introduce new "rescue=ignoresuperflags" mount option
Browse files Browse the repository at this point in the history
This new mount option allows the kernel to skip the super flags check,
it's mostly to allow the kernel to do a rescue mount of an interrupted
checksum conversion.

Reviewed-by: Josef Bacik <[email protected]>
Signed-off-by: Qu Wenruo <[email protected]>
Reviewed-by: David Sterba <[email protected]>
Signed-off-by: David Sterba <[email protected]>
  • Loading branch information
adam900710 authored and kdave committed Jun 28, 2024
1 parent 7800eac commit a817d1a
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 5 deletions.
16 changes: 12 additions & 4 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2345,15 +2345,23 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
u64 nodesize = btrfs_super_nodesize(sb);
u64 sectorsize = btrfs_super_sectorsize(sb);
int ret = 0;
const bool ignore_flags = btrfs_test_opt(fs_info, IGNORESUPERFLAGS);

if (btrfs_super_magic(sb) != BTRFS_MAGIC) {
btrfs_err(fs_info, "no valid FS found");
ret = -EINVAL;
}
if (btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP) {
btrfs_err(fs_info, "unrecognized or unsupported super flag: 0x%llx",
btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP);
ret = -EINVAL;
if ((btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP)) {
if (!ignore_flags) {
btrfs_err(fs_info,
"unrecognized or unsupported super flag 0x%llx",
btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP);
ret = -EINVAL;
} else {
btrfs_info(fs_info,
"unrecognized or unsupported super flags: 0x%llx, ignored",
btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP);
}
}
if (btrfs_super_root_level(sb) >= BTRFS_MAX_LEVEL) {
btrfs_err(fs_info, "tree_root level too big: %d >= %d",
Expand Down
1 change: 1 addition & 0 deletions fs/btrfs/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ enum {
BTRFS_MOUNT_NODISCARD = (1UL << 29),
BTRFS_MOUNT_NOSPACECACHE = (1UL << 30),
BTRFS_MOUNT_IGNOREMETACSUMS = (1UL << 31),
BTRFS_MOUNT_IGNORESUPERFLAGS = (1ULL << 32),
};

/*
Expand Down
13 changes: 12 additions & 1 deletion fs/btrfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ enum {
Opt_rescue_ignorebadroots,
Opt_rescue_ignoredatacsums,
Opt_rescue_ignoremetacsums,
Opt_rescue_ignoresuperflags,
Opt_rescue_parameter_all,
};

Expand All @@ -187,8 +188,10 @@ static const struct constant_table btrfs_parameter_rescue[] = {
{ "ibadroots", Opt_rescue_ignorebadroots },
{ "ignoredatacsums", Opt_rescue_ignoredatacsums },
{ "ignoremetacsums", Opt_rescue_ignoremetacsums},
{ "ignoresuperflags", Opt_rescue_ignoresuperflags},
{ "idatacsums", Opt_rescue_ignoredatacsums },
{ "imetacsums", Opt_rescue_ignoremetacsums},
{ "isuperflags", Opt_rescue_ignoresuperflags},
{ "all", Opt_rescue_parameter_all },
{}
};
Expand Down Expand Up @@ -577,9 +580,13 @@ static int btrfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
case Opt_rescue_ignoremetacsums:
btrfs_set_opt(ctx->mount_opt, IGNOREMETACSUMS);
break;
case Opt_rescue_ignoresuperflags:
btrfs_set_opt(ctx->mount_opt, IGNORESUPERFLAGS);
break;
case Opt_rescue_parameter_all:
btrfs_set_opt(ctx->mount_opt, IGNOREDATACSUMS);
btrfs_set_opt(ctx->mount_opt, IGNOREMETACSUMS);
btrfs_set_opt(ctx->mount_opt, IGNORESUPERFLAGS);
btrfs_set_opt(ctx->mount_opt, IGNOREBADROOTS);
btrfs_set_opt(ctx->mount_opt, NOLOGREPLAY);
break;
Expand Down Expand Up @@ -655,7 +662,8 @@ bool btrfs_check_options(const struct btrfs_fs_info *info, unsigned long *mount_
(check_ro_option(info, *mount_opt, BTRFS_MOUNT_NOLOGREPLAY, "nologreplay") ||
check_ro_option(info, *mount_opt, BTRFS_MOUNT_IGNOREBADROOTS, "ignorebadroots") ||
check_ro_option(info, *mount_opt, BTRFS_MOUNT_IGNOREDATACSUMS, "ignoredatacsums") ||
check_ro_option(info, *mount_opt, BTRFS_MOUNT_IGNOREMETACSUMS, "ignoremetacsums")))
check_ro_option(info, *mount_opt, BTRFS_MOUNT_IGNOREMETACSUMS, "ignoremetacsums") ||
check_ro_option(info, *mount_opt, BTRFS_MOUNT_IGNORESUPERFLAGS, "ignoresuperflags")))
ret = false;

if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE) &&
Expand Down Expand Up @@ -1073,6 +1081,8 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
print_rescue_option(seq, "ignoredatacsums", &printed);
if (btrfs_test_opt(info, IGNOREMETACSUMS))
print_rescue_option(seq, "ignoremetacsums", &printed);
if (btrfs_test_opt(info, IGNORESUPERFLAGS))
print_rescue_option(seq, "ignoresuperflags", &printed);
if (btrfs_test_opt(info, FLUSHONCOMMIT))
seq_puts(seq, ",flushoncommit");
if (btrfs_test_opt(info, DISCARD_SYNC))
Expand Down Expand Up @@ -1431,6 +1441,7 @@ static void btrfs_emit_options(struct btrfs_fs_info *info,
btrfs_info_if_set(info, old, IGNOREBADROOTS, "ignoring bad roots");
btrfs_info_if_set(info, old, IGNOREDATACSUMS, "ignoring data csums");
btrfs_info_if_set(info, old, IGNOREMETACSUMS, "ignoring meta csums");
btrfs_info_if_set(info, old, IGNORESUPERFLAGS, "ignoring unknown super block flags");

btrfs_info_if_unset(info, old, NODATACOW, "setting datacow");
btrfs_info_if_unset(info, old, SSD, "not using ssd optimizations");
Expand Down
1 change: 1 addition & 0 deletions fs/btrfs/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ static const char *rescue_opts[] = {
"ignorebadroots",
"ignoredatacsums",
"ignoremetacsums",
"ignoresuperflags",
"all",
};

Expand Down

0 comments on commit a817d1a

Please sign in to comment.