diff options
author | Eric Whitney <enwlinux@gmail.com> | 2020-04-30 20:53:20 +0200 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2020-06-04 05:16:50 +0200 |
commit | be809e1274ebc043640eeeb287accb7b4a4bcbff (patch) | |
tree | 9eb081fdf095f7e043cd1941533ad2dc9410fea1 | |
parent | ext4: clean up GET_BLOCKS_PRE_IO error handling (diff) | |
download | linux-be809e1274ebc043640eeeb287accb7b4a4bcbff.tar.xz linux-be809e1274ebc043640eeeb287accb7b4a4bcbff.zip |
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>
-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; |