diff mbox series

[4/4] btrfs: introduce new "rescue=ignoresuperflags" mount option

Message ID f76f3c993b70aead20d19390f430a1a03a0370c2.1718082585.git.wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: rescue= mount options enhancement to support interrupted csum conversion | expand

Commit Message

Qu Wenruo June 11, 2024, 5:21 a.m. UTC
This new mount option would allow 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.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/disk-io.c |  4 +++-
 fs/btrfs/fs.h      |  1 +
 fs/btrfs/super.c   | 13 ++++++++++++-
 3 files changed, 16 insertions(+), 2 deletions(-)

Comments

David Sterba June 12, 2024, 7:42 p.m. UTC | #1
On Tue, Jun 11, 2024 at 02:51:38PM +0930, Qu Wenruo wrote:
> This new mount option would allow 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.

This is for future-proofing but the current known super flags should be
at least defined in the kernel code and with a warning or info message.
BTRFS_SUPER_FLAG_CHANGING_FSID and _V2.

Same comment as for the imetacsum, missing sysfs.c entry.
Qu Wenruo June 13, 2024, 9:46 p.m. UTC | #2
在 2024/6/13 05:12, David Sterba 写道:
> On Tue, Jun 11, 2024 at 02:51:38PM +0930, Qu Wenruo wrote:
>> This new mount option would allow 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.
>
> This is for future-proofing but the current known super flags should be
> at least defined in the kernel code

That's already done in this patch:

https://lore.kernel.org/linux-btrfs/57b836631f9c5dcb24ace616bdb76a37b8d084b2.1717818761.git.wqu@suse.com/T/#u

> and with a warning or info message.
> BTRFS_SUPER_FLAG_CHANGING_FSID and _V2.

I can add some extra warning messages, but currently we do not do any
messages for rescue mount options at all, since user is definitely aware
of some problems then go with rescue.
(And rescue has to be paired with ro, which should already rejected the
mount once when tried without ro, thus the end user definitely knows
what they are doing)

Thus I'm more or less fine without any error messages for now.

Thanks,
Qu
>
> Same comment as for the imetacsum, missing sysfs.c entry.
>
diff mbox series

Patch

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 74ee9f335dbc..0df747646c2f 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2349,12 +2349,14 @@  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;
+	bool ignore_flags = btrfs_raw_test_opt(fs_info->mount_opt,
+						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) {
+	if (!ignore_flags && (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;
diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h
index fcef7b81f9fd..8b14df6ff96c 100644
--- a/fs/btrfs/fs.h
+++ b/fs/btrfs/fs.h
@@ -225,6 +225,7 @@  enum {
 	BTRFS_MOUNT_NODISCARD			= (1UL << 29),
 	BTRFS_MOUNT_NOSPACECACHE		= (1UL << 30),
 	BTRFS_MOUNT_IGNOREMETACSUMS		= (1UL << 31),
+	BTRFS_MOUNT_IGNORESUPERFLAGS		= (1UL << 32),
 };
 
 /*
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 386500b9b440..a66b5c901510 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -176,6 +176,7 @@  enum {
 	Opt_rescue_ignorebadroots,
 	Opt_rescue_ignoredatacsums,
 	Opt_rescue_ignoremetacsums,
+	Opt_rescue_ignoresuperflags,
 	Opt_rescue_parameter_all,
 };
 
@@ -186,8 +187,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 },
 	{}
 };
@@ -576,9 +579,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;
@@ -654,7 +661,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) &&
@@ -1072,6 +1080,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))
@@ -1430,6 +1440,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 flags");
 
 	btrfs_info_if_unset(info, old, NODATACOW, "setting datacow");
 	btrfs_info_if_unset(info, old, SSD, "not using ssd optimizations");