Skip to content

Commit 9aa5d32

Browse files
Dmitry Monakhovtytso
authored andcommitted
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
1 parent 65dd832 commit 9aa5d32

File tree

12 files changed

+43
-70
lines changed

12 files changed

+43
-70
lines changed

fs/ext4/bitmap.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
2424
__u32 provided, calculated;
2525
struct ext4_sb_info *sbi = EXT4_SB(sb);
2626

27-
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
28-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
27+
if (!ext4_has_metadata_csum(sb))
2928
return 1;
3029

3130
provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo);
@@ -46,8 +45,7 @@ void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
4645
__u32 csum;
4746
struct ext4_sb_info *sbi = EXT4_SB(sb);
4847

49-
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
50-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
48+
if (!ext4_has_metadata_csum(sb))
5149
return;
5250

5351
csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
@@ -65,8 +63,7 @@ int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
6563
struct ext4_sb_info *sbi = EXT4_SB(sb);
6664
int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
6765

68-
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
69-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
66+
if (!ext4_has_metadata_csum(sb))
7067
return 1;
7168

7269
provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo);
@@ -91,8 +88,7 @@ void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
9188
__u32 csum;
9289
struct ext4_sb_info *sbi = EXT4_SB(sb);
9390

94-
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
95-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
91+
if (!ext4_has_metadata_csum(sb))
9692
return;
9793

9894
csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);

fs/ext4/ext4.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,6 +2337,14 @@ static inline int ext4_has_group_desc_csum(struct super_block *sb)
23372337
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM);
23382338
}
23392339

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+
}
23402348
static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
23412349
{
23422350
return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |

fs/ext4/extents.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ static int ext4_extent_block_csum_verify(struct inode *inode,
7373
{
7474
struct ext4_extent_tail *et;
7575

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))
7877
return 1;
7978

8079
et = find_ext4_extent_tail(eh);
@@ -88,8 +87,7 @@ static void ext4_extent_block_csum_set(struct inode *inode,
8887
{
8988
struct ext4_extent_tail *et;
9089

91-
if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
92-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
90+
if (!ext4_has_metadata_csum(inode->i_sb))
9391
return;
9492

9593
et = find_ext4_extent_tail(eh);

fs/ext4/ialloc.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,8 +1011,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
10111011
spin_unlock(&sbi->s_next_gen_lock);
10121012

10131013
/* 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)) {
10161015
__u32 csum;
10171016
__le32 inum = cpu_to_le32(inode->i_ino);
10181017
__le32 gen = cpu_to_le32(inode->i_generation);

fs/ext4/inline.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,8 +1128,7 @@ static int ext4_finish_convert_inline_dir(handle_t *handle,
11281128
memcpy((void *)de, buf + EXT4_INLINE_DOTDOT_SIZE,
11291129
inline_size - EXT4_INLINE_DOTDOT_SIZE);
11301130

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))
11331132
csum_size = sizeof(struct ext4_dir_entry_tail);
11341133

11351134
inode->i_size = inode->i_sb->s_blocksize;

fs/ext4/inode.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ static int ext4_inode_csum_verify(struct inode *inode, struct ext4_inode *raw,
8383

8484
if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
8585
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))
8887
return 1;
8988

9089
provided = le16_to_cpu(raw->i_checksum_lo);
@@ -105,8 +104,7 @@ static void ext4_inode_csum_set(struct inode *inode, struct ext4_inode *raw,
105104

106105
if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
107106
cpu_to_le32(EXT4_OS_LINUX) ||
108-
!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
109-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
107+
!ext4_has_metadata_csum(inode->i_sb))
110108
return;
111109

112110
csum = ext4_inode_csum(inode, raw, ei);
@@ -3928,8 +3926,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
39283926
ei->i_extra_isize = 0;
39293927

39303928
/* Precompute checksum seed for inode metadata */
3931-
if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
3932-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
3929+
if (ext4_has_metadata_csum(sb)) {
39333930
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
39343931
__u32 csum;
39353932
__le32 inum = cpu_to_le32(inode->i_ino);

fs/ext4/ioctl.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
331331
if (!inode_owner_or_capable(inode))
332332
return -EPERM;
333333

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)) {
336335
ext4_warning(sb, "Setting inode version is not "
337336
"supported with metadata_csum enabled.");
338337
return -ENOTTY;

fs/ext4/mmp.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,15 @@ static __le32 ext4_mmp_csum(struct super_block *sb, struct mmp_struct *mmp)
2020

2121
static int ext4_mmp_csum_verify(struct super_block *sb, struct mmp_struct *mmp)
2222
{
23-
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
24-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
23+
if (!ext4_has_metadata_csum(sb))
2524
return 1;
2625

2726
return mmp->mmp_checksum == ext4_mmp_csum(sb, mmp);
2827
}
2928

3029
static void ext4_mmp_csum_set(struct super_block *sb, struct mmp_struct *mmp)
3130
{
32-
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
33-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
31+
if (!ext4_has_metadata_csum(sb))
3432
return;
3533

3634
mmp->mmp_checksum = ext4_mmp_csum(sb, mmp);

fs/ext4/namei.c

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
124124
"directory leaf block found instead of index block");
125125
return ERR_PTR(-EIO);
126126
}
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) ||
129128
buffer_verified(bh))
130129
return bh;
131130

