ext4: handle ext4_mark_inode_dirty errors

ext4_mark_inode_dirty() can fail for real reasons. Ignoring its return
value may lead ext4 to ignore real failures that would result in
corruption / crashes. Harden ext4_mark_inode_dirty error paths to fail
as soon as possible and return errors to the caller whenever
appropriate.

One of the possible scnearios when this bug could affected is that
while creating a new inode, its directory entry gets added
successfully but while writing the inode itself mark_inode_dirty
returns error which is ignored. This would result in inconsistency
that the directory entry points to a non-existent inode.

Ran gce-xfstests smoke tests and verified that there were no
regressions.

Signed-off-by: Harshad Shirwadkar <harshadshirwadkar@gmail.com>
Link: https://lore.kernel.org/r/20200427013438.219117-1-harshadshirwadkar@gmail.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
Harshad Shirwadkar
2020-04-26 18:34:37 -07:00
committed by Theodore Ts'o
父節點 8418897f1b
當前提交 4209ae12b1
共有 12 個文件被更改,包括 139 次插入73 次删除

查看文件

@@ -1327,7 +1327,7 @@ static int ext4_xattr_inode_write(handle_t *handle, struct inode *ea_inode,
int blocksize = ea_inode->i_sb->s_blocksize;
int max_blocks = (bufsize + blocksize - 1) >> ea_inode->i_blkbits;
int csize, wsize = 0;
int ret = 0;
int ret = 0, ret2 = 0;
int retries = 0;
retry:
@@ -1385,7 +1385,9 @@ retry:
ext4_update_i_disksize(ea_inode, wsize);
inode_unlock(ea_inode);
ext4_mark_inode_dirty(handle, ea_inode);
ret2 = ext4_mark_inode_dirty(handle, ea_inode);
if (unlikely(ret2 && !ret))
ret = ret2;
out:
brelse(bh);