Skip to content

Commit a817d1a

Browse files
adam900710kdave
authored andcommitted
btrfs: introduce new "rescue=ignoresuperflags" mount option
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]>
1 parent 7800eac commit a817d1a

File tree

4 files changed

+26
-5
lines changed

4 files changed

+26
-5
lines changed

Diff for: fs/btrfs/disk-io.c

+12-4
Original file line numberDiff line numberDiff line change
@@ -2345,15 +2345,23 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
23452345
u64 nodesize = btrfs_super_nodesize(sb);
23462346
u64 sectorsize = btrfs_super_sectorsize(sb);
23472347
int ret = 0;
2348+
const bool ignore_flags = btrfs_test_opt(fs_info, IGNORESUPERFLAGS);
23482349

23492350
if (btrfs_super_magic(sb) != BTRFS_MAGIC) {
23502351
btrfs_err(fs_info, "no valid FS found");
23512352
ret = -EINVAL;
23522353
}
2353-
if (btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP) {
2354-
btrfs_err(fs_info, "unrecognized or unsupported super flag: 0x%llx",
2355-
btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP);
2356-
ret = -EINVAL;
2354+
if ((btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP)) {
2355+
if (!ignore_flags) {
2356+
btrfs_err(fs_info,
2357+
"unrecognized or unsupported super flag 0x%llx",
2358+
btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP);
2359+
ret = -EINVAL;
2360+
} else {
2361+
btrfs_info(fs_info,
2362+
"unrecognized or unsupported super flags: 0x%llx, ignored",
2363+
btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP);
2364+
}
23572365
}
23582366
if (btrfs_super_root_level(sb) >= BTRFS_MAX_LEVEL) {
23592367
btrfs_err(fs_info, "tree_root level too big: %d >= %d",

Diff for: fs/btrfs/fs.h

+1
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ enum {
227227
BTRFS_MOUNT_NODISCARD = (1UL << 29),
228228
BTRFS_MOUNT_NOSPACECACHE = (1UL << 30),
229229
BTRFS_MOUNT_IGNOREMETACSUMS = (1UL << 31),
230+
BTRFS_MOUNT_IGNORESUPERFLAGS = (1ULL << 32),
230231
};
231232

232233
/*

Diff for: fs/btrfs/super.c

+12-1
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ enum {
177177
Opt_rescue_ignorebadroots,
178178
Opt_rescue_ignoredatacsums,
179179
Opt_rescue_ignoremetacsums,
180+
Opt_rescue_ignoresuperflags,
180181
Opt_rescue_parameter_all,
181182
};
182183

@@ -187,8 +188,10 @@ static const struct constant_table btrfs_parameter_rescue[] = {
187188
{ "ibadroots", Opt_rescue_ignorebadroots },
188189
{ "ignoredatacsums", Opt_rescue_ignoredatacsums },
189190
{ "ignoremetacsums", Opt_rescue_ignoremetacsums},
191+
{ "ignoresuperflags", Opt_rescue_ignoresuperflags},
190192
{ "idatacsums", Opt_rescue_ignoredatacsums },
191193
{ "imetacsums", Opt_rescue_ignoremetacsums},
194+
{ "isuperflags", Opt_rescue_ignoresuperflags},
192195
{ "all", Opt_rescue_parameter_all },
193196
{}
194197
};
@@ -577,9 +580,13 @@ static int btrfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
577580
case Opt_rescue_ignoremetacsums:
578581
btrfs_set_opt(ctx->mount_opt, IGNOREMETACSUMS);
579582
break;
583+
case Opt_rescue_ignoresuperflags:
584+
btrfs_set_opt(ctx->mount_opt, IGNORESUPERFLAGS);
585+
break;
580586
case Opt_rescue_parameter_all:
581587
btrfs_set_opt(ctx->mount_opt, IGNOREDATACSUMS);
582588
btrfs_set_opt(ctx->mount_opt, IGNOREMETACSUMS);
589+
btrfs_set_opt(ctx->mount_opt, IGNORESUPERFLAGS);
583590
btrfs_set_opt(ctx->mount_opt, IGNOREBADROOTS);
584591
btrfs_set_opt(ctx->mount_opt, NOLOGREPLAY);
585592
break;
@@ -655,7 +662,8 @@ bool btrfs_check_options(const struct btrfs_fs_info *info, unsigned long *mount_
655662
(check_ro_option(info, *mount_opt, BTRFS_MOUNT_NOLOGREPLAY, "nologreplay") ||
656663
check_ro_option(info, *mount_opt, BTRFS_MOUNT_IGNOREBADROOTS, "ignorebadroots") ||
657664
check_ro_option(info, *mount_opt, BTRFS_MOUNT_IGNOREDATACSUMS, "ignoredatacsums") ||
658-
check_ro_option(info, *mount_opt, BTRFS_MOUNT_IGNOREMETACSUMS, "ignoremetacsums")))
665+
check_ro_option(info, *mount_opt, BTRFS_MOUNT_IGNOREMETACSUMS, "ignoremetacsums") ||
666+
check_ro_option(info, *mount_opt, BTRFS_MOUNT_IGNORESUPERFLAGS, "ignoresuperflags")))
659667
ret = false;
660668

661669
if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE) &&
@@ -1073,6 +1081,8 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
10731081
print_rescue_option(seq, "ignoredatacsums", &printed);
10741082
if (btrfs_test_opt(info, IGNOREMETACSUMS))
10751083
print_rescue_option(seq, "ignoremetacsums", &printed);
1084+
if (btrfs_test_opt(info, IGNORESUPERFLAGS))
1085+
print_rescue_option(seq, "ignoresuperflags", &printed);
10761086
if (btrfs_test_opt(info, FLUSHONCOMMIT))
10771087
seq_puts(seq, ",flushoncommit");
10781088
if (btrfs_test_opt(info, DISCARD_SYNC))
@@ -1431,6 +1441,7 @@ static void btrfs_emit_options(struct btrfs_fs_info *info,
14311441
btrfs_info_if_set(info, old, IGNOREBADROOTS, "ignoring bad roots");
14321442
btrfs_info_if_set(info, old, IGNOREDATACSUMS, "ignoring data csums");
14331443
btrfs_info_if_set(info, old, IGNOREMETACSUMS, "ignoring meta csums");
1444+
btrfs_info_if_set(info, old, IGNORESUPERFLAGS, "ignoring unknown super block flags");
14341445

14351446
btrfs_info_if_unset(info, old, NODATACOW, "setting datacow");
14361447
btrfs_info_if_unset(info, old, SSD, "not using ssd optimizations");

Diff for: fs/btrfs/sysfs.c

+1
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ static const char *rescue_opts[] = {
386386
"ignorebadroots",
387387
"ignoredatacsums",
388388
"ignoremetacsums",
389+
"ignoresuperflags",
389390
"all",
390391
};
391392

0 commit comments

Comments
 (0)