xref: /OK3568_Linux_fs/kernel/fs/f2fs/recovery.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * fs/f2fs/recovery.c
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
6*4882a593Smuzhiyun  *             http://www.samsung.com/
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun #include <asm/unaligned.h>
9*4882a593Smuzhiyun #include <linux/fs.h>
10*4882a593Smuzhiyun #include <linux/f2fs_fs.h>
11*4882a593Smuzhiyun #include "f2fs.h"
12*4882a593Smuzhiyun #include "node.h"
13*4882a593Smuzhiyun #include "segment.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun /*
16*4882a593Smuzhiyun  * Roll forward recovery scenarios.
17*4882a593Smuzhiyun  *
18*4882a593Smuzhiyun  * [Term] F: fsync_mark, D: dentry_mark
19*4882a593Smuzhiyun  *
20*4882a593Smuzhiyun  * 1. inode(x) | CP | inode(x) | dnode(F)
21*4882a593Smuzhiyun  * -> Update the latest inode(x).
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * 2. inode(x) | CP | inode(F) | dnode(F)
24*4882a593Smuzhiyun  * -> No problem.
25*4882a593Smuzhiyun  *
26*4882a593Smuzhiyun  * 3. inode(x) | CP | dnode(F) | inode(x)
27*4882a593Smuzhiyun  * -> Recover to the latest dnode(F), and drop the last inode(x)
28*4882a593Smuzhiyun  *
29*4882a593Smuzhiyun  * 4. inode(x) | CP | dnode(F) | inode(F)
30*4882a593Smuzhiyun  * -> No problem.
31*4882a593Smuzhiyun  *
32*4882a593Smuzhiyun  * 5. CP | inode(x) | dnode(F)
33*4882a593Smuzhiyun  * -> The inode(DF) was missing. Should drop this dnode(F).
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  * 6. CP | inode(DF) | dnode(F)
36*4882a593Smuzhiyun  * -> No problem.
37*4882a593Smuzhiyun  *
38*4882a593Smuzhiyun  * 7. CP | dnode(F) | inode(DF)
39*4882a593Smuzhiyun  * -> If f2fs_iget fails, then goto next to find inode(DF).
40*4882a593Smuzhiyun  *
41*4882a593Smuzhiyun  * 8. CP | dnode(F) | inode(x)
42*4882a593Smuzhiyun  * -> If f2fs_iget fails, then goto next to find inode(DF).
43*4882a593Smuzhiyun  *    But it will fail due to no inode(DF).
44*4882a593Smuzhiyun  */
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun static struct kmem_cache *fsync_entry_slab;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #ifdef CONFIG_UNICODE
49*4882a593Smuzhiyun extern struct kmem_cache *f2fs_cf_name_slab;
50*4882a593Smuzhiyun #endif
51*4882a593Smuzhiyun 
f2fs_space_for_roll_forward(struct f2fs_sb_info * sbi)52*4882a593Smuzhiyun bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun 	s64 nalloc = percpu_counter_sum_positive(&sbi->alloc_valid_block_count);
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	if (sbi->last_valid_block_count + nalloc > sbi->user_block_count)
57*4882a593Smuzhiyun 		return false;
58*4882a593Smuzhiyun 	return true;
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun 
get_fsync_inode(struct list_head * head,nid_t ino)61*4882a593Smuzhiyun static struct fsync_inode_entry *get_fsync_inode(struct list_head *head,
62*4882a593Smuzhiyun 								nid_t ino)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun 	struct fsync_inode_entry *entry;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	list_for_each_entry(entry, head, list)
67*4882a593Smuzhiyun 		if (entry->inode->i_ino == ino)
68*4882a593Smuzhiyun 			return entry;
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 	return NULL;
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun 
add_fsync_inode(struct f2fs_sb_info * sbi,struct list_head * head,nid_t ino,bool quota_inode)73*4882a593Smuzhiyun static struct fsync_inode_entry *add_fsync_inode(struct f2fs_sb_info *sbi,
74*4882a593Smuzhiyun 			struct list_head *head, nid_t ino, bool quota_inode)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun 	struct inode *inode;
77*4882a593Smuzhiyun 	struct fsync_inode_entry *entry;
78*4882a593Smuzhiyun 	int err;
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 	inode = f2fs_iget_retry(sbi->sb, ino);
81*4882a593Smuzhiyun 	if (IS_ERR(inode))
82*4882a593Smuzhiyun 		return ERR_CAST(inode);
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	err = dquot_initialize(inode);
85*4882a593Smuzhiyun 	if (err)
86*4882a593Smuzhiyun 		goto err_out;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	if (quota_inode) {
89*4882a593Smuzhiyun 		err = dquot_alloc_inode(inode);
90*4882a593Smuzhiyun 		if (err)
91*4882a593Smuzhiyun 			goto err_out;
92*4882a593Smuzhiyun 	}
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	entry = f2fs_kmem_cache_alloc(fsync_entry_slab, GFP_F2FS_ZERO);
95*4882a593Smuzhiyun 	entry->inode = inode;
96*4882a593Smuzhiyun 	list_add_tail(&entry->list, head);
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	return entry;
99*4882a593Smuzhiyun err_out:
100*4882a593Smuzhiyun 	iput(inode);
101*4882a593Smuzhiyun 	return ERR_PTR(err);
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun 
del_fsync_inode(struct fsync_inode_entry * entry,int drop)104*4882a593Smuzhiyun static void del_fsync_inode(struct fsync_inode_entry *entry, int drop)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun 	if (drop) {
107*4882a593Smuzhiyun 		/* inode should not be recovered, drop it */
108*4882a593Smuzhiyun 		f2fs_inode_synced(entry->inode);
109*4882a593Smuzhiyun 	}
110*4882a593Smuzhiyun 	iput(entry->inode);
111*4882a593Smuzhiyun 	list_del(&entry->list);
112*4882a593Smuzhiyun 	kmem_cache_free(fsync_entry_slab, entry);
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun 
init_recovered_filename(const struct inode * dir,struct f2fs_inode * raw_inode,struct f2fs_filename * fname,struct qstr * usr_fname)115*4882a593Smuzhiyun static int init_recovered_filename(const struct inode *dir,
116*4882a593Smuzhiyun 				   struct f2fs_inode *raw_inode,
117*4882a593Smuzhiyun 				   struct f2fs_filename *fname,
118*4882a593Smuzhiyun 				   struct qstr *usr_fname)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	int err;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	memset(fname, 0, sizeof(*fname));
123*4882a593Smuzhiyun 	fname->disk_name.len = le32_to_cpu(raw_inode->i_namelen);
124*4882a593Smuzhiyun 	fname->disk_name.name = raw_inode->i_name;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	if (WARN_ON(fname->disk_name.len > F2FS_NAME_LEN))
127*4882a593Smuzhiyun 		return -ENAMETOOLONG;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	if (!IS_ENCRYPTED(dir)) {
130*4882a593Smuzhiyun 		usr_fname->name = fname->disk_name.name;
131*4882a593Smuzhiyun 		usr_fname->len = fname->disk_name.len;
132*4882a593Smuzhiyun 		fname->usr_fname = usr_fname;
133*4882a593Smuzhiyun 	}
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	/* Compute the hash of the filename */
136*4882a593Smuzhiyun 	if (IS_ENCRYPTED(dir) && IS_CASEFOLDED(dir)) {
137*4882a593Smuzhiyun 		/*
138*4882a593Smuzhiyun 		 * In this case the hash isn't computable without the key, so it
139*4882a593Smuzhiyun 		 * was saved on-disk.
140*4882a593Smuzhiyun 		 */
141*4882a593Smuzhiyun 		if (fname->disk_name.len + sizeof(f2fs_hash_t) > F2FS_NAME_LEN)
142*4882a593Smuzhiyun 			return -EINVAL;
143*4882a593Smuzhiyun 		fname->hash = get_unaligned((f2fs_hash_t *)
144*4882a593Smuzhiyun 				&raw_inode->i_name[fname->disk_name.len]);
145*4882a593Smuzhiyun 	} else if (IS_CASEFOLDED(dir)) {
146*4882a593Smuzhiyun 		err = f2fs_init_casefolded_name(dir, fname);
147*4882a593Smuzhiyun 		if (err)
148*4882a593Smuzhiyun 			return err;
149*4882a593Smuzhiyun 		f2fs_hash_filename(dir, fname);
150*4882a593Smuzhiyun #ifdef CONFIG_UNICODE
151*4882a593Smuzhiyun 		/* Case-sensitive match is fine for recovery */
152*4882a593Smuzhiyun 		kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name);
153*4882a593Smuzhiyun 		fname->cf_name.name = NULL;
154*4882a593Smuzhiyun #endif
155*4882a593Smuzhiyun 	} else {
156*4882a593Smuzhiyun 		f2fs_hash_filename(dir, fname);
157*4882a593Smuzhiyun 	}
158*4882a593Smuzhiyun 	return 0;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun 
recover_dentry(struct inode * inode,struct page * ipage,struct list_head * dir_list)161*4882a593Smuzhiyun static int recover_dentry(struct inode *inode, struct page *ipage,
162*4882a593Smuzhiyun 						struct list_head *dir_list)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun 	struct f2fs_inode *raw_inode = F2FS_INODE(ipage);
165*4882a593Smuzhiyun 	nid_t pino = le32_to_cpu(raw_inode->i_pino);
166*4882a593Smuzhiyun 	struct f2fs_dir_entry *de;
167*4882a593Smuzhiyun 	struct f2fs_filename fname;
168*4882a593Smuzhiyun 	struct qstr usr_fname;
169*4882a593Smuzhiyun 	struct page *page;
170*4882a593Smuzhiyun 	struct inode *dir, *einode;
171*4882a593Smuzhiyun 	struct fsync_inode_entry *entry;
172*4882a593Smuzhiyun 	int err = 0;
173*4882a593Smuzhiyun 	char *name;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	entry = get_fsync_inode(dir_list, pino);
176*4882a593Smuzhiyun 	if (!entry) {
177*4882a593Smuzhiyun 		entry = add_fsync_inode(F2FS_I_SB(inode), dir_list,
178*4882a593Smuzhiyun 							pino, false);
179*4882a593Smuzhiyun 		if (IS_ERR(entry)) {
180*4882a593Smuzhiyun 			dir = ERR_CAST(entry);
181*4882a593Smuzhiyun 			err = PTR_ERR(entry);
182*4882a593Smuzhiyun 			goto out;
183*4882a593Smuzhiyun 		}
184*4882a593Smuzhiyun 	}
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	dir = entry->inode;
187*4882a593Smuzhiyun 	err = init_recovered_filename(dir, raw_inode, &fname, &usr_fname);
188*4882a593Smuzhiyun 	if (err)
189*4882a593Smuzhiyun 		goto out;
190*4882a593Smuzhiyun retry:
191*4882a593Smuzhiyun 	de = __f2fs_find_entry(dir, &fname, &page);
192*4882a593Smuzhiyun 	if (de && inode->i_ino == le32_to_cpu(de->ino))
193*4882a593Smuzhiyun 		goto out_put;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	if (de) {
196*4882a593Smuzhiyun 		einode = f2fs_iget_retry(inode->i_sb, le32_to_cpu(de->ino));
197*4882a593Smuzhiyun 		if (IS_ERR(einode)) {
198*4882a593Smuzhiyun 			WARN_ON(1);
199*4882a593Smuzhiyun 			err = PTR_ERR(einode);
200*4882a593Smuzhiyun 			if (err == -ENOENT)
201*4882a593Smuzhiyun 				err = -EEXIST;
202*4882a593Smuzhiyun 			goto out_put;
203*4882a593Smuzhiyun 		}
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 		err = dquot_initialize(einode);
206*4882a593Smuzhiyun 		if (err) {
207*4882a593Smuzhiyun 			iput(einode);
208*4882a593Smuzhiyun 			goto out_put;
209*4882a593Smuzhiyun 		}
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 		err = f2fs_acquire_orphan_inode(F2FS_I_SB(inode));
212*4882a593Smuzhiyun 		if (err) {
213*4882a593Smuzhiyun 			iput(einode);
214*4882a593Smuzhiyun 			goto out_put;
215*4882a593Smuzhiyun 		}
216*4882a593Smuzhiyun 		f2fs_delete_entry(de, page, dir, einode);
217*4882a593Smuzhiyun 		iput(einode);
218*4882a593Smuzhiyun 		goto retry;
219*4882a593Smuzhiyun 	} else if (IS_ERR(page)) {
220*4882a593Smuzhiyun 		err = PTR_ERR(page);
221*4882a593Smuzhiyun 	} else {
222*4882a593Smuzhiyun 		err = f2fs_add_dentry(dir, &fname, inode,
223*4882a593Smuzhiyun 					inode->i_ino, inode->i_mode);
224*4882a593Smuzhiyun 	}
225*4882a593Smuzhiyun 	if (err == -ENOMEM)
226*4882a593Smuzhiyun 		goto retry;
227*4882a593Smuzhiyun 	goto out;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun out_put:
230*4882a593Smuzhiyun 	f2fs_put_page(page, 0);
231*4882a593Smuzhiyun out:
232*4882a593Smuzhiyun 	if (file_enc_name(inode))
233*4882a593Smuzhiyun 		name = "<encrypted>";
234*4882a593Smuzhiyun 	else
235*4882a593Smuzhiyun 		name = raw_inode->i_name;
236*4882a593Smuzhiyun 	f2fs_notice(F2FS_I_SB(inode), "%s: ino = %x, name = %s, dir = %lx, err = %d",
237*4882a593Smuzhiyun 		    __func__, ino_of_node(ipage), name,
238*4882a593Smuzhiyun 		    IS_ERR(dir) ? 0 : dir->i_ino, err);
239*4882a593Smuzhiyun 	return err;
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun 
recover_quota_data(struct inode * inode,struct page * page)242*4882a593Smuzhiyun static int recover_quota_data(struct inode *inode, struct page *page)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun 	struct f2fs_inode *raw = F2FS_INODE(page);
245*4882a593Smuzhiyun 	struct iattr attr;
246*4882a593Smuzhiyun 	uid_t i_uid = le32_to_cpu(raw->i_uid);
247*4882a593Smuzhiyun 	gid_t i_gid = le32_to_cpu(raw->i_gid);
248*4882a593Smuzhiyun 	int err;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	memset(&attr, 0, sizeof(attr));
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	attr.ia_uid = make_kuid(inode->i_sb->s_user_ns, i_uid);
253*4882a593Smuzhiyun 	attr.ia_gid = make_kgid(inode->i_sb->s_user_ns, i_gid);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	if (!uid_eq(attr.ia_uid, inode->i_uid))
256*4882a593Smuzhiyun 		attr.ia_valid |= ATTR_UID;
257*4882a593Smuzhiyun 	if (!gid_eq(attr.ia_gid, inode->i_gid))
258*4882a593Smuzhiyun 		attr.ia_valid |= ATTR_GID;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	if (!attr.ia_valid)
261*4882a593Smuzhiyun 		return 0;
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	err = dquot_transfer(inode, &attr);
264*4882a593Smuzhiyun 	if (err)
265*4882a593Smuzhiyun 		set_sbi_flag(F2FS_I_SB(inode), SBI_QUOTA_NEED_REPAIR);
266*4882a593Smuzhiyun 	return err;
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun 
recover_inline_flags(struct inode * inode,struct f2fs_inode * ri)269*4882a593Smuzhiyun static void recover_inline_flags(struct inode *inode, struct f2fs_inode *ri)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun 	if (ri->i_inline & F2FS_PIN_FILE)
272*4882a593Smuzhiyun 		set_inode_flag(inode, FI_PIN_FILE);
273*4882a593Smuzhiyun 	else
274*4882a593Smuzhiyun 		clear_inode_flag(inode, FI_PIN_FILE);
275*4882a593Smuzhiyun 	if (ri->i_inline & F2FS_DATA_EXIST)
276*4882a593Smuzhiyun 		set_inode_flag(inode, FI_DATA_EXIST);
277*4882a593Smuzhiyun 	else
278*4882a593Smuzhiyun 		clear_inode_flag(inode, FI_DATA_EXIST);
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun 
recover_inode(struct inode * inode,struct page * page)281*4882a593Smuzhiyun static int recover_inode(struct inode *inode, struct page *page)
282*4882a593Smuzhiyun {
283*4882a593Smuzhiyun 	struct f2fs_inode *raw = F2FS_INODE(page);
284*4882a593Smuzhiyun 	char *name;
285*4882a593Smuzhiyun 	int err;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 	inode->i_mode = le16_to_cpu(raw->i_mode);
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	err = recover_quota_data(inode, page);
290*4882a593Smuzhiyun 	if (err)
291*4882a593Smuzhiyun 		return err;
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	i_uid_write(inode, le32_to_cpu(raw->i_uid));
294*4882a593Smuzhiyun 	i_gid_write(inode, le32_to_cpu(raw->i_gid));
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	if (raw->i_inline & F2FS_EXTRA_ATTR) {
297*4882a593Smuzhiyun 		if (f2fs_sb_has_project_quota(F2FS_I_SB(inode)) &&
298*4882a593Smuzhiyun 			F2FS_FITS_IN_INODE(raw, le16_to_cpu(raw->i_extra_isize),
299*4882a593Smuzhiyun 								i_projid)) {
300*4882a593Smuzhiyun 			projid_t i_projid;
301*4882a593Smuzhiyun 			kprojid_t kprojid;
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 			i_projid = (projid_t)le32_to_cpu(raw->i_projid);
304*4882a593Smuzhiyun 			kprojid = make_kprojid(&init_user_ns, i_projid);
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 			if (!projid_eq(kprojid, F2FS_I(inode)->i_projid)) {
307*4882a593Smuzhiyun 				err = f2fs_transfer_project_quota(inode,
308*4882a593Smuzhiyun 								kprojid);
309*4882a593Smuzhiyun 				if (err)
310*4882a593Smuzhiyun 					return err;
311*4882a593Smuzhiyun 				F2FS_I(inode)->i_projid = kprojid;
312*4882a593Smuzhiyun 			}
313*4882a593Smuzhiyun 		}
314*4882a593Smuzhiyun 	}
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	f2fs_i_size_write(inode, le64_to_cpu(raw->i_size));
317*4882a593Smuzhiyun 	inode->i_atime.tv_sec = le64_to_cpu(raw->i_atime);
318*4882a593Smuzhiyun 	inode->i_ctime.tv_sec = le64_to_cpu(raw->i_ctime);
319*4882a593Smuzhiyun 	inode->i_mtime.tv_sec = le64_to_cpu(raw->i_mtime);
320*4882a593Smuzhiyun 	inode->i_atime.tv_nsec = le32_to_cpu(raw->i_atime_nsec);
321*4882a593Smuzhiyun 	inode->i_ctime.tv_nsec = le32_to_cpu(raw->i_ctime_nsec);
322*4882a593Smuzhiyun 	inode->i_mtime.tv_nsec = le32_to_cpu(raw->i_mtime_nsec);
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	F2FS_I(inode)->i_advise = raw->i_advise;
325*4882a593Smuzhiyun 	F2FS_I(inode)->i_flags = le32_to_cpu(raw->i_flags);
326*4882a593Smuzhiyun 	f2fs_set_inode_flags(inode);
327*4882a593Smuzhiyun 	F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN] =
328*4882a593Smuzhiyun 				le16_to_cpu(raw->i_gc_failures);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	recover_inline_flags(inode, raw);
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	f2fs_mark_inode_dirty_sync(inode, true);
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	if (file_enc_name(inode))
335*4882a593Smuzhiyun 		name = "<encrypted>";
336*4882a593Smuzhiyun 	else
337*4882a593Smuzhiyun 		name = F2FS_INODE(page)->i_name;
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	f2fs_notice(F2FS_I_SB(inode), "recover_inode: ino = %x, name = %s, inline = %x",
340*4882a593Smuzhiyun 		    ino_of_node(page), name, raw->i_inline);
341*4882a593Smuzhiyun 	return 0;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun 
find_fsync_dnodes(struct f2fs_sb_info * sbi,struct list_head * head,bool check_only)344*4882a593Smuzhiyun static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
345*4882a593Smuzhiyun 				bool check_only)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun 	struct curseg_info *curseg;
348*4882a593Smuzhiyun 	struct page *page = NULL;
349*4882a593Smuzhiyun 	block_t blkaddr;
350*4882a593Smuzhiyun 	unsigned int loop_cnt = 0;
351*4882a593Smuzhiyun 	unsigned int free_blocks = MAIN_SEGS(sbi) * sbi->blocks_per_seg -
352*4882a593Smuzhiyun 						valid_user_blocks(sbi);
353*4882a593Smuzhiyun 	int err = 0;
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	/* get node pages in the current segment */
356*4882a593Smuzhiyun 	curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
357*4882a593Smuzhiyun 	blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	while (1) {
360*4882a593Smuzhiyun 		struct fsync_inode_entry *entry;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 		if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR))
363*4882a593Smuzhiyun 			return 0;
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 		page = f2fs_get_tmp_page(sbi, blkaddr);
366*4882a593Smuzhiyun 		if (IS_ERR(page)) {
367*4882a593Smuzhiyun 			err = PTR_ERR(page);
368*4882a593Smuzhiyun 			break;
369*4882a593Smuzhiyun 		}
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 		if (!is_recoverable_dnode(page)) {
372*4882a593Smuzhiyun 			f2fs_put_page(page, 1);
373*4882a593Smuzhiyun 			break;
374*4882a593Smuzhiyun 		}
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 		if (!is_fsync_dnode(page))
377*4882a593Smuzhiyun 			goto next;
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 		entry = get_fsync_inode(head, ino_of_node(page));
380*4882a593Smuzhiyun 		if (!entry) {
381*4882a593Smuzhiyun 			bool quota_inode = false;
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 			if (!check_only &&
384*4882a593Smuzhiyun 					IS_INODE(page) && is_dent_dnode(page)) {
385*4882a593Smuzhiyun 				err = f2fs_recover_inode_page(sbi, page);
386*4882a593Smuzhiyun 				if (err) {
387*4882a593Smuzhiyun 					f2fs_put_page(page, 1);
388*4882a593Smuzhiyun 					break;
389*4882a593Smuzhiyun 				}
390*4882a593Smuzhiyun 				quota_inode = true;
391*4882a593Smuzhiyun 			}
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 			/*
394*4882a593Smuzhiyun 			 * CP | dnode(F) | inode(DF)
395*4882a593Smuzhiyun 			 * For this case, we should not give up now.
396*4882a593Smuzhiyun 			 */
397*4882a593Smuzhiyun 			entry = add_fsync_inode(sbi, head, ino_of_node(page),
398*4882a593Smuzhiyun 								quota_inode);
399*4882a593Smuzhiyun 			if (IS_ERR(entry)) {
400*4882a593Smuzhiyun 				err = PTR_ERR(entry);
401*4882a593Smuzhiyun 				if (err == -ENOENT) {
402*4882a593Smuzhiyun 					err = 0;
403*4882a593Smuzhiyun 					goto next;
404*4882a593Smuzhiyun 				}
405*4882a593Smuzhiyun 				f2fs_put_page(page, 1);
406*4882a593Smuzhiyun 				break;
407*4882a593Smuzhiyun 			}
408*4882a593Smuzhiyun 		}
409*4882a593Smuzhiyun 		entry->blkaddr = blkaddr;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 		if (IS_INODE(page) && is_dent_dnode(page))
412*4882a593Smuzhiyun 			entry->last_dentry = blkaddr;
413*4882a593Smuzhiyun next:
414*4882a593Smuzhiyun 		/* sanity check in order to detect looped node chain */
415*4882a593Smuzhiyun 		if (++loop_cnt >= free_blocks ||
416*4882a593Smuzhiyun 			blkaddr == next_blkaddr_of_node(page)) {
417*4882a593Smuzhiyun 			f2fs_notice(sbi, "%s: detect looped node chain, blkaddr:%u, next:%u",
418*4882a593Smuzhiyun 				    __func__, blkaddr,
419*4882a593Smuzhiyun 				    next_blkaddr_of_node(page));
420*4882a593Smuzhiyun 			f2fs_put_page(page, 1);
421*4882a593Smuzhiyun 			err = -EINVAL;
422*4882a593Smuzhiyun 			break;
423*4882a593Smuzhiyun 		}
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 		/* check next segment */
426*4882a593Smuzhiyun 		blkaddr = next_blkaddr_of_node(page);
427*4882a593Smuzhiyun 		f2fs_put_page(page, 1);
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 		f2fs_ra_meta_pages_cond(sbi, blkaddr);
430*4882a593Smuzhiyun 	}
431*4882a593Smuzhiyun 	return err;
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun 
destroy_fsync_dnodes(struct list_head * head,int drop)434*4882a593Smuzhiyun static void destroy_fsync_dnodes(struct list_head *head, int drop)
435*4882a593Smuzhiyun {
436*4882a593Smuzhiyun 	struct fsync_inode_entry *entry, *tmp;
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	list_for_each_entry_safe(entry, tmp, head, list)
439*4882a593Smuzhiyun 		del_fsync_inode(entry, drop);
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun 
check_index_in_prev_nodes(struct f2fs_sb_info * sbi,block_t blkaddr,struct dnode_of_data * dn)442*4882a593Smuzhiyun static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
443*4882a593Smuzhiyun 			block_t blkaddr, struct dnode_of_data *dn)
444*4882a593Smuzhiyun {
445*4882a593Smuzhiyun 	struct seg_entry *sentry;
446*4882a593Smuzhiyun 	unsigned int segno = GET_SEGNO(sbi, blkaddr);
447*4882a593Smuzhiyun 	unsigned short blkoff = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
448*4882a593Smuzhiyun 	struct f2fs_summary_block *sum_node;
449*4882a593Smuzhiyun 	struct f2fs_summary sum;
450*4882a593Smuzhiyun 	struct page *sum_page, *node_page;
451*4882a593Smuzhiyun 	struct dnode_of_data tdn = *dn;
452*4882a593Smuzhiyun 	nid_t ino, nid;
453*4882a593Smuzhiyun 	struct inode *inode;
454*4882a593Smuzhiyun 	unsigned int offset, ofs_in_node, max_addrs;
455*4882a593Smuzhiyun 	block_t bidx;
456*4882a593Smuzhiyun 	int i;
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 	sentry = get_seg_entry(sbi, segno);
459*4882a593Smuzhiyun 	if (!f2fs_test_bit(blkoff, sentry->cur_valid_map))
460*4882a593Smuzhiyun 		return 0;
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	/* Get the previous summary */
463*4882a593Smuzhiyun 	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
464*4882a593Smuzhiyun 		struct curseg_info *curseg = CURSEG_I(sbi, i);
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 		if (curseg->segno == segno) {
467*4882a593Smuzhiyun 			sum = curseg->sum_blk->entries[blkoff];
468*4882a593Smuzhiyun 			goto got_it;
469*4882a593Smuzhiyun 		}
470*4882a593Smuzhiyun 	}
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	sum_page = f2fs_get_sum_page(sbi, segno);
473*4882a593Smuzhiyun 	if (IS_ERR(sum_page))
474*4882a593Smuzhiyun 		return PTR_ERR(sum_page);
475*4882a593Smuzhiyun 	sum_node = (struct f2fs_summary_block *)page_address(sum_page);
476*4882a593Smuzhiyun 	sum = sum_node->entries[blkoff];
477*4882a593Smuzhiyun 	f2fs_put_page(sum_page, 1);
478*4882a593Smuzhiyun got_it:
479*4882a593Smuzhiyun 	/* Use the locked dnode page and inode */
480*4882a593Smuzhiyun 	nid = le32_to_cpu(sum.nid);
481*4882a593Smuzhiyun 	ofs_in_node = le16_to_cpu(sum.ofs_in_node);
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	max_addrs = ADDRS_PER_PAGE(dn->node_page, dn->inode);
484*4882a593Smuzhiyun 	if (ofs_in_node >= max_addrs) {
485*4882a593Smuzhiyun 		f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%lu, nid:%u, max:%u",
486*4882a593Smuzhiyun 			ofs_in_node, dn->inode->i_ino, nid, max_addrs);
487*4882a593Smuzhiyun 		return -EFSCORRUPTED;
488*4882a593Smuzhiyun 	}
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun 	if (dn->inode->i_ino == nid) {
491*4882a593Smuzhiyun 		tdn.nid = nid;
492*4882a593Smuzhiyun 		if (!dn->inode_page_locked)
493*4882a593Smuzhiyun 			lock_page(dn->inode_page);
494*4882a593Smuzhiyun 		tdn.node_page = dn->inode_page;
495*4882a593Smuzhiyun 		tdn.ofs_in_node = ofs_in_node;
496*4882a593Smuzhiyun 		goto truncate_out;
497*4882a593Smuzhiyun 	} else if (dn->nid == nid) {
498*4882a593Smuzhiyun 		tdn.ofs_in_node = ofs_in_node;
499*4882a593Smuzhiyun 		goto truncate_out;
500*4882a593Smuzhiyun 	}
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	/* Get the node page */
503*4882a593Smuzhiyun 	node_page = f2fs_get_node_page(sbi, nid);
504*4882a593Smuzhiyun 	if (IS_ERR(node_page))
505*4882a593Smuzhiyun 		return PTR_ERR(node_page);
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 	offset = ofs_of_node(node_page);
508*4882a593Smuzhiyun 	ino = ino_of_node(node_page);
509*4882a593Smuzhiyun 	f2fs_put_page(node_page, 1);
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 	if (ino != dn->inode->i_ino) {
512*4882a593Smuzhiyun 		int ret;
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 		/* Deallocate previous index in the node page */
515*4882a593Smuzhiyun 		inode = f2fs_iget_retry(sbi->sb, ino);
516*4882a593Smuzhiyun 		if (IS_ERR(inode))
517*4882a593Smuzhiyun 			return PTR_ERR(inode);
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 		ret = dquot_initialize(inode);
520*4882a593Smuzhiyun 		if (ret) {
521*4882a593Smuzhiyun 			iput(inode);
522*4882a593Smuzhiyun 			return ret;
523*4882a593Smuzhiyun 		}
524*4882a593Smuzhiyun 	} else {
525*4882a593Smuzhiyun 		inode = dn->inode;
526*4882a593Smuzhiyun 	}
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	bidx = f2fs_start_bidx_of_node(offset, inode) +
529*4882a593Smuzhiyun 				le16_to_cpu(sum.ofs_in_node);
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 	/*
532*4882a593Smuzhiyun 	 * if inode page is locked, unlock temporarily, but its reference
533*4882a593Smuzhiyun 	 * count keeps alive.
534*4882a593Smuzhiyun 	 */
535*4882a593Smuzhiyun 	if (ino == dn->inode->i_ino && dn->inode_page_locked)
536*4882a593Smuzhiyun 		unlock_page(dn->inode_page);
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	set_new_dnode(&tdn, inode, NULL, NULL, 0);
539*4882a593Smuzhiyun 	if (f2fs_get_dnode_of_data(&tdn, bidx, LOOKUP_NODE))
540*4882a593Smuzhiyun 		goto out;
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	if (tdn.data_blkaddr == blkaddr)
543*4882a593Smuzhiyun 		f2fs_truncate_data_blocks_range(&tdn, 1);
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 	f2fs_put_dnode(&tdn);
546*4882a593Smuzhiyun out:
547*4882a593Smuzhiyun 	if (ino != dn->inode->i_ino)
548*4882a593Smuzhiyun 		iput(inode);
549*4882a593Smuzhiyun 	else if (dn->inode_page_locked)
550*4882a593Smuzhiyun 		lock_page(dn->inode_page);
551*4882a593Smuzhiyun 	return 0;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun truncate_out:
554*4882a593Smuzhiyun 	if (f2fs_data_blkaddr(&tdn) == blkaddr)
555*4882a593Smuzhiyun 		f2fs_truncate_data_blocks_range(&tdn, 1);
556*4882a593Smuzhiyun 	if (dn->inode->i_ino == nid && !dn->inode_page_locked)
557*4882a593Smuzhiyun 		unlock_page(dn->inode_page);
558*4882a593Smuzhiyun 	return 0;
559*4882a593Smuzhiyun }
560*4882a593Smuzhiyun 
do_recover_data(struct f2fs_sb_info * sbi,struct inode * inode,struct page * page)561*4882a593Smuzhiyun static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
562*4882a593Smuzhiyun 					struct page *page)
563*4882a593Smuzhiyun {
564*4882a593Smuzhiyun 	struct dnode_of_data dn;
565*4882a593Smuzhiyun 	struct node_info ni;
566*4882a593Smuzhiyun 	unsigned int start, end;
567*4882a593Smuzhiyun 	int err = 0, recovered = 0;
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	/* step 1: recover xattr */
570*4882a593Smuzhiyun 	if (IS_INODE(page)) {
571*4882a593Smuzhiyun 		err = f2fs_recover_inline_xattr(inode, page);
572*4882a593Smuzhiyun 		if (err)
573*4882a593Smuzhiyun 			goto out;
574*4882a593Smuzhiyun 	} else if (f2fs_has_xattr_block(ofs_of_node(page))) {
575*4882a593Smuzhiyun 		err = f2fs_recover_xattr_data(inode, page);
576*4882a593Smuzhiyun 		if (!err)
577*4882a593Smuzhiyun 			recovered++;
578*4882a593Smuzhiyun 		goto out;
579*4882a593Smuzhiyun 	}
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun 	/* step 2: recover inline data */
582*4882a593Smuzhiyun 	err = f2fs_recover_inline_data(inode, page);
583*4882a593Smuzhiyun 	if (err) {
584*4882a593Smuzhiyun 		if (err == 1)
585*4882a593Smuzhiyun 			err = 0;
586*4882a593Smuzhiyun 		goto out;
587*4882a593Smuzhiyun 	}
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 	/* step 3: recover data indices */
590*4882a593Smuzhiyun 	start = f2fs_start_bidx_of_node(ofs_of_node(page), inode);
591*4882a593Smuzhiyun 	end = start + ADDRS_PER_PAGE(page, inode);
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 	set_new_dnode(&dn, inode, NULL, NULL, 0);
594*4882a593Smuzhiyun retry_dn:
595*4882a593Smuzhiyun 	err = f2fs_get_dnode_of_data(&dn, start, ALLOC_NODE);
596*4882a593Smuzhiyun 	if (err) {
597*4882a593Smuzhiyun 		if (err == -ENOMEM) {
598*4882a593Smuzhiyun 			congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT);
599*4882a593Smuzhiyun 			goto retry_dn;
600*4882a593Smuzhiyun 		}
601*4882a593Smuzhiyun 		goto out;
602*4882a593Smuzhiyun 	}
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun 	f2fs_wait_on_page_writeback(dn.node_page, NODE, true, true);
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	err = f2fs_get_node_info(sbi, dn.nid, &ni, false);
607*4882a593Smuzhiyun 	if (err)
608*4882a593Smuzhiyun 		goto err;
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	f2fs_bug_on(sbi, ni.ino != ino_of_node(page));
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	if (ofs_of_node(dn.node_page) != ofs_of_node(page)) {
613*4882a593Smuzhiyun 		f2fs_warn(sbi, "Inconsistent ofs_of_node, ino:%lu, ofs:%u, %u",
614*4882a593Smuzhiyun 			  inode->i_ino, ofs_of_node(dn.node_page),
615*4882a593Smuzhiyun 			  ofs_of_node(page));
616*4882a593Smuzhiyun 		err = -EFSCORRUPTED;
617*4882a593Smuzhiyun 		goto err;
618*4882a593Smuzhiyun 	}
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun 	for (; start < end; start++, dn.ofs_in_node++) {
621*4882a593Smuzhiyun 		block_t src, dest;
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun 		src = f2fs_data_blkaddr(&dn);
624*4882a593Smuzhiyun 		dest = data_blkaddr(dn.inode, page, dn.ofs_in_node);
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 		if (__is_valid_data_blkaddr(src) &&
627*4882a593Smuzhiyun 			!f2fs_is_valid_blkaddr(sbi, src, META_POR)) {
628*4882a593Smuzhiyun 			err = -EFSCORRUPTED;
629*4882a593Smuzhiyun 			goto err;
630*4882a593Smuzhiyun 		}
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 		if (__is_valid_data_blkaddr(dest) &&
633*4882a593Smuzhiyun 			!f2fs_is_valid_blkaddr(sbi, dest, META_POR)) {
634*4882a593Smuzhiyun 			err = -EFSCORRUPTED;
635*4882a593Smuzhiyun 			goto err;
636*4882a593Smuzhiyun 		}
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun 		/* skip recovering if dest is the same as src */
639*4882a593Smuzhiyun 		if (src == dest)
640*4882a593Smuzhiyun 			continue;
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun 		/* dest is invalid, just invalidate src block */
643*4882a593Smuzhiyun 		if (dest == NULL_ADDR) {
644*4882a593Smuzhiyun 			f2fs_truncate_data_blocks_range(&dn, 1);
645*4882a593Smuzhiyun 			continue;
646*4882a593Smuzhiyun 		}
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 		if (!file_keep_isize(inode) &&
649*4882a593Smuzhiyun 			(i_size_read(inode) <= ((loff_t)start << PAGE_SHIFT)))
650*4882a593Smuzhiyun 			f2fs_i_size_write(inode,
651*4882a593Smuzhiyun 				(loff_t)(start + 1) << PAGE_SHIFT);
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 		/*
654*4882a593Smuzhiyun 		 * dest is reserved block, invalidate src block
655*4882a593Smuzhiyun 		 * and then reserve one new block in dnode page.
656*4882a593Smuzhiyun 		 */
657*4882a593Smuzhiyun 		if (dest == NEW_ADDR) {
658*4882a593Smuzhiyun 			f2fs_truncate_data_blocks_range(&dn, 1);
659*4882a593Smuzhiyun 			f2fs_reserve_new_block(&dn);
660*4882a593Smuzhiyun 			continue;
661*4882a593Smuzhiyun 		}
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 		/* dest is valid block, try to recover from src to dest */
664*4882a593Smuzhiyun 		if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) {
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun 			if (src == NULL_ADDR) {
667*4882a593Smuzhiyun 				err = f2fs_reserve_new_block(&dn);
668*4882a593Smuzhiyun 				while (err &&
669*4882a593Smuzhiyun 				       IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION))
670*4882a593Smuzhiyun 					err = f2fs_reserve_new_block(&dn);
671*4882a593Smuzhiyun 				/* We should not get -ENOSPC */
672*4882a593Smuzhiyun 				f2fs_bug_on(sbi, err);
673*4882a593Smuzhiyun 				if (err)
674*4882a593Smuzhiyun 					goto err;
675*4882a593Smuzhiyun 			}
676*4882a593Smuzhiyun retry_prev:
677*4882a593Smuzhiyun 			/* Check the previous node page having this index */
678*4882a593Smuzhiyun 			err = check_index_in_prev_nodes(sbi, dest, &dn);
679*4882a593Smuzhiyun 			if (err) {
680*4882a593Smuzhiyun 				if (err == -ENOMEM) {
681*4882a593Smuzhiyun 					congestion_wait(BLK_RW_ASYNC,
682*4882a593Smuzhiyun 							DEFAULT_IO_TIMEOUT);
683*4882a593Smuzhiyun 					goto retry_prev;
684*4882a593Smuzhiyun 				}
685*4882a593Smuzhiyun 				goto err;
686*4882a593Smuzhiyun 			}
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 			if (f2fs_is_valid_blkaddr(sbi, dest,
689*4882a593Smuzhiyun 					DATA_GENERIC_ENHANCE_UPDATE)) {
690*4882a593Smuzhiyun 				f2fs_err(sbi, "Inconsistent dest blkaddr:%u, ino:%lu, ofs:%u",
691*4882a593Smuzhiyun 					dest, inode->i_ino, dn.ofs_in_node);
692*4882a593Smuzhiyun 				err = -EFSCORRUPTED;
693*4882a593Smuzhiyun 				goto err;
694*4882a593Smuzhiyun 			}
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun 			/* write dummy data page */
697*4882a593Smuzhiyun 			f2fs_replace_block(sbi, &dn, src, dest,
698*4882a593Smuzhiyun 						ni.version, false, false);
699*4882a593Smuzhiyun 			recovered++;
700*4882a593Smuzhiyun 		}
701*4882a593Smuzhiyun 	}
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun 	copy_node_footer(dn.node_page, page);
704*4882a593Smuzhiyun 	fill_node_footer(dn.node_page, dn.nid, ni.ino,
705*4882a593Smuzhiyun 					ofs_of_node(page), false);
706*4882a593Smuzhiyun 	set_page_dirty(dn.node_page);
707*4882a593Smuzhiyun err:
708*4882a593Smuzhiyun 	f2fs_put_dnode(&dn);
709*4882a593Smuzhiyun out:
710*4882a593Smuzhiyun 	f2fs_notice(sbi, "recover_data: ino = %lx (i_size: %s) recovered = %d, err = %d",
711*4882a593Smuzhiyun 		    inode->i_ino, file_keep_isize(inode) ? "keep" : "recover",
712*4882a593Smuzhiyun 		    recovered, err);
713*4882a593Smuzhiyun 	return err;
714*4882a593Smuzhiyun }
715*4882a593Smuzhiyun 
recover_data(struct f2fs_sb_info * sbi,struct list_head * inode_list,struct list_head * tmp_inode_list,struct list_head * dir_list)716*4882a593Smuzhiyun static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
717*4882a593Smuzhiyun 		struct list_head *tmp_inode_list, struct list_head *dir_list)
718*4882a593Smuzhiyun {
719*4882a593Smuzhiyun 	struct curseg_info *curseg;
720*4882a593Smuzhiyun 	struct page *page = NULL;
721*4882a593Smuzhiyun 	int err = 0;
722*4882a593Smuzhiyun 	block_t blkaddr;
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun 	/* get node pages in the current segment */
725*4882a593Smuzhiyun 	curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
726*4882a593Smuzhiyun 	blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	while (1) {
729*4882a593Smuzhiyun 		struct fsync_inode_entry *entry;
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun 		if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR))
732*4882a593Smuzhiyun 			break;
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun 		f2fs_ra_meta_pages_cond(sbi, blkaddr);
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun 		page = f2fs_get_tmp_page(sbi, blkaddr);
737*4882a593Smuzhiyun 		if (IS_ERR(page)) {
738*4882a593Smuzhiyun 			err = PTR_ERR(page);
739*4882a593Smuzhiyun 			break;
740*4882a593Smuzhiyun 		}
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 		if (!is_recoverable_dnode(page)) {
743*4882a593Smuzhiyun 			f2fs_put_page(page, 1);
744*4882a593Smuzhiyun 			break;
745*4882a593Smuzhiyun 		}
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 		entry = get_fsync_inode(inode_list, ino_of_node(page));
748*4882a593Smuzhiyun 		if (!entry)
749*4882a593Smuzhiyun 			goto next;
750*4882a593Smuzhiyun 		/*
751*4882a593Smuzhiyun 		 * inode(x) | CP | inode(x) | dnode(F)
752*4882a593Smuzhiyun 		 * In this case, we can lose the latest inode(x).
753*4882a593Smuzhiyun 		 * So, call recover_inode for the inode update.
754*4882a593Smuzhiyun 		 */
755*4882a593Smuzhiyun 		if (IS_INODE(page)) {
756*4882a593Smuzhiyun 			err = recover_inode(entry->inode, page);
757*4882a593Smuzhiyun 			if (err) {
758*4882a593Smuzhiyun 				f2fs_put_page(page, 1);
759*4882a593Smuzhiyun 				break;
760*4882a593Smuzhiyun 			}
761*4882a593Smuzhiyun 		}
762*4882a593Smuzhiyun 		if (entry->last_dentry == blkaddr) {
763*4882a593Smuzhiyun 			err = recover_dentry(entry->inode, page, dir_list);
764*4882a593Smuzhiyun 			if (err) {
765*4882a593Smuzhiyun 				f2fs_put_page(page, 1);
766*4882a593Smuzhiyun 				break;
767*4882a593Smuzhiyun 			}
768*4882a593Smuzhiyun 		}
769*4882a593Smuzhiyun 		err = do_recover_data(sbi, entry->inode, page);
770*4882a593Smuzhiyun 		if (err) {
771*4882a593Smuzhiyun 			f2fs_put_page(page, 1);
772*4882a593Smuzhiyun 			break;
773*4882a593Smuzhiyun 		}
774*4882a593Smuzhiyun 
775*4882a593Smuzhiyun 		if (entry->blkaddr == blkaddr)
776*4882a593Smuzhiyun 			list_move_tail(&entry->list, tmp_inode_list);
777*4882a593Smuzhiyun next:
778*4882a593Smuzhiyun 		/* check next segment */
779*4882a593Smuzhiyun 		blkaddr = next_blkaddr_of_node(page);
780*4882a593Smuzhiyun 		f2fs_put_page(page, 1);
781*4882a593Smuzhiyun 	}
782*4882a593Smuzhiyun 	if (!err)
783*4882a593Smuzhiyun 		f2fs_allocate_new_segments(sbi);
784*4882a593Smuzhiyun 	return err;
785*4882a593Smuzhiyun }
786*4882a593Smuzhiyun 
f2fs_recover_fsync_data(struct f2fs_sb_info * sbi,bool check_only)787*4882a593Smuzhiyun int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
788*4882a593Smuzhiyun {
789*4882a593Smuzhiyun 	struct list_head inode_list, tmp_inode_list;
790*4882a593Smuzhiyun 	struct list_head dir_list;
791*4882a593Smuzhiyun 	int err;
792*4882a593Smuzhiyun 	int ret = 0;
793*4882a593Smuzhiyun 	unsigned long s_flags = sbi->sb->s_flags;
794*4882a593Smuzhiyun 	bool need_writecp = false;
795*4882a593Smuzhiyun 	bool fix_curseg_write_pointer = false;
796*4882a593Smuzhiyun #ifdef CONFIG_QUOTA
797*4882a593Smuzhiyun 	int quota_enabled;
798*4882a593Smuzhiyun #endif
799*4882a593Smuzhiyun 
800*4882a593Smuzhiyun 	if (s_flags & SB_RDONLY) {
801*4882a593Smuzhiyun 		f2fs_info(sbi, "recover fsync data on readonly fs");
802*4882a593Smuzhiyun 		sbi->sb->s_flags &= ~SB_RDONLY;
803*4882a593Smuzhiyun 	}
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun #ifdef CONFIG_QUOTA
806*4882a593Smuzhiyun 	/* Needed for iput() to work correctly and not trash data */
807*4882a593Smuzhiyun 	sbi->sb->s_flags |= SB_ACTIVE;
808*4882a593Smuzhiyun 	/* Turn on quotas so that they are updated correctly */
809*4882a593Smuzhiyun 	quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY);
810*4882a593Smuzhiyun #endif
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 	INIT_LIST_HEAD(&inode_list);
813*4882a593Smuzhiyun 	INIT_LIST_HEAD(&tmp_inode_list);
814*4882a593Smuzhiyun 	INIT_LIST_HEAD(&dir_list);
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun 	/* prevent checkpoint */
817*4882a593Smuzhiyun 	f2fs_down_write(&sbi->cp_global_sem);
818*4882a593Smuzhiyun 
819*4882a593Smuzhiyun 	/* step #1: find fsynced inode numbers */
820*4882a593Smuzhiyun 	err = find_fsync_dnodes(sbi, &inode_list, check_only);
821*4882a593Smuzhiyun 	if (err || list_empty(&inode_list))
822*4882a593Smuzhiyun 		goto skip;
823*4882a593Smuzhiyun 
824*4882a593Smuzhiyun 	if (check_only) {
825*4882a593Smuzhiyun 		ret = 1;
826*4882a593Smuzhiyun 		goto skip;
827*4882a593Smuzhiyun 	}
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun 	need_writecp = true;
830*4882a593Smuzhiyun 
831*4882a593Smuzhiyun 	/* step #2: recover data */
832*4882a593Smuzhiyun 	err = recover_data(sbi, &inode_list, &tmp_inode_list, &dir_list);
833*4882a593Smuzhiyun 	if (!err)
834*4882a593Smuzhiyun 		f2fs_bug_on(sbi, !list_empty(&inode_list));
835*4882a593Smuzhiyun 	else {
836*4882a593Smuzhiyun 		/* restore s_flags to let iput() trash data */
837*4882a593Smuzhiyun 		sbi->sb->s_flags = s_flags;
838*4882a593Smuzhiyun 	}
839*4882a593Smuzhiyun skip:
840*4882a593Smuzhiyun 	fix_curseg_write_pointer = !check_only || list_empty(&inode_list);
841*4882a593Smuzhiyun 
842*4882a593Smuzhiyun 	destroy_fsync_dnodes(&inode_list, err);
843*4882a593Smuzhiyun 	destroy_fsync_dnodes(&tmp_inode_list, err);
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun 	/* truncate meta pages to be used by the recovery */
846*4882a593Smuzhiyun 	truncate_inode_pages_range(META_MAPPING(sbi),
847*4882a593Smuzhiyun 			(loff_t)MAIN_BLKADDR(sbi) << PAGE_SHIFT, -1);
848*4882a593Smuzhiyun 
849*4882a593Smuzhiyun 	if (err) {
850*4882a593Smuzhiyun 		truncate_inode_pages_final(NODE_MAPPING(sbi));
851*4882a593Smuzhiyun 		truncate_inode_pages_final(META_MAPPING(sbi));
852*4882a593Smuzhiyun 	}
853*4882a593Smuzhiyun 
854*4882a593Smuzhiyun 	/*
855*4882a593Smuzhiyun 	 * If fsync data succeeds or there is no fsync data to recover,
856*4882a593Smuzhiyun 	 * and the f2fs is not read only, check and fix zoned block devices'
857*4882a593Smuzhiyun 	 * write pointer consistency.
858*4882a593Smuzhiyun 	 */
859*4882a593Smuzhiyun 	if (!err && fix_curseg_write_pointer && !f2fs_readonly(sbi->sb) &&
860*4882a593Smuzhiyun 			f2fs_sb_has_blkzoned(sbi)) {
861*4882a593Smuzhiyun 		err = f2fs_fix_curseg_write_pointer(sbi);
862*4882a593Smuzhiyun 		ret = err;
863*4882a593Smuzhiyun 	}
864*4882a593Smuzhiyun 
865*4882a593Smuzhiyun 	if (!err)
866*4882a593Smuzhiyun 		clear_sbi_flag(sbi, SBI_POR_DOING);
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun 	f2fs_up_write(&sbi->cp_global_sem);
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun 	/* let's drop all the directory inodes for clean checkpoint */
871*4882a593Smuzhiyun 	destroy_fsync_dnodes(&dir_list, err);
872*4882a593Smuzhiyun 
873*4882a593Smuzhiyun 	if (need_writecp) {
874*4882a593Smuzhiyun 		set_sbi_flag(sbi, SBI_IS_RECOVERED);
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun 		if (!err) {
877*4882a593Smuzhiyun 			struct cp_control cpc = {
878*4882a593Smuzhiyun 				.reason = CP_RECOVERY,
879*4882a593Smuzhiyun 			};
880*4882a593Smuzhiyun 			err = f2fs_write_checkpoint(sbi, &cpc);
881*4882a593Smuzhiyun 		}
882*4882a593Smuzhiyun 	}
883*4882a593Smuzhiyun 
884*4882a593Smuzhiyun #ifdef CONFIG_QUOTA
885*4882a593Smuzhiyun 	/* Turn quotas off */
886*4882a593Smuzhiyun 	if (quota_enabled)
887*4882a593Smuzhiyun 		f2fs_quota_off_umount(sbi->sb);
888*4882a593Smuzhiyun #endif
889*4882a593Smuzhiyun 	sbi->sb->s_flags = s_flags; /* Restore SB_RDONLY status */
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun 	return ret ? ret : err;
892*4882a593Smuzhiyun }
893*4882a593Smuzhiyun 
f2fs_create_recovery_cache(void)894*4882a593Smuzhiyun int __init f2fs_create_recovery_cache(void)
895*4882a593Smuzhiyun {
896*4882a593Smuzhiyun 	fsync_entry_slab = f2fs_kmem_cache_create("f2fs_fsync_inode_entry",
897*4882a593Smuzhiyun 					sizeof(struct fsync_inode_entry));
898*4882a593Smuzhiyun 	if (!fsync_entry_slab)
899*4882a593Smuzhiyun 		return -ENOMEM;
900*4882a593Smuzhiyun 	return 0;
901*4882a593Smuzhiyun }
902*4882a593Smuzhiyun 
f2fs_destroy_recovery_cache(void)903*4882a593Smuzhiyun void f2fs_destroy_recovery_cache(void)
904*4882a593Smuzhiyun {
905*4882a593Smuzhiyun 	kmem_cache_destroy(fsync_entry_slab);
906*4882a593Smuzhiyun }
907