xref: /openbmc/linux/fs/f2fs/inode.c (revision 278002edb19bce2c628fafb0af936e77000f3a5b)
17c1a000dSChao Yu // SPDX-License-Identifier: GPL-2.0
20a8165d7SJaegeuk Kim /*
319f99ceeSJaegeuk Kim  * fs/f2fs/inode.c
419f99ceeSJaegeuk Kim  *
519f99ceeSJaegeuk Kim  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
619f99ceeSJaegeuk Kim  *             http://www.samsung.com/
719f99ceeSJaegeuk Kim  */
819f99ceeSJaegeuk Kim #include <linux/fs.h>
919f99ceeSJaegeuk Kim #include <linux/f2fs_fs.h>
1019f99ceeSJaegeuk Kim #include <linux/buffer_head.h>
1119f99ceeSJaegeuk Kim #include <linux/writeback.h>
124034247aSNeilBrown #include <linux/sched/mm.h>
13698a5c8cSYangtao Li #include <linux/lz4.h>
14698a5c8cSYangtao Li #include <linux/zstd.h>
1519f99ceeSJaegeuk Kim 
1619f99ceeSJaegeuk Kim #include "f2fs.h"
1719f99ceeSJaegeuk Kim #include "node.h"
180eb0adadSChao Yu #include "segment.h"
19dd6c89b5SChao Yu #include "xattr.h"
2019f99ceeSJaegeuk Kim 
21a2a4a7e4SNamjae Jeon #include <trace/events/f2fs.h>
22a2a4a7e4SNamjae Jeon 
236ce19affSChao Yu #ifdef CONFIG_F2FS_FS_COMPRESSION
246ce19affSChao Yu extern const struct address_space_operations f2fs_compress_aops;
256ce19affSChao Yu #endif
266ce19affSChao Yu 
f2fs_mark_inode_dirty_sync(struct inode * inode,bool sync)277c45729aSJaegeuk Kim void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync)
28b56ab837SJaegeuk Kim {
299ac1e2d8SDaeho Jeong 	if (is_inode_flag_set(inode, FI_NEW_INODE))
309ac1e2d8SDaeho Jeong 		return;
319ac1e2d8SDaeho Jeong 
32e62ff092SChao Yu 	if (f2fs_readonly(F2FS_I_SB(inode)->sb))
33e62ff092SChao Yu 		return;
34e62ff092SChao Yu 
357c45729aSJaegeuk Kim 	if (f2fs_inode_dirtied(inode, sync))
36b56ab837SJaegeuk Kim 		return;
377c45729aSJaegeuk Kim 
38364afd8aSDaeho Jeong 	if (f2fs_is_atomic_file(inode)) {
39364afd8aSDaeho Jeong 		set_inode_flag(inode, FI_ATOMIC_DIRTIED);
40364afd8aSDaeho Jeong 		return;
41364afd8aSDaeho Jeong 	}
42364afd8aSDaeho Jeong 
43b56ab837SJaegeuk Kim 	mark_inode_dirty_sync(inode);
44b56ab837SJaegeuk Kim }
45b56ab837SJaegeuk Kim 
f2fs_set_inode_flags(struct inode * inode)4619f99ceeSJaegeuk Kim void f2fs_set_inode_flags(struct inode *inode)
4719f99ceeSJaegeuk Kim {
4819f99ceeSJaegeuk Kim 	unsigned int flags = F2FS_I(inode)->i_flags;
498abfb36aSZhang Zhen 	unsigned int new_fl = 0;
5019f99ceeSJaegeuk Kim 
5159c84408SChao Yu 	if (flags & F2FS_SYNC_FL)
528abfb36aSZhang Zhen 		new_fl |= S_SYNC;
5359c84408SChao Yu 	if (flags & F2FS_APPEND_FL)
548abfb36aSZhang Zhen 		new_fl |= S_APPEND;
5559c84408SChao Yu 	if (flags & F2FS_IMMUTABLE_FL)
568abfb36aSZhang Zhen 		new_fl |= S_IMMUTABLE;
5759c84408SChao Yu 	if (flags & F2FS_NOATIME_FL)
588abfb36aSZhang Zhen 		new_fl |= S_NOATIME;
5959c84408SChao Yu 	if (flags & F2FS_DIRSYNC_FL)
608abfb36aSZhang Zhen 		new_fl |= S_DIRSYNC;
6162230e0dSChandan Rajendra 	if (file_is_encrypt(inode))
622ee6a576SEric Biggers 		new_fl |= S_ENCRYPTED;
6395ae251fSEric Biggers 	if (file_is_verity(inode))
6495ae251fSEric Biggers 		new_fl |= S_VERITY;
652c2eb7a3SDaniel Rosenberg 	if (flags & F2FS_CASEFOLD_FL)
662c2eb7a3SDaniel Rosenberg 		new_fl |= S_CASEFOLD;
676a678857SZhang Zhen 	inode_set_flags(inode, new_fl,
682ee6a576SEric Biggers 			S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|
69fbc246a1SLinus Torvalds 			S_ENCRYPTED|S_VERITY|S_CASEFOLD);
7019f99ceeSJaegeuk Kim }
7119f99ceeSJaegeuk Kim 
__get_inode_rdev(struct inode * inode,struct page * node_page)72dcd6b38bSChao Yu static void __get_inode_rdev(struct inode *inode, struct page *node_page)
733d1e3807SJaegeuk Kim {
74dcd6b38bSChao Yu 	__le32 *addr = get_dnode_addr(inode, node_page);
757a2af766SChao Yu 
763d1e3807SJaegeuk Kim 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
773d1e3807SJaegeuk Kim 			S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
78dcd6b38bSChao Yu 		if (addr[0])
79dcd6b38bSChao Yu 			inode->i_rdev = old_decode_dev(le32_to_cpu(addr[0]));
803d1e3807SJaegeuk Kim 		else
81dcd6b38bSChao Yu 			inode->i_rdev = new_decode_dev(le32_to_cpu(addr[1]));
823d1e3807SJaegeuk Kim 	}
833d1e3807SJaegeuk Kim }
843d1e3807SJaegeuk Kim 
__set_inode_rdev(struct inode * inode,struct page * node_page)85dcd6b38bSChao Yu static void __set_inode_rdev(struct inode *inode, struct page *node_page)
863d1e3807SJaegeuk Kim {
87dcd6b38bSChao Yu 	__le32 *addr = get_dnode_addr(inode, node_page);
887a2af766SChao Yu 
893d1e3807SJaegeuk Kim 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
903d1e3807SJaegeuk Kim 		if (old_valid_dev(inode->i_rdev)) {
91dcd6b38bSChao Yu 			addr[0] = cpu_to_le32(old_encode_dev(inode->i_rdev));
92dcd6b38bSChao Yu 			addr[1] = 0;
933d1e3807SJaegeuk Kim 		} else {
94dcd6b38bSChao Yu 			addr[0] = 0;
95dcd6b38bSChao Yu 			addr[1] = cpu_to_le32(new_encode_dev(inode->i_rdev));
96dcd6b38bSChao Yu 			addr[2] = 0;
973d1e3807SJaegeuk Kim 		}
983d1e3807SJaegeuk Kim 	}
993d1e3807SJaegeuk Kim }
1003d1e3807SJaegeuk Kim 
__recover_inline_status(struct inode * inode,struct page * ipage)1019e5ba77fSChao Yu static void __recover_inline_status(struct inode *inode, struct page *ipage)
102b3d208f9SJaegeuk Kim {
103f2470371SChao Yu 	void *inline_data = inline_data_addr(inode, ipage);
1049e5ba77fSChao Yu 	__le32 *start = inline_data;
105f2470371SChao Yu 	__le32 *end = start + MAX_INLINE_DATA(inode) / sizeof(__le32);
106b3d208f9SJaegeuk Kim 
1079e5ba77fSChao Yu 	while (start < end) {
1089e5ba77fSChao Yu 		if (*start++) {
109bae0ee7aSChao Yu 			f2fs_wait_on_page_writeback(ipage, NODE, true, true);
110b3d208f9SJaegeuk Kim 
11191942321SJaegeuk Kim 			set_inode_flag(inode, FI_DATA_EXIST);
11291942321SJaegeuk Kim 			set_raw_inline(inode, F2FS_INODE(ipage));
113b3d208f9SJaegeuk Kim 			set_page_dirty(ipage);
1149e5ba77fSChao Yu 			return;
1159e5ba77fSChao Yu 		}
1169e5ba77fSChao Yu 	}
1179e5ba77fSChao Yu 	return;
118b3d208f9SJaegeuk Kim }
119b3d208f9SJaegeuk Kim 
f2fs_enable_inode_chksum(struct f2fs_sb_info * sbi,struct page * page)120704956ecSChao Yu static bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct page *page)
121704956ecSChao Yu {
122704956ecSChao Yu 	struct f2fs_inode *ri = &F2FS_NODE(page)->i;
123704956ecSChao Yu 
1247beb01f7SChao Yu 	if (!f2fs_sb_has_inode_chksum(sbi))
125704956ecSChao Yu 		return false;
126704956ecSChao Yu 
1274c6b56c0SChao Yu 	if (!IS_INODE(page) || !(ri->i_inline & F2FS_EXTRA_ATTR))
128704956ecSChao Yu 		return false;
129704956ecSChao Yu 
130d6964949SZhikang Zhang 	if (!F2FS_FITS_IN_INODE(ri, le16_to_cpu(ri->i_extra_isize),
131d6964949SZhikang Zhang 				i_inode_checksum))
132704956ecSChao Yu 		return false;
133704956ecSChao Yu 
134704956ecSChao Yu 	return true;
135704956ecSChao Yu }
136704956ecSChao Yu 
f2fs_inode_chksum(struct f2fs_sb_info * sbi,struct page * page)137704956ecSChao Yu static __u32 f2fs_inode_chksum(struct f2fs_sb_info *sbi, struct page *page)
138704956ecSChao Yu {
139704956ecSChao Yu 	struct f2fs_node *node = F2FS_NODE(page);
140704956ecSChao Yu 	struct f2fs_inode *ri = &node->i;
141704956ecSChao Yu 	__le32 ino = node->footer.ino;
142704956ecSChao Yu 	__le32 gen = ri->i_generation;
143704956ecSChao Yu 	__u32 chksum, chksum_seed;
144704956ecSChao Yu 	__u32 dummy_cs = 0;
145704956ecSChao Yu 	unsigned int offset = offsetof(struct f2fs_inode, i_inode_checksum);
146704956ecSChao Yu 	unsigned int cs_size = sizeof(dummy_cs);
147704956ecSChao Yu 
148704956ecSChao Yu 	chksum = f2fs_chksum(sbi, sbi->s_chksum_seed, (__u8 *)&ino,
149704956ecSChao Yu 							sizeof(ino));
150704956ecSChao Yu 	chksum_seed = f2fs_chksum(sbi, chksum, (__u8 *)&gen, sizeof(gen));
151704956ecSChao Yu 
152704956ecSChao Yu 	chksum = f2fs_chksum(sbi, chksum_seed, (__u8 *)ri, offset);
153704956ecSChao Yu 	chksum = f2fs_chksum(sbi, chksum, (__u8 *)&dummy_cs, cs_size);
154704956ecSChao Yu 	offset += cs_size;
155704956ecSChao Yu 	chksum = f2fs_chksum(sbi, chksum, (__u8 *)ri + offset,
156704956ecSChao Yu 						F2FS_BLKSIZE - offset);
157704956ecSChao Yu 	return chksum;
158704956ecSChao Yu }
159704956ecSChao Yu 
f2fs_inode_chksum_verify(struct f2fs_sb_info * sbi,struct page * page)160704956ecSChao Yu bool f2fs_inode_chksum_verify(struct f2fs_sb_info *sbi, struct page *page)
161704956ecSChao Yu {
162704956ecSChao Yu 	struct f2fs_inode *ri;
163704956ecSChao Yu 	__u32 provided, calculated;
164704956ecSChao Yu 
16583a3bfdbSJaegeuk Kim 	if (unlikely(is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)))
16683a3bfdbSJaegeuk Kim 		return true;
16783a3bfdbSJaegeuk Kim 
16854c55c4eSWeichao Guo #ifdef CONFIG_F2FS_CHECK_FS
16954c55c4eSWeichao Guo 	if (!f2fs_enable_inode_chksum(sbi, page))
17054c55c4eSWeichao Guo #else
171ee605234SJaegeuk Kim 	if (!f2fs_enable_inode_chksum(sbi, page) ||
172ee605234SJaegeuk Kim 			PageDirty(page) || PageWriteback(page))
17354c55c4eSWeichao Guo #endif
174704956ecSChao Yu 		return true;
175704956ecSChao Yu 
176704956ecSChao Yu 	ri = &F2FS_NODE(page)->i;
177704956ecSChao Yu 	provided = le32_to_cpu(ri->i_inode_checksum);
178704956ecSChao Yu 	calculated = f2fs_inode_chksum(sbi, page);
179704956ecSChao Yu 
180704956ecSChao Yu 	if (provided != calculated)
181dcbb4c10SJoe Perches 		f2fs_warn(sbi, "checksum invalid, nid = %lu, ino_of_node = %x, %x vs. %x",
182b42b179bSChao Yu 			  page->index, ino_of_node(page), provided, calculated);
183704956ecSChao Yu 
184704956ecSChao Yu 	return provided == calculated;
185704956ecSChao Yu }
186704956ecSChao Yu 
f2fs_inode_chksum_set(struct f2fs_sb_info * sbi,struct page * page)187704956ecSChao Yu void f2fs_inode_chksum_set(struct f2fs_sb_info *sbi, struct page *page)
188704956ecSChao Yu {
189704956ecSChao Yu 	struct f2fs_inode *ri = &F2FS_NODE(page)->i;
190704956ecSChao Yu 
191704956ecSChao Yu 	if (!f2fs_enable_inode_chksum(sbi, page))
192704956ecSChao Yu 		return;
193704956ecSChao Yu 
194704956ecSChao Yu 	ri->i_inode_checksum = cpu_to_le32(f2fs_inode_chksum(sbi, page));
195704956ecSChao Yu }
196704956ecSChao Yu 
sanity_check_compress_inode(struct inode * inode,struct f2fs_inode * ri)197698a5c8cSYangtao Li static bool sanity_check_compress_inode(struct inode *inode,
198698a5c8cSYangtao Li 			struct f2fs_inode *ri)
199698a5c8cSYangtao Li {
200698a5c8cSYangtao Li 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
201698a5c8cSYangtao Li 	unsigned char clevel;
202698a5c8cSYangtao Li 
203698a5c8cSYangtao Li 	if (ri->i_compress_algorithm >= COMPRESS_MAX) {
204698a5c8cSYangtao Li 		f2fs_warn(sbi,
205698a5c8cSYangtao Li 			"%s: inode (ino=%lx) has unsupported compress algorithm: %u, run fsck to fix",
206698a5c8cSYangtao Li 			__func__, inode->i_ino, ri->i_compress_algorithm);
207c9887949SChao Yu 		return false;
208698a5c8cSYangtao Li 	}
209698a5c8cSYangtao Li 	if (le64_to_cpu(ri->i_compr_blocks) >
210698a5c8cSYangtao Li 			SECTOR_TO_BLOCK(inode->i_blocks)) {
211698a5c8cSYangtao Li 		f2fs_warn(sbi,
212698a5c8cSYangtao Li 			"%s: inode (ino=%lx) has inconsistent i_compr_blocks:%llu, i_blocks:%llu, run fsck to fix",
213698a5c8cSYangtao Li 			__func__, inode->i_ino, le64_to_cpu(ri->i_compr_blocks),
214698a5c8cSYangtao Li 			SECTOR_TO_BLOCK(inode->i_blocks));
215c9887949SChao Yu 		return false;
216698a5c8cSYangtao Li 	}
217698a5c8cSYangtao Li 	if (ri->i_log_cluster_size < MIN_COMPRESS_LOG_SIZE ||
218698a5c8cSYangtao Li 		ri->i_log_cluster_size > MAX_COMPRESS_LOG_SIZE) {
219698a5c8cSYangtao Li 		f2fs_warn(sbi,
220698a5c8cSYangtao Li 			"%s: inode (ino=%lx) has unsupported log cluster size: %u, run fsck to fix",
221698a5c8cSYangtao Li 			__func__, inode->i_ino, ri->i_log_cluster_size);
222c9887949SChao Yu 		return false;
223698a5c8cSYangtao Li 	}
224698a5c8cSYangtao Li 
225698a5c8cSYangtao Li 	clevel = le16_to_cpu(ri->i_compress_flag) >>
226698a5c8cSYangtao Li 				COMPRESS_LEVEL_OFFSET;
227698a5c8cSYangtao Li 	switch (ri->i_compress_algorithm) {
228698a5c8cSYangtao Li 	case COMPRESS_LZO:
229698a5c8cSYangtao Li #ifdef CONFIG_F2FS_FS_LZO
230698a5c8cSYangtao Li 		if (clevel)
231698a5c8cSYangtao Li 			goto err_level;
232698a5c8cSYangtao Li #endif
233698a5c8cSYangtao Li 		break;
234698a5c8cSYangtao Li 	case COMPRESS_LZORLE:
235698a5c8cSYangtao Li #ifdef CONFIG_F2FS_FS_LZORLE
236698a5c8cSYangtao Li 		if (clevel)
237698a5c8cSYangtao Li 			goto err_level;
238698a5c8cSYangtao Li #endif
239698a5c8cSYangtao Li 		break;
240698a5c8cSYangtao Li 	case COMPRESS_LZ4:
241698a5c8cSYangtao Li #ifdef CONFIG_F2FS_FS_LZ4
242698a5c8cSYangtao Li #ifdef CONFIG_F2FS_FS_LZ4HC
243698a5c8cSYangtao Li 		if (clevel &&
244698a5c8cSYangtao Li 		   (clevel < LZ4HC_MIN_CLEVEL || clevel > LZ4HC_MAX_CLEVEL))
245698a5c8cSYangtao Li 			goto err_level;
246698a5c8cSYangtao Li #else
247698a5c8cSYangtao Li 		if (clevel)
248698a5c8cSYangtao Li 			goto err_level;
249698a5c8cSYangtao Li #endif
250698a5c8cSYangtao Li #endif
251698a5c8cSYangtao Li 		break;
252698a5c8cSYangtao Li 	case COMPRESS_ZSTD:
253698a5c8cSYangtao Li #ifdef CONFIG_F2FS_FS_ZSTD
254698a5c8cSYangtao Li 		if (clevel < zstd_min_clevel() || clevel > zstd_max_clevel())
255698a5c8cSYangtao Li 			goto err_level;
256698a5c8cSYangtao Li #endif
257698a5c8cSYangtao Li 		break;
258698a5c8cSYangtao Li 	default:
259698a5c8cSYangtao Li 		goto err_level;
260698a5c8cSYangtao Li 	}
261698a5c8cSYangtao Li 
262698a5c8cSYangtao Li 	return true;
263698a5c8cSYangtao Li err_level:
264698a5c8cSYangtao Li 	f2fs_warn(sbi, "%s: inode (ino=%lx) has unsupported compress level: %u, run fsck to fix",
265698a5c8cSYangtao Li 		  __func__, inode->i_ino, clevel);
266698a5c8cSYangtao Li 	return false;
267698a5c8cSYangtao Li }
268698a5c8cSYangtao Li 
sanity_check_inode(struct inode * inode,struct page * node_page)269e34438c9SChao Yu static bool sanity_check_inode(struct inode *inode, struct page *node_page)
2705d64600dSJaegeuk Kim {
2715d64600dSJaegeuk Kim 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
27218dd6470SChao Yu 	struct f2fs_inode_info *fi = F2FS_I(inode);
2734c8ff709SChao Yu 	struct f2fs_inode *ri = F2FS_INODE(node_page);
274e34438c9SChao Yu 	unsigned long long iblocks;
275e34438c9SChao Yu 
276e34438c9SChao Yu 	iblocks = le64_to_cpu(F2FS_INODE(node_page)->i_blocks);
277e34438c9SChao Yu 	if (!iblocks) {
278dcbb4c10SJoe Perches 		f2fs_warn(sbi, "%s: corrupted inode i_blocks i_ino=%lx iblocks=%llu, run fsck to fix.",
279e34438c9SChao Yu 			  __func__, inode->i_ino, iblocks);
280e34438c9SChao Yu 		return false;
281e34438c9SChao Yu 	}
282e34438c9SChao Yu 
283e34438c9SChao Yu 	if (ino_of_node(node_page) != nid_of_node(node_page)) {
284dcbb4c10SJoe Perches 		f2fs_warn(sbi, "%s: corrupted inode footer i_ino=%lx, ino,nid: [%u, %u] run fsck to fix.",
285e34438c9SChao Yu 			  __func__, inode->i_ino,
286e34438c9SChao Yu 			  ino_of_node(node_page), nid_of_node(node_page));
287e34438c9SChao Yu 		return false;
288e34438c9SChao Yu 	}
2895d64600dSJaegeuk Kim 
290f240d3aaSChao Yu 	if (f2fs_has_extra_attr(inode)) {
291f240d3aaSChao Yu 		if (!f2fs_sb_has_extra_attr(sbi)) {
292dcbb4c10SJoe Perches 			f2fs_warn(sbi, "%s: inode (ino=%lx) is with extra_attr, but extra_attr feature is off",
29376d56d4aSChao Yu 				  __func__, inode->i_ino);
29476d56d4aSChao Yu 			return false;
29576d56d4aSChao Yu 		}
29618dd6470SChao Yu 		if (fi->i_extra_isize > F2FS_TOTAL_EXTRA_ATTR_SIZE ||
297f240d3aaSChao Yu 			fi->i_extra_isize < F2FS_MIN_EXTRA_ATTR_SIZE ||
29818dd6470SChao Yu 			fi->i_extra_isize % sizeof(__le32)) {
299dcbb4c10SJoe Perches 			f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_extra_isize: %d, max: %zu",
30018dd6470SChao Yu 				  __func__, inode->i_ino, fi->i_extra_isize,
30118dd6470SChao Yu 				  F2FS_TOTAL_EXTRA_ATTR_SIZE);
30218dd6470SChao Yu 			return false;
30318dd6470SChao Yu 		}
304f240d3aaSChao Yu 		if (f2fs_sb_has_flexible_inline_xattr(sbi) &&
305dd6c89b5SChao Yu 			f2fs_has_inline_xattr(inode) &&
306dd6c89b5SChao Yu 			(!fi->i_inline_xattr_size ||
307dd6c89b5SChao Yu 			fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE)) {
308dcbb4c10SJoe Perches 			f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_inline_xattr_size: %d, max: %zu",
309dd6c89b5SChao Yu 				  __func__, inode->i_ino, fi->i_inline_xattr_size,
310dd6c89b5SChao Yu 				  MAX_INLINE_XATTR_SIZE);
311dd6c89b5SChao Yu 			return false;
312dd6c89b5SChao Yu 		}
313f240d3aaSChao Yu 		if (f2fs_sb_has_compression(sbi) &&
314f240d3aaSChao Yu 			fi->i_flags & F2FS_COMPR_FL &&
315f240d3aaSChao Yu 			F2FS_FITS_IN_INODE(ri, fi->i_extra_isize,
316f240d3aaSChao Yu 						i_compress_flag)) {
317f240d3aaSChao Yu 			if (!sanity_check_compress_inode(inode, ri))
318f240d3aaSChao Yu 				return false;
319f240d3aaSChao Yu 		}
320f240d3aaSChao Yu 	} else if (f2fs_sb_has_flexible_inline_xattr(sbi)) {
321f240d3aaSChao Yu 		f2fs_warn(sbi, "%s: corrupted inode ino=%lx, run fsck to fix.",
322f240d3aaSChao Yu 			  __func__, inode->i_ino);
323f240d3aaSChao Yu 		return false;
324f240d3aaSChao Yu 	}
325f240d3aaSChao Yu 
326f240d3aaSChao Yu 	if (!f2fs_sb_has_extra_attr(sbi)) {
327f240d3aaSChao Yu 		if (f2fs_sb_has_project_quota(sbi)) {
328f240d3aaSChao Yu 			f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.",
329f240d3aaSChao Yu 				  __func__, inode->i_ino, F2FS_FEATURE_PRJQUOTA);
330f240d3aaSChao Yu 			return false;
331f240d3aaSChao Yu 		}
332f240d3aaSChao Yu 		if (f2fs_sb_has_inode_chksum(sbi)) {
333f240d3aaSChao Yu 			f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.",
334f240d3aaSChao Yu 				  __func__, inode->i_ino, F2FS_FEATURE_INODE_CHKSUM);
335f240d3aaSChao Yu 			return false;
336f240d3aaSChao Yu 		}
337f240d3aaSChao Yu 		if (f2fs_sb_has_flexible_inline_xattr(sbi)) {
338f240d3aaSChao Yu 			f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.",
339f240d3aaSChao Yu 				  __func__, inode->i_ino, F2FS_FEATURE_FLEXIBLE_INLINE_XATTR);
340f240d3aaSChao Yu 			return false;
341f240d3aaSChao Yu 		}
342f240d3aaSChao Yu 		if (f2fs_sb_has_inode_crtime(sbi)) {
343f240d3aaSChao Yu 			f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.",
344f240d3aaSChao Yu 				  __func__, inode->i_ino, F2FS_FEATURE_INODE_CRTIME);
345f240d3aaSChao Yu 			return false;
346f240d3aaSChao Yu 		}
347f240d3aaSChao Yu 		if (f2fs_sb_has_compression(sbi)) {
348f240d3aaSChao Yu 			f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.",
349f240d3aaSChao Yu 				  __func__, inode->i_ino, F2FS_FEATURE_COMPRESSION);
350f240d3aaSChao Yu 			return false;
351f240d3aaSChao Yu 		}
352f240d3aaSChao Yu 	}
353dd6c89b5SChao Yu 
3546290d3f5SChao Yu 	if (f2fs_sanity_check_inline_data(inode, node_page)) {
355dcbb4c10SJoe Perches 		f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_data, run fsck to fix",
356bcbfbd60SChao Yu 			  __func__, inode->i_ino, inode->i_mode);
357bcbfbd60SChao Yu 		return false;
358bcbfbd60SChao Yu 	}
359bcbfbd60SChao Yu 
360bcbfbd60SChao Yu 	if (f2fs_has_inline_dentry(inode) && !S_ISDIR(inode->i_mode)) {
361dcbb4c10SJoe Perches 		f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_dentry, run fsck to fix",
362bcbfbd60SChao Yu 			  __func__, inode->i_ino, inode->i_mode);
363bcbfbd60SChao Yu 		return false;
364bcbfbd60SChao Yu 	}
365bcbfbd60SChao Yu 
366f6322f3fSEric Biggers 	if ((fi->i_flags & F2FS_CASEFOLD_FL) && !f2fs_sb_has_casefold(sbi)) {
367f6322f3fSEric Biggers 		f2fs_warn(sbi, "%s: inode (ino=%lx) has casefold flag, but casefold feature is off",
368f6322f3fSEric Biggers 			  __func__, inode->i_ino);
369f6322f3fSEric Biggers 		return false;
370f6322f3fSEric Biggers 	}
371f6322f3fSEric Biggers 
372be015520SChao Yu 	if (fi->i_xattr_nid && f2fs_check_nid_range(sbi, fi->i_xattr_nid)) {
373be015520SChao Yu 		f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_xattr_nid: %u, run fsck to fix.",
374be015520SChao Yu 			  __func__, inode->i_ino, fi->i_xattr_nid);
375be015520SChao Yu 		return false;
376be015520SChao Yu 	}
377be015520SChao Yu 
3785d64600dSJaegeuk Kim 	return true;
3795d64600dSJaegeuk Kim }
3805d64600dSJaegeuk Kim 
init_idisk_time(struct inode * inode)381049ea86cSZhang Qilong static void init_idisk_time(struct inode *inode)
382049ea86cSZhang Qilong {
383049ea86cSZhang Qilong 	struct f2fs_inode_info *fi = F2FS_I(inode);
384049ea86cSZhang Qilong 
385049ea86cSZhang Qilong 	fi->i_disk_time[0] = inode->i_atime;
386c62ebd35SJeff Layton 	fi->i_disk_time[1] = inode_get_ctime(inode);
387049ea86cSZhang Qilong 	fi->i_disk_time[2] = inode->i_mtime;
388049ea86cSZhang Qilong }
389049ea86cSZhang Qilong 
do_read_inode(struct inode * inode)39019f99ceeSJaegeuk Kim static int do_read_inode(struct inode *inode)
39119f99ceeSJaegeuk Kim {
3924081363fSJaegeuk Kim 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
39319f99ceeSJaegeuk Kim 	struct f2fs_inode_info *fi = F2FS_I(inode);
39419f99ceeSJaegeuk Kim 	struct page *node_page;
39519f99ceeSJaegeuk Kim 	struct f2fs_inode *ri;
3965c57132eSChao Yu 	projid_t i_projid;
39719f99ceeSJaegeuk Kim 
39819f99ceeSJaegeuk Kim 	/* Check if ino is within scope */
3994d57b86dSChao Yu 	if (f2fs_check_nid_range(sbi, inode->i_ino))
400064e0823SNamjae Jeon 		return -EINVAL;
40119f99ceeSJaegeuk Kim 
4024d57b86dSChao Yu 	node_page = f2fs_get_node_page(sbi, inode->i_ino);
40319f99ceeSJaegeuk Kim 	if (IS_ERR(node_page))
40419f99ceeSJaegeuk Kim 		return PTR_ERR(node_page);
40519f99ceeSJaegeuk Kim 
40658bfaf44SJaegeuk Kim 	ri = F2FS_INODE(node_page);
40719f99ceeSJaegeuk Kim 
40819f99ceeSJaegeuk Kim 	inode->i_mode = le16_to_cpu(ri->i_mode);
40919f99ceeSJaegeuk Kim 	i_uid_write(inode, le32_to_cpu(ri->i_uid));
41019f99ceeSJaegeuk Kim 	i_gid_write(inode, le32_to_cpu(ri->i_gid));
41119f99ceeSJaegeuk Kim 	set_nlink(inode, le32_to_cpu(ri->i_links));
41219f99ceeSJaegeuk Kim 	inode->i_size = le64_to_cpu(ri->i_size);
413000519f2SChao Yu 	inode->i_blocks = SECTOR_FROM_BLOCK(le64_to_cpu(ri->i_blocks) - 1);
41419f99ceeSJaegeuk Kim 
41519f99ceeSJaegeuk Kim 	inode->i_atime.tv_sec = le64_to_cpu(ri->i_atime);
416c62ebd35SJeff Layton 	inode_set_ctime(inode, le64_to_cpu(ri->i_ctime),
417c62ebd35SJeff Layton 			le32_to_cpu(ri->i_ctime_nsec));
41819f99ceeSJaegeuk Kim 	inode->i_mtime.tv_sec = le64_to_cpu(ri->i_mtime);
41919f99ceeSJaegeuk Kim 	inode->i_atime.tv_nsec = le32_to_cpu(ri->i_atime_nsec);
42019f99ceeSJaegeuk Kim 	inode->i_mtime.tv_nsec = le32_to_cpu(ri->i_mtime_nsec);
42119f99ceeSJaegeuk Kim 	inode->i_generation = le32_to_cpu(ri->i_generation);
4221c41e680SChao Yu 	if (S_ISDIR(inode->i_mode))
42319f99ceeSJaegeuk Kim 		fi->i_current_depth = le32_to_cpu(ri->i_current_depth);
4241c41e680SChao Yu 	else if (S_ISREG(inode->i_mode))
4252ef79ecbSChao Yu 		fi->i_gc_failures[GC_FAILURE_PIN] =
4262ef79ecbSChao Yu 					le16_to_cpu(ri->i_gc_failures);
42719f99ceeSJaegeuk Kim 	fi->i_xattr_nid = le32_to_cpu(ri->i_xattr_nid);
42819f99ceeSJaegeuk Kim 	fi->i_flags = le32_to_cpu(ri->i_flags);
4295043a964SWang Shilong 	if (S_ISREG(inode->i_mode))
4305043a964SWang Shilong 		fi->i_flags &= ~F2FS_PROJINHERIT_FL;
4317653b9d8SChao Yu 	bitmap_zero(fi->flags, FI_MAX);
43219f99ceeSJaegeuk Kim 	fi->i_advise = ri->i_advise;
4336666e6aaSJaegeuk Kim 	fi->i_pino = le32_to_cpu(ri->i_pino);
43438431545SJaegeuk Kim 	fi->i_dir_level = ri->i_dir_level;
4353d1e3807SJaegeuk Kim 
43691942321SJaegeuk Kim 	get_inline_info(inode, ri);
4373d1e3807SJaegeuk Kim 
4387a2af766SChao Yu 	fi->i_extra_isize = f2fs_has_extra_attr(inode) ?
4397a2af766SChao Yu 					le16_to_cpu(ri->i_extra_isize) : 0;
4407a2af766SChao Yu 
4417beb01f7SChao Yu 	if (f2fs_sb_has_flexible_inline_xattr(sbi)) {
4426afc662eSChao Yu 		fi->i_inline_xattr_size = le16_to_cpu(ri->i_inline_xattr_size);
4436afc662eSChao Yu 	} else if (f2fs_has_inline_xattr(inode) ||
4446afc662eSChao Yu 				f2fs_has_inline_dentry(inode)) {
4456afc662eSChao Yu 		fi->i_inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS;
4466afc662eSChao Yu 	} else {
4476afc662eSChao Yu 
4486afc662eSChao Yu 		/*
4496afc662eSChao Yu 		 * Previous inline data or directory always reserved 200 bytes
4506afc662eSChao Yu 		 * in inode layout, even if inline_xattr is disabled. In order
4516afc662eSChao Yu 		 * to keep inline_dentry's structure for backward compatibility,
4526afc662eSChao Yu 		 * we get the space back only from inline_data.
4536afc662eSChao Yu 		 */
4546afc662eSChao Yu 		fi->i_inline_xattr_size = 0;
4556afc662eSChao Yu 	}
4566afc662eSChao Yu 
457958ccbbfSChao Yu 	if (!sanity_check_inode(inode, node_page)) {
458958ccbbfSChao Yu 		f2fs_put_page(node_page, 1);
459c9887949SChao Yu 		set_sbi_flag(sbi, SBI_NEED_FSCK);
460958ccbbfSChao Yu 		f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE);
461958ccbbfSChao Yu 		return -EFSCORRUPTED;
462958ccbbfSChao Yu 	}
463958ccbbfSChao Yu 
464b3d208f9SJaegeuk Kim 	/* check data exist */
465b3d208f9SJaegeuk Kim 	if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode))
4669e5ba77fSChao Yu 		__recover_inline_status(inode, node_page);
467b3d208f9SJaegeuk Kim 
468ef2a0071SChao Yu 	/* try to recover cold bit for non-dir inode */
469ef2a0071SChao Yu 	if (!S_ISDIR(inode->i_mode) && !is_cold_node(node_page)) {
470db5ae363SWuyun Zhao 		f2fs_wait_on_page_writeback(node_page, NODE, true, true);
471ef2a0071SChao Yu 		set_cold_node(node_page, false);
472ef2a0071SChao Yu 		set_page_dirty(node_page);
473ef2a0071SChao Yu 	}
474ef2a0071SChao Yu 
4753d1e3807SJaegeuk Kim 	/* get rdev by using inline_info */
476dcd6b38bSChao Yu 	__get_inode_rdev(inode, node_page);
4773d1e3807SJaegeuk Kim 
4784d57b86dSChao Yu 	if (!f2fs_need_inode_block_update(sbi, inode->i_ino))
47926de9b11SJaegeuk Kim 		fi->last_disk_size = inode->i_size;
48026de9b11SJaegeuk Kim 
48159c84408SChao Yu 	if (fi->i_flags & F2FS_PROJINHERIT_FL)
4825c57132eSChao Yu 		set_inode_flag(inode, FI_PROJ_INHERIT);
4835c57132eSChao Yu 
4847beb01f7SChao Yu 	if (f2fs_has_extra_attr(inode) && f2fs_sb_has_project_quota(sbi) &&
4855c57132eSChao Yu 			F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, i_projid))
4865c57132eSChao Yu 		i_projid = (projid_t)le32_to_cpu(ri->i_projid);
4875c57132eSChao Yu 	else
4885c57132eSChao Yu 		i_projid = F2FS_DEF_PROJID;
4895c57132eSChao Yu 	fi->i_projid = make_kprojid(&init_user_ns, i_projid);
4905c57132eSChao Yu 
4917beb01f7SChao Yu 	if (f2fs_has_extra_attr(inode) && f2fs_sb_has_inode_crtime(sbi) &&
4921c1d35dfSChao Yu 			F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, i_crtime)) {
4931c1d35dfSChao Yu 		fi->i_crtime.tv_sec = le64_to_cpu(ri->i_crtime);
4941c1d35dfSChao Yu 		fi->i_crtime.tv_nsec = le32_to_cpu(ri->i_crtime_nsec);
4951c1d35dfSChao Yu 	}
4961c1d35dfSChao Yu 
4974c8ff709SChao Yu 	if (f2fs_has_extra_attr(inode) && f2fs_sb_has_compression(sbi) &&
4984c8ff709SChao Yu 					(fi->i_flags & F2FS_COMPR_FL)) {
4994c8ff709SChao Yu 		if (F2FS_FITS_IN_INODE(ri, fi->i_extra_isize,
50064ee9163SChao Yu 					i_compress_flag)) {
501b90e5086SChao Yu 			unsigned short compress_flag;
502b90e5086SChao Yu 
503c2759ebaSDaeho Jeong 			atomic_set(&fi->i_compr_blocks,
504c2759ebaSDaeho Jeong 					le64_to_cpu(ri->i_compr_blocks));
5054c8ff709SChao Yu 			fi->i_compress_algorithm = ri->i_compress_algorithm;
5064c8ff709SChao Yu 			fi->i_log_cluster_size = ri->i_log_cluster_size;
507b90e5086SChao Yu 			compress_flag = le16_to_cpu(ri->i_compress_flag);
508b90e5086SChao Yu 			fi->i_compress_level = compress_flag >>
509b90e5086SChao Yu 						COMPRESS_LEVEL_OFFSET;
510b90e5086SChao Yu 			fi->i_compress_flag = compress_flag &
511447286ebSYangtao Li 					GENMASK(COMPRESS_LEVEL_OFFSET - 1, 0);
512447286ebSYangtao Li 			fi->i_cluster_size = BIT(fi->i_log_cluster_size);
5134c8ff709SChao Yu 			set_inode_flag(inode, FI_COMPRESSED_FILE);
5144c8ff709SChao Yu 		}
5154c8ff709SChao Yu 	}
5164c8ff709SChao Yu 
517049ea86cSZhang Qilong 	init_idisk_time(inode);
51872840cccSJaegeuk Kim 
519263df781SChao Yu 	if (!sanity_check_extent_cache(inode, node_page)) {
520269d1194SChao Yu 		f2fs_put_page(node_page, 1);
521269d1194SChao Yu 		f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE);
522269d1194SChao Yu 		return -EFSCORRUPTED;
523269d1194SChao Yu 	}
524269d1194SChao Yu 
525263df781SChao Yu 	/* Need all the flag bits */
526263df781SChao Yu 	f2fs_init_read_extent_tree(inode, node_page);
527263df781SChao Yu 	f2fs_init_age_extent_tree(inode);
528263df781SChao Yu 
52919f99ceeSJaegeuk Kim 	f2fs_put_page(node_page, 1);
5309d1015ddSJaegeuk Kim 
531d5e8f6c9SChao Yu 	stat_inc_inline_xattr(inode);
5329d1015ddSJaegeuk Kim 	stat_inc_inline_inode(inode);
5339d1015ddSJaegeuk Kim 	stat_inc_inline_dir(inode);
5344c8ff709SChao Yu 	stat_inc_compr_inode(inode);
535c2759ebaSDaeho Jeong 	stat_add_compr_blocks(inode, atomic_read(&fi->i_compr_blocks));
5369d1015ddSJaegeuk Kim 
5379e5ba77fSChao Yu 	return 0;
53819f99ceeSJaegeuk Kim }
53919f99ceeSJaegeuk Kim 
is_meta_ino(struct f2fs_sb_info * sbi,unsigned int ino)540fcc2d8ccSChao Yu static bool is_meta_ino(struct f2fs_sb_info *sbi, unsigned int ino)
541fcc2d8ccSChao Yu {
542fcc2d8ccSChao Yu 	return ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi) ||
543fcc2d8ccSChao Yu 		ino == F2FS_COMPRESS_INO(sbi);
544fcc2d8ccSChao Yu }
545fcc2d8ccSChao Yu 
f2fs_iget(struct super_block * sb,unsigned long ino)54619f99ceeSJaegeuk Kim struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
54719f99ceeSJaegeuk Kim {
54819f99ceeSJaegeuk Kim 	struct f2fs_sb_info *sbi = F2FS_SB(sb);
54919f99ceeSJaegeuk Kim 	struct inode *inode;
550a2a4a7e4SNamjae Jeon 	int ret = 0;
55119f99ceeSJaegeuk Kim 
55219f99ceeSJaegeuk Kim 	inode = iget_locked(sb, ino);
55319f99ceeSJaegeuk Kim 	if (!inode)
55419f99ceeSJaegeuk Kim 		return ERR_PTR(-ENOMEM);
555a2a4a7e4SNamjae Jeon 
556a2a4a7e4SNamjae Jeon 	if (!(inode->i_state & I_NEW)) {
557fcc2d8ccSChao Yu 		if (is_meta_ino(sbi, ino)) {
558fcc2d8ccSChao Yu 			f2fs_err(sbi, "inaccessible inode: %lu, run fsck to repair", ino);
559fcc2d8ccSChao Yu 			set_sbi_flag(sbi, SBI_NEED_FSCK);
560fcc2d8ccSChao Yu 			ret = -EFSCORRUPTED;
561fcc2d8ccSChao Yu 			trace_f2fs_iget_exit(inode, ret);
562fcc2d8ccSChao Yu 			iput(inode);
56395fa90c9SChao Yu 			f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE);
564fcc2d8ccSChao Yu 			return ERR_PTR(ret);
565fcc2d8ccSChao Yu 		}
566fcc2d8ccSChao Yu 
567a2a4a7e4SNamjae Jeon 		trace_f2fs_iget(inode);
56819f99ceeSJaegeuk Kim 		return inode;
569a2a4a7e4SNamjae Jeon 	}
57019f99ceeSJaegeuk Kim 
571fcc2d8ccSChao Yu 	if (is_meta_ino(sbi, ino))
5726ce19affSChao Yu 		goto make_now;
5736ce19affSChao Yu 
57419f99ceeSJaegeuk Kim 	ret = do_read_inode(inode);
57519f99ceeSJaegeuk Kim 	if (ret)
57619f99ceeSJaegeuk Kim 		goto bad_inode;
57719f99ceeSJaegeuk Kim make_now:
57819f99ceeSJaegeuk Kim 	if (ino == F2FS_NODE_INO(sbi)) {
57919f99ceeSJaegeuk Kim 		inode->i_mapping->a_ops = &f2fs_node_aops;
58081114baaSChao Yu 		mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
58119f99ceeSJaegeuk Kim 	} else if (ino == F2FS_META_INO(sbi)) {
58219f99ceeSJaegeuk Kim 		inode->i_mapping->a_ops = &f2fs_meta_aops;
58381114baaSChao Yu 		mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
5846ce19affSChao Yu 	} else if (ino == F2FS_COMPRESS_INO(sbi)) {
5856ce19affSChao Yu #ifdef CONFIG_F2FS_FS_COMPRESSION
5866ce19affSChao Yu 		inode->i_mapping->a_ops = &f2fs_compress_aops;
587d1917865SFengnan Chang 		/*
588d1917865SFengnan Chang 		 * generic_error_remove_page only truncates pages of regular
589d1917865SFengnan Chang 		 * inode
590d1917865SFengnan Chang 		 */
591d1917865SFengnan Chang 		inode->i_mode |= S_IFREG;
5926ce19affSChao Yu #endif
5936ce19affSChao Yu 		mapping_set_gfp_mask(inode->i_mapping,
5946ce19affSChao Yu 			GFP_NOFS | __GFP_HIGHMEM | __GFP_MOVABLE);
59519f99ceeSJaegeuk Kim 	} else if (S_ISREG(inode->i_mode)) {
59619f99ceeSJaegeuk Kim 		inode->i_op = &f2fs_file_inode_operations;
59719f99ceeSJaegeuk Kim 		inode->i_fop = &f2fs_file_operations;
59819f99ceeSJaegeuk Kim 		inode->i_mapping->a_ops = &f2fs_dblock_aops;
59919f99ceeSJaegeuk Kim 	} else if (S_ISDIR(inode->i_mode)) {
60019f99ceeSJaegeuk Kim 		inode->i_op = &f2fs_dir_inode_operations;
60119f99ceeSJaegeuk Kim 		inode->i_fop = &f2fs_dir_operations;
60219f99ceeSJaegeuk Kim 		inode->i_mapping->a_ops = &f2fs_dblock_aops;
60392d602bcSJaegeuk Kim 		mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
60419f99ceeSJaegeuk Kim 	} else if (S_ISLNK(inode->i_mode)) {
60562230e0dSChandan Rajendra 		if (file_is_encrypt(inode))
606cbaf042aSJaegeuk Kim 			inode->i_op = &f2fs_encrypted_symlink_inode_operations;
607cbaf042aSJaegeuk Kim 		else
60819f99ceeSJaegeuk Kim 			inode->i_op = &f2fs_symlink_inode_operations;
60921fc61c7SAl Viro 		inode_nohighmem(inode);
61019f99ceeSJaegeuk Kim 		inode->i_mapping->a_ops = &f2fs_dblock_aops;
61119f99ceeSJaegeuk Kim 	} else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
61219f99ceeSJaegeuk Kim 			S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
61319f99ceeSJaegeuk Kim 		inode->i_op = &f2fs_special_inode_operations;
61419f99ceeSJaegeuk Kim 		init_special_inode(inode, inode->i_mode, inode->i_rdev);
61519f99ceeSJaegeuk Kim 	} else {
61619f99ceeSJaegeuk Kim 		ret = -EIO;
61719f99ceeSJaegeuk Kim 		goto bad_inode;
61819f99ceeSJaegeuk Kim 	}
61993607124SJaegeuk Kim 	f2fs_set_inode_flags(inode);
620d4dd19ecSJaegeuk Kim 
62119f99ceeSJaegeuk Kim 	unlock_new_inode(inode);
622a2a4a7e4SNamjae Jeon 	trace_f2fs_iget(inode);
62319f99ceeSJaegeuk Kim 	return inode;
62419f99ceeSJaegeuk Kim 
62519f99ceeSJaegeuk Kim bad_inode:
626546d22f0SChao Yu 	f2fs_inode_synced(inode);
62719f99ceeSJaegeuk Kim 	iget_failed(inode);
628a2a4a7e4SNamjae Jeon 	trace_f2fs_iget_exit(inode, ret);
62919f99ceeSJaegeuk Kim 	return ERR_PTR(ret);
63019f99ceeSJaegeuk Kim }
63119f99ceeSJaegeuk Kim 
f2fs_iget_retry(struct super_block * sb,unsigned long ino)632e8ea9b3dSJaegeuk Kim struct inode *f2fs_iget_retry(struct super_block *sb, unsigned long ino)
633e8ea9b3dSJaegeuk Kim {
634e8ea9b3dSJaegeuk Kim 	struct inode *inode;
635e8ea9b3dSJaegeuk Kim retry:
636e8ea9b3dSJaegeuk Kim 	inode = f2fs_iget(sb, ino);
637e8ea9b3dSJaegeuk Kim 	if (IS_ERR(inode)) {
638e8ea9b3dSJaegeuk Kim 		if (PTR_ERR(inode) == -ENOMEM) {
6394034247aSNeilBrown 			memalloc_retry_wait(GFP_NOFS);
640e8ea9b3dSJaegeuk Kim 			goto retry;
641e8ea9b3dSJaegeuk Kim 		}
642e8ea9b3dSJaegeuk Kim 	}
643e8ea9b3dSJaegeuk Kim 	return inode;
644e8ea9b3dSJaegeuk Kim }
645e8ea9b3dSJaegeuk Kim 
f2fs_update_inode(struct inode * inode,struct page * node_page)6464d57b86dSChao Yu void f2fs_update_inode(struct inode *inode, struct page *node_page)
64719f99ceeSJaegeuk Kim {
64819f99ceeSJaegeuk Kim 	struct f2fs_inode *ri;
649e7547dacSJaegeuk Kim 	struct extent_tree *et = F2FS_I(inode)->extent_tree[EX_READ];
65019f99ceeSJaegeuk Kim 
651bae0ee7aSChao Yu 	f2fs_wait_on_page_writeback(node_page, NODE, true, true);
652211a6fa0SYunlei He 	set_page_dirty(node_page);
653211a6fa0SYunlei He 
654211a6fa0SYunlei He 	f2fs_inode_synced(inode);
65519f99ceeSJaegeuk Kim 
65658bfaf44SJaegeuk Kim 	ri = F2FS_INODE(node_page);
65719f99ceeSJaegeuk Kim 
65819f99ceeSJaegeuk Kim 	ri->i_mode = cpu_to_le16(inode->i_mode);
65919f99ceeSJaegeuk Kim 	ri->i_advise = F2FS_I(inode)->i_advise;
66019f99ceeSJaegeuk Kim 	ri->i_uid = cpu_to_le32(i_uid_read(inode));
66119f99ceeSJaegeuk Kim 	ri->i_gid = cpu_to_le32(i_gid_read(inode));
66219f99ceeSJaegeuk Kim 	ri->i_links = cpu_to_le32(inode->i_nlink);
663000519f2SChao Yu 	ri->i_blocks = cpu_to_le64(SECTOR_TO_BLOCK(inode->i_blocks) + 1);
6640c872e2dSChao Yu 
6654d8d45dfSDaeho Jeong 	if (!f2fs_is_atomic_file(inode) ||
6664d8d45dfSDaeho Jeong 			is_inode_flag_set(inode, FI_ATOMIC_COMMITTED))
6674d8d45dfSDaeho Jeong 		ri->i_size = cpu_to_le64(i_size_read(inode));
6684d8d45dfSDaeho Jeong 
669b691d98fSChao Yu 	if (et) {
670b691d98fSChao Yu 		read_lock(&et->lock);
67112607c1bSJaegeuk Kim 		set_raw_read_extent(&et->largest, &ri->i_ext);
672b691d98fSChao Yu 		read_unlock(&et->lock);
673b691d98fSChao Yu 	} else {
6743e72f721SJaegeuk Kim 		memset(&ri->i_ext, 0, sizeof(ri->i_ext));
675b691d98fSChao Yu 	}
67691942321SJaegeuk Kim 	set_raw_inline(inode, ri);
67719f99ceeSJaegeuk Kim 
67819f99ceeSJaegeuk Kim 	ri->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
679c62ebd35SJeff Layton 	ri->i_ctime = cpu_to_le64(inode_get_ctime(inode).tv_sec);
68019f99ceeSJaegeuk Kim 	ri->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec);
68119f99ceeSJaegeuk Kim 	ri->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
682c62ebd35SJeff Layton 	ri->i_ctime_nsec = cpu_to_le32(inode_get_ctime(inode).tv_nsec);
68319f99ceeSJaegeuk Kim 	ri->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
6841c41e680SChao Yu 	if (S_ISDIR(inode->i_mode))
6851c41e680SChao Yu 		ri->i_current_depth =
6861c41e680SChao Yu 			cpu_to_le32(F2FS_I(inode)->i_current_depth);
6871c41e680SChao Yu 	else if (S_ISREG(inode->i_mode))
6882ef79ecbSChao Yu 		ri->i_gc_failures =
6892ef79ecbSChao Yu 			cpu_to_le16(F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN]);
69019f99ceeSJaegeuk Kim 	ri->i_xattr_nid = cpu_to_le32(F2FS_I(inode)->i_xattr_nid);
69119f99ceeSJaegeuk Kim 	ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags);
6926666e6aaSJaegeuk Kim 	ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino);
69319f99ceeSJaegeuk Kim 	ri->i_generation = cpu_to_le32(inode->i_generation);
69438431545SJaegeuk Kim 	ri->i_dir_level = F2FS_I(inode)->i_dir_level;
6957d79e75fSChangman Lee 
6965c57132eSChao Yu 	if (f2fs_has_extra_attr(inode)) {
6977a2af766SChao Yu 		ri->i_extra_isize = cpu_to_le16(F2FS_I(inode)->i_extra_isize);
6987a2af766SChao Yu 
6997beb01f7SChao Yu 		if (f2fs_sb_has_flexible_inline_xattr(F2FS_I_SB(inode)))
7006afc662eSChao Yu 			ri->i_inline_xattr_size =
7016afc662eSChao Yu 				cpu_to_le16(F2FS_I(inode)->i_inline_xattr_size);
7026afc662eSChao Yu 
7037beb01f7SChao Yu 		if (f2fs_sb_has_project_quota(F2FS_I_SB(inode)) &&
7045c57132eSChao Yu 			F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize,
7055c57132eSChao Yu 								i_projid)) {
7065c57132eSChao Yu 			projid_t i_projid;
7075c57132eSChao Yu 
7085c57132eSChao Yu 			i_projid = from_kprojid(&init_user_ns,
7095c57132eSChao Yu 						F2FS_I(inode)->i_projid);
7105c57132eSChao Yu 			ri->i_projid = cpu_to_le32(i_projid);
7115c57132eSChao Yu 		}
7121c1d35dfSChao Yu 
7137beb01f7SChao Yu 		if (f2fs_sb_has_inode_crtime(F2FS_I_SB(inode)) &&
7141c1d35dfSChao Yu 			F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize,
7151c1d35dfSChao Yu 								i_crtime)) {
7161c1d35dfSChao Yu 			ri->i_crtime =
7171c1d35dfSChao Yu 				cpu_to_le64(F2FS_I(inode)->i_crtime.tv_sec);
7181c1d35dfSChao Yu 			ri->i_crtime_nsec =
7191c1d35dfSChao Yu 				cpu_to_le32(F2FS_I(inode)->i_crtime.tv_nsec);
7201c1d35dfSChao Yu 		}
7214c8ff709SChao Yu 
7224c8ff709SChao Yu 		if (f2fs_sb_has_compression(F2FS_I_SB(inode)) &&
7234c8ff709SChao Yu 			F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize,
72464ee9163SChao Yu 							i_compress_flag)) {
725b90e5086SChao Yu 			unsigned short compress_flag;
726b90e5086SChao Yu 
7274c8ff709SChao Yu 			ri->i_compr_blocks =
728c2759ebaSDaeho Jeong 				cpu_to_le64(atomic_read(
729c2759ebaSDaeho Jeong 					&F2FS_I(inode)->i_compr_blocks));
7304c8ff709SChao Yu 			ri->i_compress_algorithm =
7314c8ff709SChao Yu 				F2FS_I(inode)->i_compress_algorithm;
732b90e5086SChao Yu 			compress_flag = F2FS_I(inode)->i_compress_flag |
733b90e5086SChao Yu 				F2FS_I(inode)->i_compress_level <<
734b90e5086SChao Yu 						COMPRESS_LEVEL_OFFSET;
735b90e5086SChao Yu 			ri->i_compress_flag = cpu_to_le16(compress_flag);
7364c8ff709SChao Yu 			ri->i_log_cluster_size =
7374c8ff709SChao Yu 				F2FS_I(inode)->i_log_cluster_size;
7384c8ff709SChao Yu 		}
7395c57132eSChao Yu 	}
7405c57132eSChao Yu 
741dcd6b38bSChao Yu 	__set_inode_rdev(inode, node_page);
74212719ae1SJaegeuk Kim 
7432049d4fcSJaegeuk Kim 	/* deleted inode */
7442049d4fcSJaegeuk Kim 	if (inode->i_nlink == 0)
745b763f3beSChao Yu 		clear_page_private_inline(node_page);
7462049d4fcSJaegeuk Kim 
747049ea86cSZhang Qilong 	init_idisk_time(inode);
74854c55c4eSWeichao Guo #ifdef CONFIG_F2FS_CHECK_FS
74954c55c4eSWeichao Guo 	f2fs_inode_chksum_set(F2FS_I_SB(inode), node_page);
75054c55c4eSWeichao Guo #endif
75119f99ceeSJaegeuk Kim }
75219f99ceeSJaegeuk Kim 
f2fs_update_inode_page(struct inode * inode)7534d57b86dSChao Yu void f2fs_update_inode_page(struct inode *inode)
75419f99ceeSJaegeuk Kim {
7554081363fSJaegeuk Kim 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
75619f99ceeSJaegeuk Kim 	struct page *node_page;
7573aa51c61SJaegeuk Kim 	int count = 0;
758744602cfSJaegeuk Kim retry:
7594d57b86dSChao Yu 	node_page = f2fs_get_node_page(sbi, inode->i_ino);
760744602cfSJaegeuk Kim 	if (IS_ERR(node_page)) {
761744602cfSJaegeuk Kim 		int err = PTR_ERR(node_page);
7625f029c04SYi Zhuang 
7633aa51c61SJaegeuk Kim 		/* The node block was truncated. */
7643aa51c61SJaegeuk Kim 		if (err == -ENOENT)
7653aa51c61SJaegeuk Kim 			return;
7663aa51c61SJaegeuk Kim 
7673aa51c61SJaegeuk Kim 		if (err == -ENOMEM || ++count <= DEFAULT_RETRY_IO_COUNT)
768744602cfSJaegeuk Kim 			goto retry;
7693aa51c61SJaegeuk Kim 		f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_UPDATE_INODE);
770211a6fa0SYunlei He 		return;
771744602cfSJaegeuk Kim 	}
7724d57b86dSChao Yu 	f2fs_update_inode(inode, node_page);
77339936837SJaegeuk Kim 	f2fs_put_page(node_page, 1);
77439936837SJaegeuk Kim }
77539936837SJaegeuk Kim 
f2fs_write_inode(struct inode * inode,struct writeback_control * wbc)77639936837SJaegeuk Kim int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
77739936837SJaegeuk Kim {
7784081363fSJaegeuk Kim 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
77919f99ceeSJaegeuk Kim 
78019f99ceeSJaegeuk Kim 	if (inode->i_ino == F2FS_NODE_INO(sbi) ||
78119f99ceeSJaegeuk Kim 			inode->i_ino == F2FS_META_INO(sbi))
78219f99ceeSJaegeuk Kim 		return 0;
78319f99ceeSJaegeuk Kim 
784fe1897eaSChao Yu 	/*
785fe1897eaSChao Yu 	 * atime could be updated without dirtying f2fs inode in lazytime mode
786fe1897eaSChao Yu 	 */
787fe1897eaSChao Yu 	if (f2fs_is_time_consistent(inode) &&
788fe1897eaSChao Yu 		!is_inode_flag_set(inode, FI_DIRTY_INODE))
789b3783873SJaegeuk Kim 		return 0;
790b3783873SJaegeuk Kim 
791*9669b28fSQi Han 	if (!f2fs_is_checkpoint_ready(sbi)) {
792*9669b28fSQi Han 		f2fs_mark_inode_dirty_sync(inode, true);
7934354994fSDaniel Rosenberg 		return -ENOSPC;
794*9669b28fSQi Han 	}
7954354994fSDaniel Rosenberg 
79639936837SJaegeuk Kim 	/*
797c5cd29d2SJaegeuk Kim 	 * We need to balance fs here to prevent from producing dirty node pages
7982c718feeSRuiqi Gong 	 * during the urgent cleaning time when running out of free sections.
79939936837SJaegeuk Kim 	 */
8004d57b86dSChao Yu 	f2fs_update_inode_page(inode);
801a7881893SJaegeuk Kim 	if (wbc && wbc->nr_to_write)
8022c4db1a6SJaegeuk Kim 		f2fs_balance_fs(sbi, true);
803744602cfSJaegeuk Kim 	return 0;
80419f99ceeSJaegeuk Kim }
80519f99ceeSJaegeuk Kim 
8060a8165d7SJaegeuk Kim /*
80719f99ceeSJaegeuk Kim  * Called at the last iput() if i_nlink is zero
80819f99ceeSJaegeuk Kim  */
f2fs_evict_inode(struct inode * inode)80919f99ceeSJaegeuk Kim void f2fs_evict_inode(struct inode *inode)
81019f99ceeSJaegeuk Kim {
8114081363fSJaegeuk Kim 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
812a46bebd5SDaeho Jeong 	struct f2fs_inode_info *fi = F2FS_I(inode);
813a46bebd5SDaeho Jeong 	nid_t xnid = fi->i_xattr_nid;
81413ec7297SChao Yu 	int err = 0;
81519f99ceeSJaegeuk Kim 
8163db1de0eSDaeho Jeong 	f2fs_abort_atomic_write(inode, true);
81788b88a66SJaegeuk Kim 
818b82d4300SSunmin Jeong 	if (fi->cow_inode && f2fs_is_cow_file(fi->cow_inode)) {
819a46bebd5SDaeho Jeong 		clear_inode_flag(fi->cow_inode, FI_COW_FILE);
820b82d4300SSunmin Jeong 		F2FS_I(fi->cow_inode)->atomic_inode = NULL;
821a46bebd5SDaeho Jeong 		iput(fi->cow_inode);
822a46bebd5SDaeho Jeong 		fi->cow_inode = NULL;
823a46bebd5SDaeho Jeong 	}
824a46bebd5SDaeho Jeong 
825a2a4a7e4SNamjae Jeon 	trace_f2fs_evict_inode(inode);
82691b0abe3SJohannes Weiner 	truncate_inode_pages_final(&inode->i_data);
82719f99ceeSJaegeuk Kim 
8282b642898SFengnan Chang 	if ((inode->i_nlink || is_bad_inode(inode)) &&
8292b642898SFengnan Chang 		test_opt(sbi, COMPRESS_CACHE) && f2fs_compressed_file(inode))
8306ce19affSChao Yu 		f2fs_invalidate_compress_pages(sbi, inode->i_ino);
8316ce19affSChao Yu 
83219f99ceeSJaegeuk Kim 	if (inode->i_ino == F2FS_NODE_INO(sbi) ||
8336ce19affSChao Yu 			inode->i_ino == F2FS_META_INO(sbi) ||
8346ce19affSChao Yu 			inode->i_ino == F2FS_COMPRESS_INO(sbi))
835dbf20cb2SChao Yu 		goto out_clear;
83619f99ceeSJaegeuk Kim 
837a7ffdbe2SJaegeuk Kim 	f2fs_bug_on(sbi, get_dirty_pages(inode));
8384d57b86dSChao Yu 	f2fs_remove_dirty_inode(inode);
83919f99ceeSJaegeuk Kim 
8403e72f721SJaegeuk Kim 	f2fs_destroy_extent_tree(inode);
8413e72f721SJaegeuk Kim 
84219f99ceeSJaegeuk Kim 	if (inode->i_nlink || is_bad_inode(inode))
84319f99ceeSJaegeuk Kim 		goto no_delete;
84419f99ceeSJaegeuk Kim 
84510a26878SChao Yu 	err = f2fs_dquot_initialize(inode);
846af033b2aSChao Yu 	if (err) {
847af033b2aSChao Yu 		err = 0;
848af033b2aSChao Yu 		set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
849af033b2aSChao Yu 	}
8500abd675eSChao Yu 
8514d57b86dSChao Yu 	f2fs_remove_ino_entry(sbi, inode->i_ino, APPEND_INO);
8524d57b86dSChao Yu 	f2fs_remove_ino_entry(sbi, inode->i_ino, UPDATE_INO);
8534d57b86dSChao Yu 	f2fs_remove_ino_entry(sbi, inode->i_ino, FLUSH_INO);
85460dcedc9SChao Yu 
855ba900534SJaegeuk Kim 	if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING))
856d6212a5fSChangman Lee 		sb_start_intwrite(inode->i_sb);
85791942321SJaegeuk Kim 	set_inode_flag(inode, FI_NO_ALLOC);
85819f99ceeSJaegeuk Kim 	i_size_write(inode, 0);
8594c0c2949SJaegeuk Kim retry:
86019f99ceeSJaegeuk Kim 	if (F2FS_HAS_BLOCKS(inode))
8619a449e9cSJaegeuk Kim 		err = f2fs_truncate(inode);
86219f99ceeSJaegeuk Kim 
863c40e15a9SYangtao Li 	if (time_to_inject(sbi, FAULT_EVICT_INODE))
8648c1b3c0fSJaegeuk Kim 		err = -EIO;
8657fa750a1SArnd Bergmann 
86613ec7297SChao Yu 	if (!err) {
867e479556bSGu Zheng 		f2fs_lock_op(sbi);
8684d57b86dSChao Yu 		err = f2fs_remove_inode_page(inode);
869e479556bSGu Zheng 		f2fs_unlock_op(sbi);
870f2db7105SChao Yu 		if (err == -ENOENT) {
871a11b9f65SChao Yu 			err = 0;
872f2db7105SChao Yu 
873f2db7105SChao Yu 			/*
874f2db7105SChao Yu 			 * in fuzzed image, another node may has the same
875f2db7105SChao Yu 			 * block address as inode's, if it was truncated
876f2db7105SChao Yu 			 * previously, truncation of inode node will fail.
877f2db7105SChao Yu 			 */
878f2db7105SChao Yu 			if (is_inode_flag_set(inode, FI_DIRTY_INODE)) {
879f2db7105SChao Yu 				f2fs_warn(F2FS_I_SB(inode),
880f2db7105SChao Yu 					"f2fs_evict_inode: inconsistent node id, ino:%lu",
881f2db7105SChao Yu 					inode->i_ino);
882f2db7105SChao Yu 				f2fs_inode_synced(inode);
883f2db7105SChao Yu 				set_sbi_flag(sbi, SBI_NEED_FSCK);
884f2db7105SChao Yu 			}
885f2db7105SChao Yu 		}
88613ec7297SChao Yu 	}
88739936837SJaegeuk Kim 
8884c0c2949SJaegeuk Kim 	/* give more chances, if ENOMEM case */
8894c0c2949SJaegeuk Kim 	if (err == -ENOMEM) {
8904c0c2949SJaegeuk Kim 		err = 0;
8914c0c2949SJaegeuk Kim 		goto retry;
8924c0c2949SJaegeuk Kim 	}
8934c0c2949SJaegeuk Kim 
894af033b2aSChao Yu 	if (err) {
8954d57b86dSChao Yu 		f2fs_update_inode_page(inode);
8960f1898f9SChao Yu 		if (dquot_initialize_needed(inode))
897af033b2aSChao Yu 			set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
898af033b2aSChao Yu 	}
899ba900534SJaegeuk Kim 	if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING))
900d6212a5fSChangman Lee 		sb_end_intwrite(inode->i_sb);
90119f99ceeSJaegeuk Kim no_delete:
9020abd675eSChao Yu 	dquot_drop(inode);
9030abd675eSChao Yu 
904d5e8f6c9SChao Yu 	stat_dec_inline_xattr(inode);
9053289c061SJaegeuk Kim 	stat_dec_inline_dir(inode);
906e7a2bf22SJaegeuk Kim 	stat_dec_inline_inode(inode);
9074c8ff709SChao Yu 	stat_dec_compr_inode(inode);
908c2759ebaSDaeho Jeong 	stat_sub_compr_blocks(inode,
909a46bebd5SDaeho Jeong 			atomic_read(&fi->i_compr_blocks));
9100bdee482SChao Yu 
91133ac18a1SChao Yu 	if (likely(!f2fs_cp_error(sbi) &&
9124354994fSDaniel Rosenberg 				!is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
913ca7d802aSChao Yu 		f2fs_bug_on(sbi, is_inode_flag_set(inode, FI_DIRTY_INODE));
914943973cdSJaegeuk Kim 	else
915943973cdSJaegeuk Kim 		f2fs_inode_synced(inode);
916ca7d802aSChao Yu 
9177a88ddb5SChao Yu 	/* for the case f2fs_new_inode() was failed, .i_ino is zero, skip it */
9184f295443SJaegeuk Kim 	if (inode->i_ino)
9194f295443SJaegeuk Kim 		invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino,
9204f295443SJaegeuk Kim 							inode->i_ino);
921002a41caSChao Yu 	if (xnid)
922002a41caSChao Yu 		invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid);
92360dcedc9SChao Yu 	if (inode->i_nlink) {
92491942321SJaegeuk Kim 		if (is_inode_flag_set(inode, FI_APPEND_WRITE))
9254d57b86dSChao Yu 			f2fs_add_ino_entry(sbi, inode->i_ino, APPEND_INO);
92691942321SJaegeuk Kim 		if (is_inode_flag_set(inode, FI_UPDATE_WRITE))
9274d57b86dSChao Yu 			f2fs_add_ino_entry(sbi, inode->i_ino, UPDATE_INO);
92860dcedc9SChao Yu 	}
92991942321SJaegeuk Kim 	if (is_inode_flag_set(inode, FI_FREE_NID)) {
9304d57b86dSChao Yu 		f2fs_alloc_nid_failed(sbi, inode->i_ino);
93191942321SJaegeuk Kim 		clear_inode_flag(inode, FI_FREE_NID);
932d8c4256cSJaegeuk Kim 	} else {
933a4f843bdSJaegeuk Kim 		/*
934a4f843bdSJaegeuk Kim 		 * If xattr nid is corrupted, we can reach out error condition,
9354d57b86dSChao Yu 		 * err & !f2fs_exist_written_data(sbi, inode->i_ino, ORPHAN_INO)).
9364d57b86dSChao Yu 		 * In that case, f2fs_check_nid_range() is enough to give a clue.
937a4f843bdSJaegeuk Kim 		 */
938d8c4256cSJaegeuk Kim 	}
939dbf20cb2SChao Yu out_clear:
9403d204e24SEric Biggers 	fscrypt_put_encryption_info(inode);
94195ae251fSEric Biggers 	fsverity_cleanup_inode(inode);
942dbf20cb2SChao Yu 	clear_inode(inode);
94319f99ceeSJaegeuk Kim }
94444c16156SJaegeuk Kim 
94544c16156SJaegeuk Kim /* caller should call f2fs_lock_op() */
f2fs_handle_failed_inode(struct inode * inode)9464d57b86dSChao Yu void f2fs_handle_failed_inode(struct inode *inode)
94744c16156SJaegeuk Kim {
94844c16156SJaegeuk Kim 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
949221149c0SJaegeuk Kim 	struct node_info ni;
9507735730dSChao Yu 	int err;
95144c16156SJaegeuk Kim 
952a11b9f65SChao Yu 	/*
953a11b9f65SChao Yu 	 * clear nlink of inode in order to release resource of inode
954a11b9f65SChao Yu 	 * immediately.
955a11b9f65SChao Yu 	 */
956a11b9f65SChao Yu 	clear_nlink(inode);
957a11b9f65SChao Yu 
958a11b9f65SChao Yu 	/*
959a11b9f65SChao Yu 	 * we must call this to avoid inode being remained as dirty, resulting
960a11b9f65SChao Yu 	 * in a panic when flushing dirty inodes in gdirty_list.
961a11b9f65SChao Yu 	 */
9624d57b86dSChao Yu 	f2fs_update_inode_page(inode);
9639bb02c36SJaegeuk Kim 	f2fs_inode_synced(inode);
964a11b9f65SChao Yu 
965221149c0SJaegeuk Kim 	/* don't make bad inode, since it becomes a regular file. */
96644c16156SJaegeuk Kim 	unlock_new_inode(inode);
96744c16156SJaegeuk Kim 
96813ec7297SChao Yu 	/*
96913ec7297SChao Yu 	 * Note: we should add inode to orphan list before f2fs_unlock_op()
97013ec7297SChao Yu 	 * so we can prevent losing this orphan when encoutering checkpoint
97113ec7297SChao Yu 	 * and following suddenly power-off.
97213ec7297SChao Yu 	 */
973a9419b63SJaegeuk Kim 	err = f2fs_get_node_info(sbi, inode->i_ino, &ni, false);
9747735730dSChao Yu 	if (err) {
9757735730dSChao Yu 		set_sbi_flag(sbi, SBI_NEED_FSCK);
9762fef99b8SJaegeuk Kim 		set_inode_flag(inode, FI_FREE_NID);
977dcbb4c10SJoe Perches 		f2fs_warn(sbi, "May loss orphan inode, run fsck to fix.");
9787735730dSChao Yu 		goto out;
9797735730dSChao Yu 	}
980221149c0SJaegeuk Kim 
981221149c0SJaegeuk Kim 	if (ni.blk_addr != NULL_ADDR) {
9827735730dSChao Yu 		err = f2fs_acquire_orphan_inode(sbi);
983221149c0SJaegeuk Kim 		if (err) {
984221149c0SJaegeuk Kim 			set_sbi_flag(sbi, SBI_NEED_FSCK);
985dcbb4c10SJoe Perches 			f2fs_warn(sbi, "Too many orphan inodes, run fsck to fix.");
986221149c0SJaegeuk Kim 		} else {
9874d57b86dSChao Yu 			f2fs_add_orphan_inode(inode);
98813ec7297SChao Yu 		}
9894d57b86dSChao Yu 		f2fs_alloc_nid_done(sbi, inode->i_ino);
990221149c0SJaegeuk Kim 	} else {
99191942321SJaegeuk Kim 		set_inode_flag(inode, FI_FREE_NID);
992221149c0SJaegeuk Kim 	}
993221149c0SJaegeuk Kim 
9947735730dSChao Yu out:
99544c16156SJaegeuk Kim 	f2fs_unlock_op(sbi);
99644c16156SJaegeuk Kim 
99744c16156SJaegeuk Kim 	/* iput will drop the inode object */
99844c16156SJaegeuk Kim 	iput(inode);
99944c16156SJaegeuk Kim }
1000