Add cc:stable@vger.kernel org tags
[ext4-patch-queue.git] / check-s_chksum_driver-when-looking-for-bg-csum-presence
blob2a1be6544f443ddd7de6525e9555068c6f484e87
1 ext4: check s_chksum_driver when looking for bg csum presence
3 From: "Darrick J. Wong" <darrick.wong@oracle.com>
5 Convert the ext4_has_group_desc_csum predicate to look for a checksum
6 driver instead of the metadata_csum flag and change the bg checksum
7 calculation function to look for GDT_CSUM before taking the crc16
8 path.
10 Without this patch, if we mount with ^uninit_bg,^metadata_csum and
11 later metadata_csum gets turned on by accident, the block group
12 checksum functions will incorrectly assume that checksumming is
13 enabled (metadata_csum) but that crc16 should be used
14 (!s_chksum_driver).  This is totally wrong, so fix the predicate
15 and the checksum formula selection.
17 (Granted, if the metadata_csum feature bit gets enabled on a live FS
18 then something underhanded is going on, but we could at least avoid
19 writing garbage into the on-disk fields.)
21 Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
22 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
23 Reviewed-by: Dmitry Monakhov <dmonakhov@openvz.org>
24 Cc: stable@vger.kernel.org
25 ---
26  fs/ext4/ext4.h  |    4 ++--
27  fs/ext4/super.c |    4 ++++
28  2 files changed, 6 insertions(+), 2 deletions(-)
30 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
31 index fb6aadf..db38ca0f 100644
32 --- a/fs/ext4/ext4.h
33 +++ b/fs/ext4/ext4.h
34 @@ -2367,8 +2367,8 @@ extern int ext4_register_li_request(struct super_block *sb,
35  static inline int ext4_has_group_desc_csum(struct super_block *sb)
36  {
37         return EXT4_HAS_RO_COMPAT_FEATURE(sb,
38 -                                         EXT4_FEATURE_RO_COMPAT_GDT_CSUM |
39 -                                         EXT4_FEATURE_RO_COMPAT_METADATA_CSUM);
40 +                                         EXT4_FEATURE_RO_COMPAT_GDT_CSUM) ||
41 +              (EXT4_SB(sb)->s_chksum_driver != NULL);
42  }
44  static inline int ext4_has_metadata_csum(struct super_block *sb)
45 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
46 index 6ae47d4..de38a96 100644
47 --- a/fs/ext4/super.c
48 +++ b/fs/ext4/super.c
49 @@ -2032,6 +2032,10 @@ static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
50         }
52         /* old crc16 code */
53 +       if (!(sbi->s_es->s_feature_ro_compat &
54 +             cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)))
55 +               return 0;
57         offset = offsetof(struct ext4_group_desc, bg_checksum);
59         crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));