Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64e37023 authored by Gao Xiang's avatar Gao Xiang Committed by Greg Kroah-Hartman
Browse files

staging: erofs: add requirements field in superblock



commit 5efe5137f05bbb4688890620934538c005e7d1d6 upstream.

There are some backward incompatible features pending
for months, mainly due to on-disk format expensions.

However, we should ensure that it cannot be mounted with
old kernels. Otherwise, it will causes unexpected behaviors.

Fixes: ba2b77a8 ("staging: erofs: add super block operations")
Cc: <stable@vger.kernel.org> # 4.19+
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarGao Xiang <gaoxiang25@huawei.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e6803ce3
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -17,10 +17,16 @@
#define EROFS_SUPER_MAGIC_V1    0xE0F5E1E2
#define EROFS_SUPER_OFFSET      1024

/*
 * Any bits that aren't in EROFS_ALL_REQUIREMENTS should be
 * incompatible with this kernel version.
 */
#define EROFS_ALL_REQUIREMENTS  0

struct erofs_super_block {
/*  0 */__le32 magic;           /* in the little endian */
/*  4 */__le32 checksum;        /* crc32c(super_block) */
/*  8 */__le32 features;
/*  8 */__le32 features;        /* (aka. feature_compat) */
/* 12 */__u8 blkszbits;         /* support block_size == PAGE_SIZE only */
/* 13 */__u8 reserved;

@@ -34,9 +40,10 @@ struct erofs_super_block {
/* 44 */__le32 xattr_blkaddr;
/* 48 */__u8 uuid[16];          /* 128-bit uuid for volume */
/* 64 */__u8 volume_name[16];   /* volume name */
/* 80 */__le32 requirements;    /* (aka. feature_incompat) */

/* 80 */__u8 reserved2[48];     /* 128 bytes */
} __packed;
/* 84 */__u8 reserved2[44];
} __packed;                     /* 128 bytes */

#define __EROFS_BIT(_prefix, _cur, _pre)	enum {	\
	_prefix ## _cur ## _BIT = _prefix ## _pre ## _BIT + \
+2 −0
Original line number Diff line number Diff line
@@ -111,6 +111,8 @@ struct erofs_sb_info {

	u8 uuid[16];                    /* 128-bit uuid for volume */
	u8 volume_name[16];             /* volume name */
	u32 requirements;

	char *dev_name;

	unsigned int mount_opt;
+19 −0
Original line number Diff line number Diff line
@@ -75,6 +75,22 @@ static void destroy_inode(struct inode *inode)
	call_rcu(&inode->i_rcu, i_callback);
}

static bool check_layout_compatibility(struct super_block *sb,
				       struct erofs_super_block *layout)
{
	const unsigned int requirements = le32_to_cpu(layout->requirements);

	EROFS_SB(sb)->requirements = requirements;

	/* check if current kernel meets all mandatory requirements */
	if (requirements & (~EROFS_ALL_REQUIREMENTS)) {
		errln("unidentified requirements %x, please upgrade kernel version",
		      requirements & ~EROFS_ALL_REQUIREMENTS);
		return false;
	}
	return true;
}

static int superblock_read(struct super_block *sb)
{
	struct erofs_sb_info *sbi;
@@ -108,6 +124,9 @@ static int superblock_read(struct super_block *sb)
		goto out;
	}

	if (!check_layout_compatibility(sb, layout))
		goto out;

	sbi->blocks = le32_to_cpu(layout->blocks);
	sbi->meta_blkaddr = le32_to_cpu(layout->meta_blkaddr);
#ifdef CONFIG_EROFS_FS_XATTR