forked from mirrors/linux
		
	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 <josef@toxicpanda.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									169aaaf2e0
								
							
						
					
					
						commit
						32e6216512
					
				
					 4 changed files with 26 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -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",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -177,6 +177,7 @@ enum {
 | 
			
		|||
	Opt_rescue_ignorebadroots,
 | 
			
		||||
	Opt_rescue_ignoredatacsums,
 | 
			
		||||
	Opt_rescue_ignoremetacsums,
 | 
			
		||||
	Opt_rescue_ignoresuperflags,
 | 
			
		||||
	Opt_rescue_parameter_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 },
 | 
			
		||||
	{}
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			@ -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) &&
 | 
			
		||||
| 
						 | 
				
			
			@ -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))
 | 
			
		||||
| 
						 | 
				
			
			@ -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");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -386,6 +386,7 @@ static const char *rescue_opts[] = {
 | 
			
		|||
	"ignorebadroots",
 | 
			
		||||
	"ignoredatacsums",
 | 
			
		||||
	"ignoremetacsums",
 | 
			
		||||
	"ignoresuperflags",
 | 
			
		||||
	"all",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue