diff options
author | Zhang Yi <yi.zhang@huawei.com> | 2021-07-16 14:20:22 +0200 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2021-09-05 05:38:18 +0200 |
commit | 55ce2f649b9e88111270333a8127e23f4f8f42d7 (patch) | |
tree | 33af2ceb5eb9b03f539c11d3828930b479ef6e35 /fs/ext4/inline.c | |
parent | ext4: check and update i_disksize properly (diff) | |
download | linux-55ce2f649b9e88111270333a8127e23f4f8f42d7.tar.xz linux-55ce2f649b9e88111270333a8127e23f4f8f42d7.zip |
ext4: correct the error path of ext4_write_inline_data_end()
Current error path of ext4_write_inline_data_end() is not correct.
Firstly, it should pass out the error value if ext4_get_inode_loc()
return fail, or else it could trigger infinite loop if we inject error
here. And then it's better to add inode to orphan list if it return fail
in ext4_journal_stop(), otherwise we could not restore inline xattr
entry after power failure. Finally, we need to reset the 'ret' value if
ext4_write_inline_data_end() return success in ext4_write_end() and
ext4_journalled_write_end(), otherwise we could not get the error return
value of ext4_journal_stop().
Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Link: https://lore.kernel.org/r/20210716122024.1105856-3-yi.zhang@huawei.com
Diffstat (limited to 'fs/ext4/inline.c')
-rw-r--r-- | fs/ext4/inline.c | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 70cb64db33f7..28b666f25ac2 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -733,25 +733,20 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len, void *kaddr; struct ext4_iloc iloc; - if (unlikely(copied < len)) { - if (!PageUptodate(page)) { - copied = 0; - goto out; - } - } + if (unlikely(copied < len) && !PageUptodate(page)) + return 0; ret = ext4_get_inode_loc(inode, &iloc); if (ret) { ext4_std_error(inode->i_sb, ret); - copied = 0; - goto out; + return ret; } ext4_write_lock_xattr(inode, &no_expand); BUG_ON(!ext4_has_inline_data(inode)); kaddr = kmap_atomic(page); - ext4_write_inline_data(inode, &iloc, kaddr, pos, len); + ext4_write_inline_data(inode, &iloc, kaddr, pos, copied); kunmap_atomic(kaddr); SetPageUptodate(page); /* clear page dirty so that writepages wouldn't work for us. */ @@ -760,7 +755,7 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len, ext4_write_unlock_xattr(inode, &no_expand); brelse(iloc.bh); mark_inode_dirty(inode); -out: + return copied; } |