Skip to content

Commit 64e3702

Browse files
Gao Xianggregkh
authored andcommitted
staging: erofs: add requirements field in superblock
commit 5efe513 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: ba2b77a ("staging: erofs: add super block operations") Cc: <stable@vger.kernel.org> # 4.19+ Reviewed-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Gao Xiang <gaoxiang25@huawei.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e6803ce commit 64e3702

3 files changed

Lines changed: 31 additions & 3 deletions

File tree

drivers/staging/erofs/erofs_fs.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@
1717
#define EROFS_SUPER_MAGIC_V1 0xE0F5E1E2
1818
#define EROFS_SUPER_OFFSET 1024
1919

20+
/*
21+
* Any bits that aren't in EROFS_ALL_REQUIREMENTS should be
22+
* incompatible with this kernel version.
23+
*/
24+
#define EROFS_ALL_REQUIREMENTS 0
25+
2026
struct erofs_super_block {
2127
/* 0 */__le32 magic; /* in the little endian */
2228
/* 4 */__le32 checksum; /* crc32c(super_block) */
23-
/* 8 */__le32 features;
29+
/* 8 */__le32 features; /* (aka. feature_compat) */
2430
/* 12 */__u8 blkszbits; /* support block_size == PAGE_SIZE only */
2531
/* 13 */__u8 reserved;
2632

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

38-
/* 80 */__u8 reserved2[48]; /* 128 bytes */
39-
} __packed;
45+
/* 84 */__u8 reserved2[44];
46+
} __packed; /* 128 bytes */
4047

4148
#define __EROFS_BIT(_prefix, _cur, _pre) enum { \
4249
_prefix ## _cur ## _BIT = _prefix ## _pre ## _BIT + \

drivers/staging/erofs/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ struct erofs_sb_info {
111111

112112
u8 uuid[16]; /* 128-bit uuid for volume */
113113
u8 volume_name[16]; /* volume name */
114+
u32 requirements;
115+
114116
char *dev_name;
115117

116118
unsigned int mount_opt;

drivers/staging/erofs/super.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ static void destroy_inode(struct inode *inode)
7575
call_rcu(&inode->i_rcu, i_callback);
7676
}
7777

78+
static bool check_layout_compatibility(struct super_block *sb,
79+
struct erofs_super_block *layout)
80+
{
81+
const unsigned int requirements = le32_to_cpu(layout->requirements);
82+
83+
EROFS_SB(sb)->requirements = requirements;
84+
85+
/* check if current kernel meets all mandatory requirements */
86+
if (requirements & (~EROFS_ALL_REQUIREMENTS)) {
87+
errln("unidentified requirements %x, please upgrade kernel version",
88+
requirements & ~EROFS_ALL_REQUIREMENTS);
89+
return false;
90+
}
91+
return true;
92+
}
93+
7894
static int superblock_read(struct super_block *sb)
7995
{
8096
struct erofs_sb_info *sbi;
@@ -108,6 +124,9 @@ static int superblock_read(struct super_block *sb)
108124
goto out;
109125
}
110126

127+
if (!check_layout_compatibility(sb, layout))
128+
goto out;
129+
111130
sbi->blocks = le32_to_cpu(layout->blocks);
112131
sbi->meta_blkaddr = le32_to_cpu(layout->meta_blkaddr);
113132
#ifdef CONFIG_EROFS_FS_XATTR

0 commit comments

Comments
 (0)