diff options
author | Eric Whitney <enwlinux@gmail.com> | 2020-04-30 14:53:20 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2020-06-03 23:16:50 -0400 |
commit | be809e1274ebc043640eeeb287accb7b4a4bcbff (patch) | |
tree | 9eb081fdf095f7e043cd1941533ad2dc9410fea1 /fs/ext4 | |
parent | 779e26517b3600830fe58933d5f97627711c9435 (diff) |
ext4: clean up ext4_ext_convert_to_initialized() error handling
If ext4_ext_convert_to_initialized() fails when called within
ext4_ext_handle_unwritten_extents(), immediately error out through the
exit point at function end. Fix the error handling in the event
ext4_ext_convert_to_initialized() returns 0, which it shouldn't do when
converting an existing extent. The current code returns the passed in
value of allocated (which is likely non-zero) while failing to set
m_flags, m_pblk, and m_len.
Signed-off-by: Eric Whitney <enwlinux@gmail.com>
Link: https://lore.kernel.org/r/20200430185320.23001-5-enwlinux@gmail.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/extents.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index c63bc13f9a72..03b94c6e90cc 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3872,15 +3872,28 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode, goto out1; } - /* buffered write, writepage time, convert*/ + /* + * Default case when (flags & EXT4_GET_BLOCKS_CREATE) == 1. + * For buffered writes, at writepage time, etc. Convert a + * discovered unwritten extent to written. + */ ret = ext4_ext_convert_to_initialized(handle, inode, map, ppath, flags); - if (ret >= 0) - ext4_update_inode_fsync_trans(handle, inode, 1); - - if (ret <= 0) { + if (ret < 0) { err = ret; goto out2; } + ext4_update_inode_fsync_trans(handle, inode, 1); + /* + * shouldn't get a 0 return when converting an unwritten extent + * unless m_len is 0 (bug) or extent has been corrupted + */ + if (unlikely(ret == 0)) { + EXT4_ERROR_INODE(inode, "unexpected ret == 0, m_len = %u", + map->m_len); + err = -EFSCORRUPTED; + goto out2; + } + out: allocated = ret; map->m_flags |= EXT4_MAP_NEW; |