提交 8b7f13a4 编写于 作者: Z Zhang Yi 提交者: Yang Yingliang

ext4: prevent partial update of the extent blocks

hulk inclusion
category: bugfix
bugzilla: 109205
CVE: NA
---------------------------

In the most error path of current extents updating operations are not
roll back partial updates properly when some bad things happens(.e.g in
ext4_ext_insert_extent()). So we may get an inconsistent extents tree
if journal has been aborted due to IO error, which may probability lead
to BUGON later when we accessing these extent entries in errors=continue
mode. This patch drop extent buffer's verify flag before updatng the
contents in ext4_ext_get_access(), and reset it after updating in
__ext4_ext_dirty(). After this patch we could force to check the extent
buffer if extents tree updating was break off, make sure the extents are
consistent.
Signed-off-by: NZhang Yi <yi.zhang@huawei.com>
Reviewed-by: NTheodore Ts'o <tytso@mit.edu>
Link: https://lore.kernel.org/r/20210908120850.4012324-4-yi.zhang@huawei.comSigned-off-by: NTheodore Ts'o <tytso@mit.edu>

conflict:
	fs/ext4/extents.c
Reviewed-by: NYang Erkun <yangerkun@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 28353d3b
...@@ -145,14 +145,24 @@ int ext4_datasem_ensure_credits(handle_t *handle, struct inode *inode, ...@@ -145,14 +145,24 @@ int ext4_datasem_ensure_credits(handle_t *handle, struct inode *inode,
static int ext4_ext_get_access(handle_t *handle, struct inode *inode, static int ext4_ext_get_access(handle_t *handle, struct inode *inode,
struct ext4_ext_path *path) struct ext4_ext_path *path)
{ {
int err = 0;
if (path->p_bh) { if (path->p_bh) {
/* path points to block */ /* path points to block */
BUFFER_TRACE(path->p_bh, "get_write_access"); BUFFER_TRACE(path->p_bh, "get_write_access");
return ext4_journal_get_write_access(handle, path->p_bh); err = ext4_journal_get_write_access(handle, path->p_bh);
/*
* The extent buffer's verified bit will be set again in
* __ext4_ext_dirty(). We could leave an inconsistent
* buffer if the extents updating procudure break off du
* to some error happens, force to check it again.
*/
if (!err)
clear_buffer_verified(path->p_bh);
} }
/* path points to leaf/index in inode body */ /* path points to leaf/index in inode body */
/* we use in-core data, no need to protect them */ /* we use in-core data, no need to protect them */
return 0; return err;
} }
/* /*
...@@ -172,6 +182,9 @@ int __ext4_ext_dirty(const char *where, unsigned int line, handle_t *handle, ...@@ -172,6 +182,9 @@ int __ext4_ext_dirty(const char *where, unsigned int line, handle_t *handle,
/* path points to block */ /* path points to block */
err = __ext4_handle_dirty_metadata(where, line, handle, err = __ext4_handle_dirty_metadata(where, line, handle,
inode, path->p_bh); inode, path->p_bh);
/* Extents updating done, re-set verified flag */
if (!err)
set_buffer_verified(path->p_bh);
} else { } else {
/* path points to leaf/index in inode body */ /* path points to leaf/index in inode body */
err = ext4_mark_inode_dirty(handle, inode); err = ext4_mark_inode_dirty(handle, inode);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册