summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Whitney <enwlinux@gmail.com>2020-04-30 20:53:20 +0200
committerTheodore Ts'o <tytso@mit.edu>2020-06-04 05:16:50 +0200
commitbe809e1274ebc043640eeeb287accb7b4a4bcbff (patch)
tree9eb081fdf095f7e043cd1941533ad2dc9410fea1
parentext4: clean up GET_BLOCKS_PRE_IO error handling (diff)
downloadlinux-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.c23
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;