1 ext4: don't try to modify s_flags if the the file system is read-only
3 If an ext4 file system is created by some tool other than mke2fs
4 (perhaps by someone who has a pathalogical fear of the GPL) that
5 doesn't set one or the other of the EXT2_FLAGS_{UN}SIGNED_HASH flags,
6 and that file system is then mounted read-only, don't try to modify
7 the s_flags field. Otherwise, if dm_verity is in use, the superblock
8 will change, causing an dm_verity failure.
10 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
11 Cc: stable@vger.kernel.org
13 fs/ext4/super.c | 20 +++++++++++++-------
14 1 file changed, 13 insertions(+), 7 deletions(-)
16 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
17 index 0491c81..f5c13b8 100644
20 @@ -3695,16 +3695,22 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
21 for (i = 0; i < 4; i++)
22 sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
23 sbi->s_def_hash_version = es->s_def_hash_version;
24 - i = le32_to_cpu(es->s_flags);
25 - if (i & EXT2_FLAGS_UNSIGNED_HASH)
26 - sbi->s_hash_unsigned = 3;
27 - else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
28 + if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
29 + i = le32_to_cpu(es->s_flags);
30 + if (i & EXT2_FLAGS_UNSIGNED_HASH)
31 + sbi->s_hash_unsigned = 3;
32 + else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
33 #ifdef __CHAR_UNSIGNED__
34 - es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
35 - sbi->s_hash_unsigned = 3;
36 + if (!(sb->s_flags & MS_RDONLY))
38 + cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
39 + sbi->s_hash_unsigned = 3;
41 - es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
42 + if (!(sb->s_flags & MS_RDONLY))
44 + cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
49 /* Handle clustersize */