Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c9b63bd0 authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: avoid to use failed inode immediately



Before iput is called, the inode number used by a bad inode can be reassigned
to other new inode, resulting in any abnormal behaviors on the new inode.
This should not happen for the new inode.

Reviewed-by: default avatarChao Yu <chao2.yu@samsung.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent eca616f8
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -1343,6 +1343,7 @@ enum {
	FI_INC_LINK,		/* need to increment i_nlink */
	FI_INC_LINK,		/* need to increment i_nlink */
	FI_ACL_MODE,		/* indicate acl mode */
	FI_ACL_MODE,		/* indicate acl mode */
	FI_NO_ALLOC,		/* should not allocate any blocks */
	FI_NO_ALLOC,		/* should not allocate any blocks */
	FI_FREE_NID,		/* free allocated nide */
	FI_UPDATE_DIR,		/* should update inode block for consistency */
	FI_UPDATE_DIR,		/* should update inode block for consistency */
	FI_DELAY_IPUT,		/* used for the recovery */
	FI_DELAY_IPUT,		/* used for the recovery */
	FI_NO_EXTENT,		/* not to use the extent cache */
	FI_NO_EXTENT,		/* not to use the extent cache */
+12 −7
Original line number Original line Diff line number Diff line
@@ -314,7 +314,8 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
void f2fs_evict_inode(struct inode *inode)
void f2fs_evict_inode(struct inode *inode)
{
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	nid_t xnid = F2FS_I(inode)->i_xattr_nid;
	struct f2fs_inode_info *fi = F2FS_I(inode);
	nid_t xnid = fi->i_xattr_nid;


	/* some remained atomic pages should discarded */
	/* some remained atomic pages should discarded */
	if (f2fs_is_atomic_file(inode))
	if (f2fs_is_atomic_file(inode))
@@ -334,7 +335,7 @@ void f2fs_evict_inode(struct inode *inode)
		goto no_delete;
		goto no_delete;


	sb_start_intwrite(inode->i_sb);
	sb_start_intwrite(inode->i_sb);
	set_inode_flag(F2FS_I(inode), FI_NO_ALLOC);
	set_inode_flag(fi, FI_NO_ALLOC);
	i_size_write(inode, 0);
	i_size_write(inode, 0);


	if (F2FS_HAS_BLOCKS(inode))
	if (F2FS_HAS_BLOCKS(inode))
@@ -357,14 +358,18 @@ void f2fs_evict_inode(struct inode *inode)
	invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino);
	invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino);
	if (xnid)
	if (xnid)
		invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid);
		invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid);
	if (is_inode_flag_set(F2FS_I(inode), FI_APPEND_WRITE))
	if (is_inode_flag_set(fi, FI_APPEND_WRITE))
		add_dirty_inode(sbi, inode->i_ino, APPEND_INO);
		add_dirty_inode(sbi, inode->i_ino, APPEND_INO);
	if (is_inode_flag_set(F2FS_I(inode), FI_UPDATE_WRITE))
	if (is_inode_flag_set(fi, FI_UPDATE_WRITE))
		add_dirty_inode(sbi, inode->i_ino, UPDATE_INO);
		add_dirty_inode(sbi, inode->i_ino, UPDATE_INO);
	if (is_inode_flag_set(fi, FI_FREE_NID)) {
		alloc_nid_failed(sbi, inode->i_ino);
		clear_inode_flag(fi, FI_FREE_NID);
	}
out_clear:
out_clear:
#ifdef CONFIG_F2FS_FS_ENCRYPTION
#ifdef CONFIG_F2FS_FS_ENCRYPTION
	if (F2FS_I(inode)->i_crypt_info)
	if (fi->i_crypt_info)
		f2fs_free_encryption_info(inode, F2FS_I(inode)->i_crypt_info);
		f2fs_free_encryption_info(inode, fi->i_crypt_info);
#endif
#endif
	clear_inode(inode);
	clear_inode(inode);
}
}
@@ -384,9 +389,9 @@ void handle_failed_inode(struct inode *inode)


	remove_inode_page(inode);
	remove_inode_page(inode);


	set_inode_flag(F2FS_I(inode), FI_FREE_NID);
	clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
	clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
	clear_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY);
	clear_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY);
	alloc_nid_failed(sbi, inode->i_ino);
	f2fs_unlock_op(sbi);
	f2fs_unlock_op(sbi);


	/* iput will drop the inode object */
	/* iput will drop the inode object */
+2 −2
Original line number Original line Diff line number Diff line
@@ -78,9 +78,9 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
fail:
fail:
	trace_f2fs_new_inode(inode, err);
	trace_f2fs_new_inode(inode, err);
	make_bad_inode(inode);
	make_bad_inode(inode);
	iput(inode);
	if (nid_free)
	if (nid_free)
		alloc_nid_failed(sbi, ino);
		set_inode_flag(F2FS_I(inode), FI_FREE_NID);
	iput(inode);
	return ERR_PTR(err);
	return ERR_PTR(err);
}
}