Commit 24fb24b0 authored by Chao Yu's avatar Chao Yu Committed by Wen Zhiwei
Browse files

f2fs: fix to do sanity check on blocks for inline_data inode

stable inclusion
from stable-v6.6.50
commit 6290d3f5883d27d50b64c96a01f62e96d4181d14
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAYKL6

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=6290d3f5883d27d50b64c96a01f62e96d4181d14



--------------------------------

[ Upstream commit c240c87bcd44a1a2375fc8ef8c645d1f1fe76466 ]

inode can be fuzzed, so it can has F2FS_INLINE_DATA flag and valid
i_blocks/i_nid value, this patch supports to do extra sanity check
to detect such corrupted state.

Signed-off-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarWen Zhiwei <wenzhiwei@kylinos.cn>
parent c3409e2b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4149,7 +4149,7 @@ extern struct kmem_cache *f2fs_inode_entry_slab;
 * inline.c
 */
bool f2fs_may_inline_data(struct inode *inode);
bool f2fs_sanity_check_inline_data(struct inode *inode);
bool f2fs_sanity_check_inline_data(struct inode *inode, struct page *ipage);
bool f2fs_may_inline_dentry(struct inode *inode);
void f2fs_do_read_inline_data(struct page *page, struct page *ipage);
void f2fs_truncate_inline_inode(struct inode *inode,
+19 −1
Original line number Diff line number Diff line
@@ -33,11 +33,29 @@ bool f2fs_may_inline_data(struct inode *inode)
	return !f2fs_post_read_required(inode);
}

bool f2fs_sanity_check_inline_data(struct inode *inode)
static bool inode_has_blocks(struct inode *inode, struct page *ipage)
{
	struct f2fs_inode *ri = F2FS_INODE(ipage);
	int i;

	if (F2FS_HAS_BLOCKS(inode))
		return true;

	for (i = 0; i < DEF_NIDS_PER_INODE; i++) {
		if (ri->i_nid[i])
			return true;
	}
	return false;
}

bool f2fs_sanity_check_inline_data(struct inode *inode, struct page *ipage)
{
	if (!f2fs_has_inline_data(inode))
		return false;

	if (inode_has_blocks(inode, ipage))
		return false;

	if (!support_inline_data(inode))
		return true;

+1 −1
Original line number Diff line number Diff line
@@ -346,7 +346,7 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page)
		}
	}

	if (f2fs_sanity_check_inline_data(inode)) {
	if (f2fs_sanity_check_inline_data(inode, node_page)) {
		f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_data, run fsck to fix",
			  __func__, inode->i_ino, inode->i_mode);
		return false;