Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ext4: Replace open coded mdata csum feature to helper function

Besides the fact that this replacement improves code readability
it also protects from errors caused direct EXT4_S(sb)->s_es manipulation
which may result attempt to use uninitialized csum machinery.

#Testcase_BEGIN
IMG=/dev/ram0
MNT=/mnt
mkfs.ext4 $IMG
mount $IMG $MNT
#Enable feature directly on disk, on mounted fs
tune2fs -O metadata_csum $IMG
# Provoke metadata update, likey result in OOPS
touch $MNT/test
umount $MNT
#Testcase_END

# Replacement script
@@
expression E;
@@
- EXT4_HAS_RO_COMPAT_FEATURE(E, EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)
+ ext4_has_metadata_csum(E)

https://bugzilla.kernel.org/show_bug.cgi?id=82201

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@vger.kernel.org

authored by

Dmitry Monakhov and committed by
Theodore Ts'o
9aa5d32b 65dd8327

+43 -70
+4 -8
fs/ext4/bitmap.c
··· 24 24 __u32 provided, calculated; 25 25 struct ext4_sb_info *sbi = EXT4_SB(sb); 26 26 27 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 28 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 27 + if (!ext4_has_metadata_csum(sb)) 29 28 return 1; 30 29 31 30 provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo); ··· 45 46 __u32 csum; 46 47 struct ext4_sb_info *sbi = EXT4_SB(sb); 47 48 48 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 49 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 49 + if (!ext4_has_metadata_csum(sb)) 50 50 return; 51 51 52 52 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); ··· 63 65 struct ext4_sb_info *sbi = EXT4_SB(sb); 64 66 int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; 65 67 66 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 67 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 68 + if (!ext4_has_metadata_csum(sb)) 68 69 return 1; 69 70 70 71 provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo); ··· 88 91 __u32 csum; 89 92 struct ext4_sb_info *sbi = EXT4_SB(sb); 90 93 91 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 92 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 94 + if (!ext4_has_metadata_csum(sb)) 93 95 return; 94 96 95 97 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
+8
fs/ext4/ext4.h
··· 2337 2337 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM); 2338 2338 } 2339 2339 2340 + static inline int ext4_has_metadata_csum(struct super_block *sb) 2341 + { 2342 + WARN_ON_ONCE(EXT4_HAS_RO_COMPAT_FEATURE(sb, 2343 + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) && 2344 + !EXT4_SB(sb)->s_chksum_driver); 2345 + 2346 + return (EXT4_SB(sb)->s_chksum_driver != NULL); 2347 + } 2340 2348 static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) 2341 2349 { 2342 2350 return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
+2 -4
fs/ext4/extents.c
··· 73 73 { 74 74 struct ext4_extent_tail *et; 75 75 76 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 77 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 76 + if (!ext4_has_metadata_csum(inode->i_sb)) 78 77 return 1; 79 78 80 79 et = find_ext4_extent_tail(eh); ··· 87 88 { 88 89 struct ext4_extent_tail *et; 89 90 90 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 91 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 91 + if (!ext4_has_metadata_csum(inode->i_sb)) 92 92 return; 93 93 94 94 et = find_ext4_extent_tail(eh);
+1 -2
fs/ext4/ialloc.c
··· 1011 1011 spin_unlock(&sbi->s_next_gen_lock); 1012 1012 1013 1013 /* Precompute checksum seed for inode metadata */ 1014 - if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 1015 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) { 1014 + if (ext4_has_metadata_csum(sb)) { 1016 1015 __u32 csum; 1017 1016 __le32 inum = cpu_to_le32(inode->i_ino); 1018 1017 __le32 gen = cpu_to_le32(inode->i_generation);
+1 -2
fs/ext4/inline.c
··· 1128 1128 memcpy((void *)de, buf + EXT4_INLINE_DOTDOT_SIZE, 1129 1129 inline_size - EXT4_INLINE_DOTDOT_SIZE); 1130 1130 1131 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 1132 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 1131 + if (ext4_has_metadata_csum(inode->i_sb)) 1133 1132 csum_size = sizeof(struct ext4_dir_entry_tail); 1134 1133 1135 1134 inode->i_size = inode->i_sb->s_blocksize;
+3 -6
fs/ext4/inode.c
··· 83 83 84 84 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != 85 85 cpu_to_le32(EXT4_OS_LINUX) || 86 - !EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 87 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 86 + !ext4_has_metadata_csum(inode->i_sb)) 88 87 return 1; 89 88 90 89 provided = le16_to_cpu(raw->i_checksum_lo); ··· 104 105 105 106 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != 106 107 cpu_to_le32(EXT4_OS_LINUX) || 107 - !EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 108 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 108 + !ext4_has_metadata_csum(inode->i_sb)) 109 109 return; 110 110 111 111 csum = ext4_inode_csum(inode, raw, ei); ··· 3926 3928 ei->i_extra_isize = 0; 3927 3929 3928 3930 /* Precompute checksum seed for inode metadata */ 3929 - if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 3930 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) { 3931 + if (ext4_has_metadata_csum(sb)) { 3931 3932 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 3932 3933 __u32 csum; 3933 3934 __le32 inum = cpu_to_le32(inode->i_ino);
+1 -2
fs/ext4/ioctl.c
··· 331 331 if (!inode_owner_or_capable(inode)) 332 332 return -EPERM; 333 333 334 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 335 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) { 334 + if (ext4_has_metadata_csum(inode->i_sb)) { 336 335 ext4_warning(sb, "Setting inode version is not " 337 336 "supported with metadata_csum enabled."); 338 337 return -ENOTTY;
+2 -4
fs/ext4/mmp.c
··· 20 20 21 21 static int ext4_mmp_csum_verify(struct super_block *sb, struct mmp_struct *mmp) 22 22 { 23 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 24 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 23 + if (!ext4_has_metadata_csum(sb)) 25 24 return 1; 26 25 27 26 return mmp->mmp_checksum == ext4_mmp_csum(sb, mmp); ··· 28 29 29 30 static void ext4_mmp_csum_set(struct super_block *sb, struct mmp_struct *mmp) 30 31 { 31 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 32 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 32 + if (!ext4_has_metadata_csum(sb)) 33 33 return; 34 34 35 35 mmp->mmp_checksum = ext4_mmp_csum(sb, mmp);
+13 -26
fs/ext4/namei.c
··· 124 124 "directory leaf block found instead of index block"); 125 125 return ERR_PTR(-EIO); 126 126 } 127 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 128 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) || 127 + if (!ext4_has_metadata_csum(inode->i_sb) || 129 128 buffer_verified(bh)) 130 129 return bh; 131 130 ··· 337 338 { 338 339 struct ext4_dir_entry_tail *t; 339 340 340 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 341 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 341 + if (!ext4_has_metadata_csum(inode->i_sb)) 342 342 return 1; 343 343 344 344 t = get_dirent_tail(inode, dirent); ··· 358 360 { 359 361 struct ext4_dir_entry_tail *t; 360 362 361 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 362 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 363 + if (!ext4_has_metadata_csum(inode->i_sb)) 363 364 return; 364 365 365 366 t = get_dirent_tail(inode, dirent); ··· 433 436 struct dx_tail *t; 434 437 int count_offset, limit, count; 435 438 436 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 437 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 439 + if (!ext4_has_metadata_csum(inode->i_sb)) 438 440 return 1; 439 441 440 442 c = get_dx_countlimit(inode, dirent, &count_offset); ··· 462 466 struct dx_tail *t; 463 467 int count_offset, limit, count; 464 468 465 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 466 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 469 + if (!ext4_has_metadata_csum(inode->i_sb)) 467 470 return; 468 471 469 472 c = get_dx_countlimit(inode, dirent, &count_offset); ··· 550 555 unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(1) - 551 556 EXT4_DIR_REC_LEN(2) - infosize; 552 557 553 - if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb, 554 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 558 + if (ext4_has_metadata_csum(dir->i_sb)) 555 559 entry_space -= sizeof(struct dx_tail); 556 560 return entry_space / sizeof(struct dx_entry); 557 561 } ··· 559 565 { 560 566 unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0); 561 567 562 - if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb, 563 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 568 + if (ext4_has_metadata_csum(dir->i_sb)) 564 569 entry_space -= sizeof(struct dx_tail); 565 570 return entry_space / sizeof(struct dx_entry); 566 571 } ··· 1517 1524 int csum_size = 0; 1518 1525 int err = 0, i; 1519 1526 1520 - if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb, 1521 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 1527 + if (ext4_has_metadata_csum(dir->i_sb)) 1522 1528 csum_size = sizeof(struct ext4_dir_entry_tail); 1523 1529 1524 1530 bh2 = ext4_append(handle, dir, &newblock); ··· 1683 1691 int csum_size = 0; 1684 1692 int err; 1685 1693 1686 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 1687 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 1694 + if (ext4_has_metadata_csum(inode->i_sb)) 1688 1695 csum_size = sizeof(struct ext4_dir_entry_tail); 1689 1696 1690 1697 if (!de) { ··· 1750 1759 struct fake_dirent *fde; 1751 1760 int csum_size = 0; 1752 1761 1753 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 1754 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 1762 + if (ext4_has_metadata_csum(inode->i_sb)) 1755 1763 csum_size = sizeof(struct ext4_dir_entry_tail); 1756 1764 1757 1765 blocksize = dir->i_sb->s_blocksize; ··· 1867 1877 ext4_lblk_t block, blocks; 1868 1878 int csum_size = 0; 1869 1879 1870 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 1871 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 1880 + if (ext4_has_metadata_csum(inode->i_sb)) 1872 1881 csum_size = sizeof(struct ext4_dir_entry_tail); 1873 1882 1874 1883 sb = dir->i_sb; ··· 2131 2142 return err; 2132 2143 } 2133 2144 2134 - if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb, 2135 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 2145 + if (ext4_has_metadata_csum(dir->i_sb)) 2136 2146 csum_size = sizeof(struct ext4_dir_entry_tail); 2137 2147 2138 2148 BUFFER_TRACE(bh, "get_write_access"); ··· 2350 2362 int csum_size = 0; 2351 2363 int err; 2352 2364 2353 - if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb, 2354 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 2365 + if (ext4_has_metadata_csum(dir->i_sb)) 2355 2366 csum_size = sizeof(struct ext4_dir_entry_tail); 2356 2367 2357 2368 if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
+1 -2
fs/ext4/resize.c
··· 1210 1210 { 1211 1211 struct buffer_head *bh; 1212 1212 1213 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 1214 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 1213 + if (!ext4_has_metadata_csum(sb)) 1215 1214 return 0; 1216 1215 1217 1216 bh = ext4_get_bitmap(sb, group_data->inode_bitmap);
+5 -10
fs/ext4/super.c
··· 140 140 static int ext4_superblock_csum_verify(struct super_block *sb, 141 141 struct ext4_super_block *es) 142 142 { 143 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 144 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 143 + if (!ext4_has_metadata_csum(sb)) 145 144 return 1; 146 145 147 146 return es->s_checksum == ext4_superblock_csum(sb, es); ··· 150 151 { 151 152 struct ext4_super_block *es = EXT4_SB(sb)->s_es; 152 153 153 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 154 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 154 + if (!ext4_has_metadata_csum(sb)) 155 155 return; 156 156 157 157 es->s_checksum = ext4_superblock_csum(sb, es); ··· 1987 1989 __u16 crc = 0; 1988 1990 __le32 le_group = cpu_to_le32(block_group); 1989 1991 1990 - if ((sbi->s_es->s_feature_ro_compat & 1991 - cpu_to_le32(EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))) { 1992 + if (ext4_has_metadata_csum(sbi->s_sb)) { 1992 1993 /* Use new metadata_csum algorithm */ 1993 1994 __le16 save_csum; 1994 1995 __u32 csum32; ··· 3196 3199 int compat, incompat; 3197 3200 struct ext4_sb_info *sbi = EXT4_SB(sb); 3198 3201 3199 - if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 3200 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) { 3202 + if (ext4_has_metadata_csum(sb)) { 3201 3203 /* journal checksum v3 */ 3202 3204 compat = 0; 3203 3205 incompat = JBD2_FEATURE_INCOMPAT_CSUM_V3; ··· 3504 3508 } 3505 3509 3506 3510 /* Precompute checksum seed for all metadata */ 3507 - if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 3508 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 3511 + if (ext4_has_metadata_csum(sb)) 3509 3512 sbi->s_csum_seed = ext4_chksum(sbi, ~0, es->s_uuid, 3510 3513 sizeof(es->s_uuid)); 3511 3514
+2 -4
fs/ext4/xattr.c
··· 142 142 sector_t block_nr, 143 143 struct ext4_xattr_header *hdr) 144 144 { 145 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 146 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) && 145 + if (ext4_has_metadata_csum(inode->i_sb) && 147 146 (hdr->h_checksum != ext4_xattr_block_csum(inode, block_nr, hdr))) 148 147 return 0; 149 148 return 1; ··· 152 153 sector_t block_nr, 153 154 struct ext4_xattr_header *hdr) 154 155 { 155 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 156 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 156 + if (!ext4_has_metadata_csum(inode->i_sb)) 157 157 return; 158 158 159 159 hdr->h_checksum = ext4_xattr_block_csum(inode, block_nr, hdr);