1 ext4: Replace open coded mdata csum feature to helper function
3 From: Dmitry Monakhov <dmonakhov@openvz.org>
5 Besides the fact that this replacement improves code readability
6 it also protects from errors caused direct EXT4_S(sb)->s_es manipulation
7 which may result attempt to use uninitialized csum machinery.
14 #Enable feature directly on disk, on mounted fs
15 tune2fs -O metadata_csum $IMG
16 # Provoke metadata update, likey result in OOPS
25 - EXT4_HAS_RO_COMPAT_FEATURE(E, EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)
26 + ext4_has_metadata_csum(E)
28 https://bugzilla.kernel.org/show_bug.cgi?id=82201
30 Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
31 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
32 Cc: stable@vger.kernel.org
34 fs/ext4/bitmap.c | 12 ++++--------
35 fs/ext4/ext4.h | 8 ++++++++
36 fs/ext4/extents.c | 6 ++----
37 fs/ext4/ialloc.c | 3 +--
38 fs/ext4/inline.c | 3 +--
39 fs/ext4/inode.c | 9 +++------
40 fs/ext4/ioctl.c | 3 +--
41 fs/ext4/mmp.c | 6 ++----
42 fs/ext4/namei.c | 39 +++++++++++++--------------------------
43 fs/ext4/resize.c | 3 +--
44 fs/ext4/super.c | 15 +++++----------
45 fs/ext4/xattr.c | 6 ++----
46 12 files changed, 43 insertions(+), 70 deletions(-)
48 diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c
49 index 3285aa5..b610779 100644
50 --- a/fs/ext4/bitmap.c
51 +++ b/fs/ext4/bitmap.c
52 @@ -24,8 +24,7 @@ int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
53 __u32 provided, calculated;
54 struct ext4_sb_info *sbi = EXT4_SB(sb);
56 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
57 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
58 + if (!ext4_has_metadata_csum(sb))
61 provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo);
62 @@ -46,8 +45,7 @@ void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
64 struct ext4_sb_info *sbi = EXT4_SB(sb);
66 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
67 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
68 + if (!ext4_has_metadata_csum(sb))
71 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
72 @@ -65,8 +63,7 @@ int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
73 struct ext4_sb_info *sbi = EXT4_SB(sb);
74 int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
76 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
77 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
78 + if (!ext4_has_metadata_csum(sb))
81 provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo);
82 @@ -91,8 +88,7 @@ void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
84 struct ext4_sb_info *sbi = EXT4_SB(sb);
86 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
87 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
88 + if (!ext4_has_metadata_csum(sb))
91 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
92 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
93 index 012e89b..1483d9c 100644
96 @@ -2337,6 +2337,14 @@ static inline int ext4_has_group_desc_csum(struct super_block *sb)
97 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM);
100 +static inline int ext4_has_metadata_csum(struct super_block *sb)
102 + WARN_ON_ONCE(EXT4_HAS_RO_COMPAT_FEATURE(sb,
103 + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
104 + !EXT4_SB(sb)->s_chksum_driver);
106 + return (EXT4_SB(sb)->s_chksum_driver != NULL);
108 static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
110 return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
111 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
112 index c3ed9af2..37043d0 100644
113 --- a/fs/ext4/extents.c
114 +++ b/fs/ext4/extents.c
115 @@ -73,8 +73,7 @@ static int ext4_extent_block_csum_verify(struct inode *inode,
117 struct ext4_extent_tail *et;
119 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
120 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
121 + if (!ext4_has_metadata_csum(inode->i_sb))
124 et = find_ext4_extent_tail(eh);
125 @@ -88,8 +87,7 @@ static void ext4_extent_block_csum_set(struct inode *inode,
127 struct ext4_extent_tail *et;
129 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
130 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
131 + if (!ext4_has_metadata_csum(inode->i_sb))
134 et = find_ext4_extent_tail(eh);
135 diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
136 index 5b87fc3..8012a5d 100644
137 --- a/fs/ext4/ialloc.c
138 +++ b/fs/ext4/ialloc.c
139 @@ -1011,8 +1011,7 @@ got:
140 spin_unlock(&sbi->s_next_gen_lock);
142 /* Precompute checksum seed for inode metadata */
143 - if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
144 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
145 + if (ext4_has_metadata_csum(sb)) {
147 __le32 inum = cpu_to_le32(inode->i_ino);
148 __le32 gen = cpu_to_le32(inode->i_generation);
149 diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
150 index 378aadf..3ea6269 100644
151 --- a/fs/ext4/inline.c
152 +++ b/fs/ext4/inline.c
153 @@ -1128,8 +1128,7 @@ static int ext4_finish_convert_inline_dir(handle_t *handle,
154 memcpy((void *)de, buf + EXT4_INLINE_DOTDOT_SIZE,
155 inline_size - EXT4_INLINE_DOTDOT_SIZE);
157 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
158 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
159 + if (ext4_has_metadata_csum(inode->i_sb))
160 csum_size = sizeof(struct ext4_dir_entry_tail);
162 inode->i_size = inode->i_sb->s_blocksize;
163 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
164 index 0dd9150..e9777f9 100644
165 --- a/fs/ext4/inode.c
166 +++ b/fs/ext4/inode.c
167 @@ -83,8 +83,7 @@ static int ext4_inode_csum_verify(struct inode *inode, struct ext4_inode *raw,
169 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
170 cpu_to_le32(EXT4_OS_LINUX) ||
171 - !EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
172 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
173 + !ext4_has_metadata_csum(inode->i_sb))
176 provided = le16_to_cpu(raw->i_checksum_lo);
177 @@ -105,8 +104,7 @@ static void ext4_inode_csum_set(struct inode *inode, struct ext4_inode *raw,
179 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
180 cpu_to_le32(EXT4_OS_LINUX) ||
181 - !EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
182 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
183 + !ext4_has_metadata_csum(inode->i_sb))
186 csum = ext4_inode_csum(inode, raw, ei);
187 @@ -3928,8 +3926,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
188 ei->i_extra_isize = 0;
190 /* Precompute checksum seed for inode metadata */
191 - if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
192 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
193 + if (ext4_has_metadata_csum(sb)) {
194 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
196 __le32 inum = cpu_to_le32(inode->i_ino);
197 diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
198 index 3d5de16..bfda18a 100644
199 --- a/fs/ext4/ioctl.c
200 +++ b/fs/ext4/ioctl.c
201 @@ -331,8 +331,7 @@ flags_out:
202 if (!inode_owner_or_capable(inode))
205 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
206 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
207 + if (ext4_has_metadata_csum(inode->i_sb)) {
208 ext4_warning(sb, "Setting inode version is not "
209 "supported with metadata_csum enabled.");
211 diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
212 index 32bce84..8313ca3 100644
215 @@ -20,8 +20,7 @@ static __le32 ext4_mmp_csum(struct super_block *sb, struct mmp_struct *mmp)
217 static int ext4_mmp_csum_verify(struct super_block *sb, struct mmp_struct *mmp)
219 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
220 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
221 + if (!ext4_has_metadata_csum(sb))
224 return mmp->mmp_checksum == ext4_mmp_csum(sb, mmp);
225 @@ -29,8 +28,7 @@ static int ext4_mmp_csum_verify(struct super_block *sb, struct mmp_struct *mmp)
227 static void ext4_mmp_csum_set(struct super_block *sb, struct mmp_struct *mmp)
229 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
230 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
231 + if (!ext4_has_metadata_csum(sb))
234 mmp->mmp_checksum = ext4_mmp_csum(sb, mmp);
235 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
236 index 7037ecf..61756f9 100644
237 --- a/fs/ext4/namei.c
238 +++ b/fs/ext4/namei.c
239 @@ -124,8 +124,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
240 "directory leaf block found instead of index block");
241 return ERR_PTR(-EIO);
243 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
244 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) ||
245 + if (!ext4_has_metadata_csum(inode->i_sb) ||
249 @@ -338,8 +337,7 @@ int ext4_dirent_csum_verify(struct inode *inode, struct ext4_dir_entry *dirent)
251 struct ext4_dir_entry_tail *t;
253 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
254 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
255 + if (!ext4_has_metadata_csum(inode->i_sb))
258 t = get_dirent_tail(inode, dirent);
259 @@ -360,8 +358,7 @@ static void ext4_dirent_csum_set(struct inode *inode,
261 struct ext4_dir_entry_tail *t;
263 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
264 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
265 + if (!ext4_has_metadata_csum(inode->i_sb))
268 t = get_dirent_tail(inode, dirent);
269 @@ -436,8 +433,7 @@ static int ext4_dx_csum_verify(struct inode *inode,
271 int count_offset, limit, count;
273 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
274 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
275 + if (!ext4_has_metadata_csum(inode->i_sb))
278 c = get_dx_countlimit(inode, dirent, &count_offset);
279 @@ -466,8 +462,7 @@ static void ext4_dx_csum_set(struct inode *inode, struct ext4_dir_entry *dirent)
281 int count_offset, limit, count;
283 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
284 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
285 + if (!ext4_has_metadata_csum(inode->i_sb))
288 c = get_dx_countlimit(inode, dirent, &count_offset);
289 @@ -555,8 +550,7 @@ static inline unsigned dx_root_limit(struct inode *dir, unsigned infosize)
290 unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(1) -
291 EXT4_DIR_REC_LEN(2) - infosize;
293 - if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
294 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
295 + if (ext4_has_metadata_csum(dir->i_sb))
296 entry_space -= sizeof(struct dx_tail);
297 return entry_space / sizeof(struct dx_entry);
299 @@ -565,8 +559,7 @@ static inline unsigned dx_node_limit(struct inode *dir)
301 unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0);
303 - if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
304 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
305 + if (ext4_has_metadata_csum(dir->i_sb))
306 entry_space -= sizeof(struct dx_tail);
307 return entry_space / sizeof(struct dx_entry);
309 @@ -1524,8 +1517,7 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
313 - if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
314 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
315 + if (ext4_has_metadata_csum(dir->i_sb))
316 csum_size = sizeof(struct ext4_dir_entry_tail);
318 bh2 = ext4_append(handle, dir, &newblock);
319 @@ -1691,8 +1683,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
323 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
324 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
325 + if (ext4_has_metadata_csum(inode->i_sb))
326 csum_size = sizeof(struct ext4_dir_entry_tail);
329 @@ -1759,8 +1750,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
330 struct fake_dirent *fde;
333 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
334 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
335 + if (ext4_has_metadata_csum(inode->i_sb))
336 csum_size = sizeof(struct ext4_dir_entry_tail);
338 blocksize = dir->i_sb->s_blocksize;
339 @@ -1877,8 +1867,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
340 ext4_lblk_t block, blocks;
343 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
344 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
345 + if (ext4_has_metadata_csum(inode->i_sb))
346 csum_size = sizeof(struct ext4_dir_entry_tail);
349 @@ -2142,8 +2131,7 @@ static int ext4_delete_entry(handle_t *handle,
353 - if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
354 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
355 + if (ext4_has_metadata_csum(dir->i_sb))
356 csum_size = sizeof(struct ext4_dir_entry_tail);
358 BUFFER_TRACE(bh, "get_write_access");
359 @@ -2362,8 +2350,7 @@ static int ext4_init_new_dir(handle_t *handle, struct inode *dir,
363 - if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
364 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
365 + if (ext4_has_metadata_csum(dir->i_sb))
366 csum_size = sizeof(struct ext4_dir_entry_tail);
368 if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
369 diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
370 index bb0e80f..d5afb0a 100644
371 --- a/fs/ext4/resize.c
372 +++ b/fs/ext4/resize.c
373 @@ -1210,8 +1210,7 @@ static int ext4_set_bitmap_checksums(struct super_block *sb,
375 struct buffer_head *bh;
377 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
378 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
379 + if (!ext4_has_metadata_csum(sb))
382 bh = ext4_get_bitmap(sb, group_data->inode_bitmap);
383 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
384 index a0811cc..5afe42d 100644
385 --- a/fs/ext4/super.c
386 +++ b/fs/ext4/super.c
387 @@ -140,8 +140,7 @@ static __le32 ext4_superblock_csum(struct super_block *sb,
388 static int ext4_superblock_csum_verify(struct super_block *sb,
389 struct ext4_super_block *es)
391 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
392 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
393 + if (!ext4_has_metadata_csum(sb))
396 return es->s_checksum == ext4_superblock_csum(sb, es);
397 @@ -151,8 +150,7 @@ void ext4_superblock_csum_set(struct super_block *sb)
399 struct ext4_super_block *es = EXT4_SB(sb)->s_es;
401 - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
402 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
403 + if (!ext4_has_metadata_csum(sb))
406 es->s_checksum = ext4_superblock_csum(sb, es);
407 @@ -1989,8 +1987,7 @@ static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
409 __le32 le_group = cpu_to_le32(block_group);
411 - if ((sbi->s_es->s_feature_ro_compat &
412 - cpu_to_le32(EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))) {
413 + if (ext4_has_metadata_csum(sbi->s_sb)) {
414 /* Use new metadata_csum algorithm */
417 @@ -3199,8 +3196,7 @@ static int set_journal_csum_feature_set(struct super_block *sb)
418 int compat, incompat;
419 struct ext4_sb_info *sbi = EXT4_SB(sb);
421 - if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
422 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
423 + if (ext4_has_metadata_csum(sb)) {
424 /* journal checksum v3 */
426 incompat = JBD2_FEATURE_INCOMPAT_CSUM_V3;
427 @@ -3508,8 +3504,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
430 /* Precompute checksum seed for all metadata */
431 - if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
432 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
433 + if (ext4_has_metadata_csum(sb))
434 sbi->s_csum_seed = ext4_chksum(sbi, ~0, es->s_uuid,
437 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
438 index 42823ab..1e09fc7 100644
439 --- a/fs/ext4/xattr.c
440 +++ b/fs/ext4/xattr.c
441 @@ -142,8 +142,7 @@ static int ext4_xattr_block_csum_verify(struct inode *inode,
443 struct ext4_xattr_header *hdr)
445 - if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
446 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
447 + if (ext4_has_metadata_csum(inode->i_sb) &&
448 (hdr->h_checksum != ext4_xattr_block_csum(inode, block_nr, hdr)))
451 @@ -153,8 +152,7 @@ static void ext4_xattr_block_csum_set(struct inode *inode,
453 struct ext4_xattr_header *hdr)
455 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
456 - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
457 + if (!ext4_has_metadata_csum(inode->i_sb))
460 hdr->h_checksum = ext4_xattr_block_csum(inode, block_nr, hdr);