summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Meng <luomeng12@huawei.com>2020-10-20 09:36:31 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-11-05 11:07:04 +0100
commited153317028169264c7359d21c128ecf37e3d7d8 (patch)
tree3e892cbd47d659b6010f0a60a973244c17a47ecb
parentcc6ccd104140bbbf7f146c1bb337da1e2051790e (diff)
downloadlinux-ed153317028169264c7359d21c128ecf37e3d7d8.tar.gz
linux-ed153317028169264c7359d21c128ecf37e3d7d8.tar.bz2
linux-ed153317028169264c7359d21c128ecf37e3d7d8.zip
ext4: fix invalid inode checksum
commit 1322181170bb01bce3c228b82ae3d5c6b793164f upstream. During the stability test, there are some errors: ext4_lookup:1590: inode #6967: comm fsstress: iget: checksum invalid. If the inode->i_iblocks too big and doesn't set huge file flag, checksum will not be recalculated when update the inode information to it's buffer. If other inode marks the buffer dirty, then the inconsistent inode will be flushed to disk. Fix this problem by checking i_blocks in advance. Cc: stable@kernel.org Signed-off-by: Luo Meng <luomeng12@huawei.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Link: https://lore.kernel.org/r/20201020013631.3796673-1-luomeng12@huawei.com Signed-off-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/ext4/inode.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 34da8d341c0c..1d8638ee5442 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5135,6 +5135,12 @@ static int ext4_do_update_inode(handle_t *handle,
if (ext4_test_inode_state(inode, EXT4_STATE_NEW))
memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size);
+ err = ext4_inode_blocks_set(handle, raw_inode, ei);
+ if (err) {
+ spin_unlock(&ei->i_raw_lock);
+ goto out_brelse;
+ }
+
raw_inode->i_mode = cpu_to_le16(inode->i_mode);
i_uid = i_uid_read(inode);
i_gid = i_gid_read(inode);
@@ -5168,11 +5174,6 @@ static int ext4_do_update_inode(handle_t *handle,
EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode);
EXT4_EINODE_SET_XTIME(i_crtime, ei, raw_inode);
- err = ext4_inode_blocks_set(handle, raw_inode, ei);
- if (err) {
- spin_unlock(&ei->i_raw_lock);
- goto out_brelse;
- }
raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
raw_inode->i_flags = cpu_to_le32(ei->i_flags & 0xFFFFFFFF);
if (likely(!test_opt2(inode->i_sb, HURD_COMPAT)))