Skip to content

Commit

Permalink
ext4: Replace open coded mdata csum feature to helper function
Browse files Browse the repository at this point in the history
commit 9aa5d32 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Dmitry Monakhov authored and gregkh committed Nov 14, 2014
1 parent a1d6b55 commit 2b3b37b
Show file tree
Hide file tree
Showing 12 changed files with 43 additions and 70 deletions.
12 changes: 4 additions & 8 deletions fs/ext4/bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
__u32 provided, calculated;
struct ext4_sb_info *sbi = EXT4_SB(sb);

if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(sb))
return 1;

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

if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(sb))
return;

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

if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(sb))
return 1;

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

if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(sb))
return;

csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
Expand Down
8 changes: 8 additions & 0 deletions fs/ext4/ext4.h
Original file line number Diff line number Diff line change
Expand Up @@ -2337,6 +2337,14 @@ static inline int ext4_has_group_desc_csum(struct super_block *sb)
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM);
}

static inline int ext4_has_metadata_csum(struct super_block *sb)
{
WARN_ON_ONCE(EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
!EXT4_SB(sb)->s_chksum_driver);

return (EXT4_SB(sb)->s_chksum_driver != NULL);
}
static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
{
return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
Expand Down
6 changes: 2 additions & 4 deletions fs/ext4/extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ static int ext4_extent_block_csum_verify(struct inode *inode,
{
struct ext4_extent_tail *et;

if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(inode->i_sb))
return 1;

et = find_ext4_extent_tail(eh);
Expand All @@ -88,8 +87,7 @@ static void ext4_extent_block_csum_set(struct inode *inode,
{
struct ext4_extent_tail *et;

if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(inode->i_sb))
return;

et = find_ext4_extent_tail(eh);
Expand Down
3 changes: 1 addition & 2 deletions fs/ext4/ialloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1011,8 +1011,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
spin_unlock(&sbi->s_next_gen_lock);

/* Precompute checksum seed for inode metadata */
if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
if (ext4_has_metadata_csum(sb)) {
__u32 csum;
__le32 inum = cpu_to_le32(inode->i_ino);
__le32 gen = cpu_to_le32(inode->i_generation);
Expand Down
3 changes: 1 addition & 2 deletions fs/ext4/inline.c
Original file line number Diff line number Diff line change
Expand Up @@ -1126,8 +1126,7 @@ static int ext4_finish_convert_inline_dir(handle_t *handle,
memcpy((void *)de, buf + EXT4_INLINE_DOTDOT_SIZE,
inline_size - EXT4_INLINE_DOTDOT_SIZE);

if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (ext4_has_metadata_csum(inode->i_sb))
csum_size = sizeof(struct ext4_dir_entry_tail);

inode->i_size = inode->i_sb->s_blocksize;
Expand Down
9 changes: 3 additions & 6 deletions fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ static int ext4_inode_csum_verify(struct inode *inode, struct ext4_inode *raw,

if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
cpu_to_le32(EXT4_OS_LINUX) ||
!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
!ext4_has_metadata_csum(inode->i_sb))
return 1;

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

if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
cpu_to_le32(EXT4_OS_LINUX) ||
!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
!ext4_has_metadata_csum(inode->i_sb))
return;

csum = ext4_inode_csum(inode, raw, ei);
Expand Down Expand Up @@ -3950,8 +3948,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
ei->i_extra_isize = 0;

/* Precompute checksum seed for inode metadata */
if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
if (ext4_has_metadata_csum(sb)) {
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
__u32 csum;
__le32 inum = cpu_to_le32(inode->i_ino);
Expand Down
3 changes: 1 addition & 2 deletions fs/ext4/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
if (!inode_owner_or_capable(inode))
return -EPERM;

if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
if (ext4_has_metadata_csum(inode->i_sb)) {
ext4_warning(sb, "Setting inode version is not "
"supported with metadata_csum enabled.");
return -ENOTTY;
Expand Down
6 changes: 2 additions & 4 deletions fs/ext4/mmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,15 @@ static __le32 ext4_mmp_csum(struct super_block *sb, struct mmp_struct *mmp)

static int ext4_mmp_csum_verify(struct super_block *sb, struct mmp_struct *mmp)
{
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(sb))
return 1;

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

static void ext4_mmp_csum_set(struct super_block *sb, struct mmp_struct *mmp)
{
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(sb))
return;

mmp->mmp_checksum = ext4_mmp_csum(sb, mmp);
Expand Down
39 changes: 13 additions & 26 deletions fs/ext4/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
"directory leaf block found instead of index block");
return ERR_PTR(-EIO);
}
if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) ||
if (!ext4_has_metadata_csum(inode->i_sb) ||
buffer_verified(bh))
return bh;

Expand Down Expand Up @@ -340,8 +339,7 @@ int ext4_dirent_csum_verify(struct inode *inode, struct ext4_dir_entry *dirent)
{
struct ext4_dir_entry_tail *t;

if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(inode->i_sb))
return 1;

t = get_dirent_tail(inode, dirent);
Expand All @@ -362,8 +360,7 @@ static void ext4_dirent_csum_set(struct inode *inode,
{
struct ext4_dir_entry_tail *t;

if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(inode->i_sb))
return;

t = get_dirent_tail(inode, dirent);
Expand Down Expand Up @@ -438,8 +435,7 @@ static int ext4_dx_csum_verify(struct inode *inode,
struct dx_tail *t;
int count_offset, limit, count;

if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(inode->i_sb))
return 1;

c = get_dx_countlimit(inode, dirent, &count_offset);
Expand Down Expand Up @@ -468,8 +464,7 @@ static void ext4_dx_csum_set(struct inode *inode, struct ext4_dir_entry *dirent)
struct dx_tail *t;
int count_offset, limit, count;

if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(inode->i_sb))
return;

c = get_dx_countlimit(inode, dirent, &count_offset);
Expand Down Expand Up @@ -557,8 +552,7 @@ static inline unsigned dx_root_limit(struct inode *dir, unsigned infosize)
unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(1) -
EXT4_DIR_REC_LEN(2) - infosize;

if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (ext4_has_metadata_csum(dir->i_sb))
entry_space -= sizeof(struct dx_tail);
return entry_space / sizeof(struct dx_entry);
}
Expand All @@ -567,8 +561,7 @@ static inline unsigned dx_node_limit(struct inode *dir)
{
unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0);

if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (ext4_has_metadata_csum(dir->i_sb))
entry_space -= sizeof(struct dx_tail);
return entry_space / sizeof(struct dx_entry);
}
Expand Down Expand Up @@ -1548,8 +1541,7 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
int csum_size = 0;
int err = 0, i;

if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (ext4_has_metadata_csum(dir->i_sb))
csum_size = sizeof(struct ext4_dir_entry_tail);

bh2 = ext4_append(handle, dir, &newblock);
Expand Down Expand Up @@ -1718,8 +1710,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
int csum_size = 0;
int err;

if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (ext4_has_metadata_csum(inode->i_sb))
csum_size = sizeof(struct ext4_dir_entry_tail);

if (!de) {
Expand Down Expand Up @@ -1786,8 +1777,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
struct fake_dirent *fde;
int csum_size = 0;

if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (ext4_has_metadata_csum(inode->i_sb))
csum_size = sizeof(struct ext4_dir_entry_tail);

blocksize = dir->i_sb->s_blocksize;
Expand Down Expand Up @@ -1904,8 +1894,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
ext4_lblk_t block, blocks;
int csum_size = 0;

if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (ext4_has_metadata_csum(inode->i_sb))
csum_size = sizeof(struct ext4_dir_entry_tail);

sb = dir->i_sb;
Expand Down Expand Up @@ -2167,8 +2156,7 @@ static int ext4_delete_entry(handle_t *handle,
return err;
}

if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (ext4_has_metadata_csum(dir->i_sb))
csum_size = sizeof(struct ext4_dir_entry_tail);

BUFFER_TRACE(bh, "get_write_access");
Expand Down Expand Up @@ -2387,8 +2375,7 @@ static int ext4_init_new_dir(handle_t *handle, struct inode *dir,
int csum_size = 0;
int err;

if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (ext4_has_metadata_csum(dir->i_sb))
csum_size = sizeof(struct ext4_dir_entry_tail);

if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
Expand Down
3 changes: 1 addition & 2 deletions fs/ext4/resize.c
Original file line number Diff line number Diff line change
Expand Up @@ -1212,8 +1212,7 @@ static int ext4_set_bitmap_checksums(struct super_block *sb,
{
struct buffer_head *bh;

if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(sb))
return 0;

bh = ext4_get_bitmap(sb, group_data->inode_bitmap);
Expand Down
15 changes: 5 additions & 10 deletions fs/ext4/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,7 @@ static __le32 ext4_superblock_csum(struct super_block *sb,
static int ext4_superblock_csum_verify(struct super_block *sb,
struct ext4_super_block *es)
{
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(sb))
return 1;

return es->s_checksum == ext4_superblock_csum(sb, es);
Expand All @@ -152,8 +151,7 @@ void ext4_superblock_csum_set(struct super_block *sb)
{
struct ext4_super_block *es = EXT4_SB(sb)->s_es;

if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(sb))
return;

es->s_checksum = ext4_superblock_csum(sb, es);
Expand Down Expand Up @@ -2009,8 +2007,7 @@ static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
__u16 crc = 0;
__le32 le_group = cpu_to_le32(block_group);

if ((sbi->s_es->s_feature_ro_compat &
cpu_to_le32(EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))) {
if (ext4_has_metadata_csum(sbi->s_sb)) {
/* Use new metadata_csum algorithm */
__le16 save_csum;
__u32 csum32;
Expand Down Expand Up @@ -3172,8 +3169,7 @@ static int set_journal_csum_feature_set(struct super_block *sb)
int compat, incompat;
struct ext4_sb_info *sbi = EXT4_SB(sb);

if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
if (ext4_has_metadata_csum(sb)) {
/* journal checksum v3 */
compat = 0;
incompat = JBD2_FEATURE_INCOMPAT_CSUM_V3;
Expand Down Expand Up @@ -3480,8 +3476,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
}

/* Precompute checksum seed for all metadata */
if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (ext4_has_metadata_csum(sb))
sbi->s_csum_seed = ext4_chksum(sbi, ~0, es->s_uuid,
sizeof(es->s_uuid));

Expand Down
6 changes: 2 additions & 4 deletions fs/ext4/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,7 @@ static int ext4_xattr_block_csum_verify(struct inode *inode,
sector_t block_nr,
struct ext4_xattr_header *hdr)
{
if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
if (ext4_has_metadata_csum(inode->i_sb) &&
(hdr->h_checksum != ext4_xattr_block_csum(inode, block_nr, hdr)))
return 0;
return 1;
Expand All @@ -153,8 +152,7 @@ static void ext4_xattr_block_csum_set(struct inode *inode,
sector_t block_nr,
struct ext4_xattr_header *hdr)
{
if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
if (!ext4_has_metadata_csum(inode->i_sb))
return;

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

0 comments on commit 2b3b37b

Please sign in to comment.