@@ -338,8 +337,7 @@ int ext4_dirent_csum_verify(struct inode *inode, struct ext4_dir_entry *dirent)
338337
{
339338
struct ext4_dir_entry_tail *t;
340339

341-
if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
342-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
340+
if (!ext4_has_metadata_csum(inode->i_sb))
343341
return 1;
344342

345343
t = get_dirent_tail(inode, dirent);
@@ -360,8 +358,7 @@ static void ext4_dirent_csum_set(struct inode *inode,
360358
{
361359
struct ext4_dir_entry_tail *t;
362360

363-
if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
364-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
361+
if (!ext4_has_metadata_csum(inode->i_sb))
365362
return;
366363

367364
t = get_dirent_tail(inode, dirent);
@@ -436,8 +433,7 @@ static int ext4_dx_csum_verify(struct inode *inode,
436433
struct dx_tail *t;
437434
int count_offset, limit, count;
438435

439-
if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
440-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
436+
if (!ext4_has_metadata_csum(inode->i_sb))
441437
return 1;
442438

443439
c = get_dx_countlimit(inode, dirent, &count_offset);
@@ -466,8 +462,7 @@ static void ext4_dx_csum_set(struct inode *inode, struct ext4_dir_entry *dirent)
466462
struct dx_tail *t;
467463
int count_offset, limit, count;
468464

469-
if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
470-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
465+
if (!ext4_has_metadata_csum(inode->i_sb))
471466
return;
472467

473468
c = get_dx_countlimit(inode, dirent, &count_offset);
@@ -555,8 +550,7 @@ static inline unsigned dx_root_limit(struct inode *dir, unsigned infosize)
555550
unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(1) -
556551
EXT4_DIR_REC_LEN(2) - infosize;
557552

558-
if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
559-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
553+
if (ext4_has_metadata_csum(dir->i_sb))
560554
entry_space -= sizeof(struct dx_tail);
561555
return entry_space / sizeof(struct dx_entry);
562556
}
@@ -565,8 +559,7 @@ static inline unsigned dx_node_limit(struct inode *dir)
565559
{
566560
unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0);
567561

568-
if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
569-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
562+
if (ext4_has_metadata_csum(dir->i_sb))
570563
entry_space -= sizeof(struct dx_tail);
571564
return entry_space / sizeof(struct dx_entry);
572565
}
@@ -1524,8 +1517,7 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
15241517
int csum_size = 0;
15251518
int err = 0, i;
15261519

1527-
if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
1528-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
1520+
if (ext4_has_metadata_csum(dir->i_sb))
15291521
csum_size = sizeof(struct ext4_dir_entry_tail);
15301522

15311523
bh2 = ext4_append(handle, dir, &newblock);
@@ -1691,8 +1683,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
16911683
int csum_size = 0;
16921684
int err;
16931685

1694-
if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
1695-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
1686+
if (ext4_has_metadata_csum(inode->i_sb))
16961687
csum_size = sizeof(struct ext4_dir_entry_tail);
16971688

16981689
if (!de) {
@@ -1759,8 +1750,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
17591750
struct fake_dirent *fde;
17601751
int csum_size = 0;
17611752

1762-
if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
1763-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
1753+
if (ext4_has_metadata_csum(inode->i_sb))
17641754
csum_size = sizeof(struct ext4_dir_entry_tail);
17651755

17661756
blocksize = dir->i_sb->s_blocksize;
@@ -1877,8 +1867,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
18771867
ext4_lblk_t block, blocks;
18781868
int csum_size = 0;
18791869

1880-
if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
1881-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
1870+
if (ext4_has_metadata_csum(inode->i_sb))
18821871
csum_size = sizeof(struct ext4_dir_entry_tail);
18831872

18841873
sb = dir->i_sb;
@@ -2142,8 +2131,7 @@ static int ext4_delete_entry(handle_t *handle,
21422131
return err;
21432132
}
21442133

2145-
if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
2146-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
2134+
if (ext4_has_metadata_csum(dir->i_sb))
21472135
csum_size = sizeof(struct ext4_dir_entry_tail);
21482136

21492137
BUFFER_TRACE(bh, "get_write_access");
@@ -2362,8 +2350,7 @@ static int ext4_init_new_dir(handle_t *handle, struct inode *dir,
23622350
int csum_size = 0;
23632351
int err;
23642352

2365-
if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
2366-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
2353+
if (ext4_has_metadata_csum(dir->i_sb))
23672354
csum_size = sizeof(struct ext4_dir_entry_tail);
23682355

23692356
if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {

fs/ext4/resize.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,8 +1210,7 @@ static int ext4_set_bitmap_checksums(struct super_block *sb,
12101210
{
12111211
struct buffer_head *bh;
12121212

1213-
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
1214-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
1213+
if (!ext4_has_metadata_csum(sb))
12151214
return 0;
12161215

12171216
bh = ext4_get_bitmap(sb, group_data->inode_bitmap);

fs/ext4/super.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,7 @@ static __le32 ext4_superblock_csum(struct super_block *sb,
140140
static int ext4_superblock_csum_verify(struct super_block *sb,
141141
struct ext4_super_block *es)
142142
{
143-
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
144-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
143+
if (!ext4_has_metadata_csum(sb))
145144
return 1;
146145

147146
return es->s_checksum == ext4_superblock_csum(sb, es);
@@ -151,8 +150,7 @@ void ext4_superblock_csum_set(struct super_block *sb)
151150
{
152151
struct ext4_super_block *es = EXT4_SB(sb)->s_es;
153152

154-
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
155-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
153+
if (!ext4_has_metadata_csum(sb))
156154
return;
157155

158156
es->s_checksum = ext4_superblock_csum(sb, es);
@@ -1989,8 +1987,7 @@ static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
19891987
__u16 crc = 0;
19901988
__le32 le_group = cpu_to_le32(block_group);
19911989

1992-
if ((sbi->s_es->s_feature_ro_compat &
1993-
cpu_to_le32(EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))) {
1990+
if (ext4_has_metadata_csum(sbi->s_sb)) {
19941991
/* Use new metadata_csum algorithm */
19951992
__le16 save_csum;
19961993
__u32 csum32;
@@ -3199,8 +3196,7 @@ static int set_journal_csum_feature_set(struct super_block *sb)
31993196
int compat, incompat;
32003197
struct ext4_sb_info *sbi = EXT4_SB(sb);
32013198

3202-
if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
3203-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
3199+
if (ext4_has_metadata_csum(sb)) {
32043200
/* journal checksum v3 */
32053201
compat = 0;
32063202
incompat = JBD2_FEATURE_INCOMPAT_CSUM_V3;
@@ -3508,8 +3504,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
35083504
}
35093505

35103506
/* Precompute checksum seed for all metadata */
3511-
if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
3512-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
3507+
if (ext4_has_metadata_csum(sb))
35133508
sbi->s_csum_seed = ext4_chksum(sbi, ~0, es->s_uuid,
35143509
sizeof(es->s_uuid));
35153510

fs/ext4/xattr.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,7 @@ static int ext4_xattr_block_csum_verify(struct inode *inode,
142142
sector_t block_nr,
143143
struct ext4_xattr_header *hdr)
144144
{
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) &&
147146
(hdr->h_checksum != ext4_xattr_block_csum(inode, block_nr, hdr)))
148147
return 0;
149148
return 1;
@@ -153,8 +152,7 @@ static void ext4_xattr_block_csum_set(struct inode *inode,
153152
sector_t block_nr,
154153
struct ext4_xattr_header *hdr)
155154
{
156-
if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
157-
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
155+
if (!ext4_has_metadata_csum(inode->i_sb))
158156
return;
159157

160158
hdr->h_checksum = ext4_xattr_block_csum(inode, block_nr, hdr);

0 commit comments

Comments
 (0)