Blame view

fs/f2fs/checkpoint.c 41.8 KB
7c1a000d4   Chao Yu   f2fs: add SPDX li...
1
  // SPDX-License-Identifier: GPL-2.0
0a8165d7c   Jaegeuk Kim   f2fs: adjust kern...
2
  /*
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
3
4
5
6
   * fs/f2fs/checkpoint.c
   *
   * Copyright (c) 2012 Samsung Electronics Co., Ltd.
   *             http://www.samsung.com/
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
7
8
9
10
11
12
13
14
15
16
17
18
19
   */
  #include <linux/fs.h>
  #include <linux/bio.h>
  #include <linux/mpage.h>
  #include <linux/writeback.h>
  #include <linux/blkdev.h>
  #include <linux/f2fs_fs.h>
  #include <linux/pagevec.h>
  #include <linux/swap.h>
  
  #include "f2fs.h"
  #include "node.h"
  #include "segment.h"
9e4ded3f3   Jaegeuk Kim   f2fs: activate f2...
20
  #include "trace.h"
2af4bd6ca   Namjae Jeon   f2fs: add tracepo...
21
  #include <trace/events/f2fs.h>
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
22

6451e041c   Jaegeuk Kim   f2fs: add infra f...
23
  static struct kmem_cache *ino_entry_slab;
4d57b86dd   Chao Yu   f2fs: clean up sy...
24
  struct kmem_cache *f2fs_inode_entry_slab;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
25

38f91ca8c   Jaegeuk Kim   f2fs: flush pendi...
26
27
  void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
  {
d494500a7   Chao Yu   f2fs: support fau...
28
  	f2fs_build_fault_attr(sbi, 0, 0);
aaec2b1d1   Chao Yu   f2fs: introduce c...
29
  	set_ckpt_flags(sbi, CP_ERROR_FLAG);
38f91ca8c   Jaegeuk Kim   f2fs: flush pendi...
30
  	if (!end_io)
b9109b0e4   Jaegeuk Kim   f2fs: remove unne...
31
  		f2fs_flush_merged_writes(sbi);
38f91ca8c   Jaegeuk Kim   f2fs: flush pendi...
32
  }
0a8165d7c   Jaegeuk Kim   f2fs: adjust kern...
33
  /*
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
34
35
   * We guarantee no failure on the returned page.
   */
4d57b86dd   Chao Yu   f2fs: clean up sy...
36
  struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
37
  {
9df27d982   Gu Zheng   f2fs: add help fu...
38
  	struct address_space *mapping = META_MAPPING(sbi);
c60814e9f   Zhang Qilong   f2fs: Remove the ...
39
  	struct page *page;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
40
  repeat:
300e129c1   Jaegeuk Kim   f2fs: use f2fs_gr...
41
  	page = f2fs_grab_cache_page(mapping, index, false);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
42
43
44
45
  	if (!page) {
  		cond_resched();
  		goto repeat;
  	}
bae0ee7a7   Chao Yu   f2fs: check PageW...
46
  	f2fs_wait_on_page_writeback(page, META, true, true);
237c0790e   Jaegeuk Kim   f2fs: call SetPag...
47
48
  	if (!PageUptodate(page))
  		SetPageUptodate(page);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
49
50
  	return page;
  }
2b947003f   Chao Yu   f2fs: don't tag R...
51
52
  static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
  							bool is_meta)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
53
  {
9df27d982   Gu Zheng   f2fs: add help fu...
54
  	struct address_space *mapping = META_MAPPING(sbi);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
55
  	struct page *page;
cf04e8eb5   Jaegeuk Kim   f2fs: use f2fs_io...
56
  	struct f2fs_io_info fio = {
05ca3632e   Jaegeuk Kim   f2fs: add sbi and...
57
  		.sbi = sbi,
cf04e8eb5   Jaegeuk Kim   f2fs: use f2fs_io...
58
  		.type = META,
04d328def   Mike Christie   f2fs: use bio op ...
59
  		.op = REQ_OP_READ,
70fd76140   Christoph Hellwig   block,fs: use REQ...
60
  		.op_flags = REQ_META | REQ_PRIO,
7a9d75481   Chao Yu   f2fs: trace old b...
61
62
  		.old_blkaddr = index,
  		.new_blkaddr = index,
4375a3366   Jaegeuk Kim   f2fs crypto: add ...
63
  		.encrypted_page = NULL,
6dc3a1266   Chao Yu   f2fs: fix wrong _...
64
  		.is_por = !is_meta,
cf04e8eb5   Jaegeuk Kim   f2fs: use f2fs_io...
65
  	};
7735730d3   Chao Yu   f2fs: fix to prop...
66
  	int err;
2b947003f   Chao Yu   f2fs: don't tag R...
67
68
  
  	if (unlikely(!is_meta))
04d328def   Mike Christie   f2fs: use bio op ...
69
  		fio.op_flags &= ~REQ_META;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
70
  repeat:
300e129c1   Jaegeuk Kim   f2fs: use f2fs_gr...
71
  	page = f2fs_grab_cache_page(mapping, index, false);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
72
73
74
75
  	if (!page) {
  		cond_resched();
  		goto repeat;
  	}
393ff91f5   Jaegeuk Kim   f2fs: reduce unnc...
76
77
  	if (PageUptodate(page))
  		goto out;
05ca3632e   Jaegeuk Kim   f2fs: add sbi and...
78
  	fio.page = page;
7735730d3   Chao Yu   f2fs: fix to prop...
79
80
81
82
  	err = f2fs_submit_page_bio(&fio);
  	if (err) {
  		f2fs_put_page(page, 1);
  		return ERR_PTR(err);
86531d6b8   Jaegeuk Kim   f2fs: callers tak...
83
  	}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
84

8b83ac81f   Chao Yu   f2fs: support rea...
85
  	f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
393ff91f5   Jaegeuk Kim   f2fs: reduce unnc...
86
  	lock_page(page);
6bacf52fb   Jaegeuk Kim   f2fs: add unlikel...
87
  	if (unlikely(page->mapping != mapping)) {
afcb7ca01   Jaegeuk Kim   f2fs: check trunc...
88
89
90
  		f2fs_put_page(page, 1);
  		goto repeat;
  	}
f3f338caa   Chao Yu   f2fs: freeze file...
91

81114baa8   Chao Yu   f2fs: don't use G...
92
  	if (unlikely(!PageUptodate(page))) {
7735730d3   Chao Yu   f2fs: fix to prop...
93
94
  		f2fs_put_page(page, 1);
  		return ERR_PTR(-EIO);
81114baa8   Chao Yu   f2fs: don't use G...
95
  	}
393ff91f5   Jaegeuk Kim   f2fs: reduce unnc...
96
  out:
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
97
98
  	return page;
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
99
  struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
2b947003f   Chao Yu   f2fs: don't tag R...
100
101
102
  {
  	return __get_meta_page(sbi, index, true);
  }
86f33603f   Jaegeuk Kim   f2fs: handle erro...
103
  struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index)
7735730d3   Chao Yu   f2fs: fix to prop...
104
105
106
107
108
109
110
111
112
113
  {
  	struct page *page;
  	int count = 0;
  
  retry:
  	page = __get_meta_page(sbi, index, true);
  	if (IS_ERR(page)) {
  		if (PTR_ERR(page) == -EIO &&
  				++count <= DEFAULT_RETRY_IO_COUNT)
  			goto retry;
7735730d3   Chao Yu   f2fs: fix to prop...
114
  		f2fs_stop_checkpoint(sbi, false);
7735730d3   Chao Yu   f2fs: fix to prop...
115
  	}
7735730d3   Chao Yu   f2fs: fix to prop...
116
117
  	return page;
  }
2b947003f   Chao Yu   f2fs: don't tag R...
118
  /* for POR only */
4d57b86dd   Chao Yu   f2fs: clean up sy...
119
  struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index)
2b947003f   Chao Yu   f2fs: don't tag R...
120
121
122
  {
  	return __get_meta_page(sbi, index, false);
  }
93770ab7a   Chao Yu   f2fs: introduce D...
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
  static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
  							int type)
  {
  	struct seg_entry *se;
  	unsigned int segno, offset;
  	bool exist;
  
  	if (type != DATA_GENERIC_ENHANCE && type != DATA_GENERIC_ENHANCE_READ)
  		return true;
  
  	segno = GET_SEGNO(sbi, blkaddr);
  	offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
  	se = get_seg_entry(sbi, segno);
  
  	exist = f2fs_test_bit(offset, se->cur_valid_map);
  	if (!exist && type == DATA_GENERIC_ENHANCE) {
dcbb4c10e   Joe Perches   f2fs: introduce f...
139
140
  		f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
  			 blkaddr, exist);
93770ab7a   Chao Yu   f2fs: introduce D...
141
142
143
144
145
  		set_sbi_flag(sbi, SBI_NEED_FSCK);
  		WARN_ON(1);
  	}
  	return exist;
  }
e1da7872f   Chao Yu   f2fs: introduce a...
146
  bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
4d57b86dd   Chao Yu   f2fs: clean up sy...
147
  					block_t blkaddr, int type)
662befda2   Chao Yu   f2fs: introduce r...
148
149
150
  {
  	switch (type) {
  	case META_NAT:
66b00c186   Chao Yu   f2fs: introduce i...
151
  		break;
662befda2   Chao Yu   f2fs: introduce r...
152
  	case META_SIT:
66b00c186   Chao Yu   f2fs: introduce i...
153
154
155
  		if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
  			return false;
  		break;
81c1a0f13   Chao Yu   f2fs: readahead c...
156
  	case META_SSA:
66b00c186   Chao Yu   f2fs: introduce i...
157
158
159
160
  		if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
  			blkaddr < SM_I(sbi)->ssa_blkaddr))
  			return false;
  		break;
662befda2   Chao Yu   f2fs: introduce r...
161
  	case META_CP:
66b00c186   Chao Yu   f2fs: introduce i...
162
163
164
165
  		if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
  			blkaddr < __start_cp_addr(sbi)))
  			return false;
  		break;
4c521f493   Jaegeuk Kim   f2fs: use meta_in...
166
  	case META_POR:
93770ab7a   Chao Yu   f2fs: introduce D...
167
168
169
170
  		if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
  			blkaddr < MAIN_BLKADDR(sbi)))
  			return false;
  		break;
e1da7872f   Chao Yu   f2fs: introduce a...
171
  	case DATA_GENERIC:
93770ab7a   Chao Yu   f2fs: introduce D...
172
173
  	case DATA_GENERIC_ENHANCE:
  	case DATA_GENERIC_ENHANCE_READ:
66b00c186   Chao Yu   f2fs: introduce i...
174
  		if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
93770ab7a   Chao Yu   f2fs: introduce D...
175
  				blkaddr < MAIN_BLKADDR(sbi))) {
dcbb4c10e   Joe Perches   f2fs: introduce f...
176
177
  			f2fs_warn(sbi, "access invalid blkaddr:%u",
  				  blkaddr);
93770ab7a   Chao Yu   f2fs: introduce D...
178
179
  			set_sbi_flag(sbi, SBI_NEED_FSCK);
  			WARN_ON(1);
66b00c186   Chao Yu   f2fs: introduce i...
180
  			return false;
93770ab7a   Chao Yu   f2fs: introduce D...
181
182
  		} else {
  			return __is_bitmap_valid(sbi, blkaddr, type);
c9b60788f   Chao Yu   f2fs: fix to do s...
183
  		}
66b00c186   Chao Yu   f2fs: introduce i...
184
  		break;
e1da7872f   Chao Yu   f2fs: introduce a...
185
186
187
188
189
  	case META_GENERIC:
  		if (unlikely(blkaddr < SEG0_BLKADDR(sbi) ||
  			blkaddr >= MAIN_BLKADDR(sbi)))
  			return false;
  		break;
662befda2   Chao Yu   f2fs: introduce r...
190
191
192
  	default:
  		BUG();
  	}
66b00c186   Chao Yu   f2fs: introduce i...
193
194
  
  	return true;
662befda2   Chao Yu   f2fs: introduce r...
195
196
197
  }
  
  /*
7a88ddb56   Chao Yu   f2fs: fix inconsi...
198
   * Readahead CP/NAT/SIT/SSA/POR pages
662befda2   Chao Yu   f2fs: introduce r...
199
   */
4d57b86dd   Chao Yu   f2fs: clean up sy...
200
  int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
26879fb10   Chao Yu   f2fs: support low...
201
  							int type, bool sync)
662befda2   Chao Yu   f2fs: introduce r...
202
  {
662befda2   Chao Yu   f2fs: introduce r...
203
  	struct page *page;
4c521f493   Jaegeuk Kim   f2fs: use meta_in...
204
  	block_t blkno = start;
662befda2   Chao Yu   f2fs: introduce r...
205
  	struct f2fs_io_info fio = {
05ca3632e   Jaegeuk Kim   f2fs: add sbi and...
206
  		.sbi = sbi,
662befda2   Chao Yu   f2fs: introduce r...
207
  		.type = META,
04d328def   Mike Christie   f2fs: use bio op ...
208
  		.op = REQ_OP_READ,
70fd76140   Christoph Hellwig   block,fs: use REQ...
209
  		.op_flags = sync ? (REQ_META | REQ_PRIO) : REQ_RAHEAD,
4375a3366   Jaegeuk Kim   f2fs crypto: add ...
210
  		.encrypted_page = NULL,
fb830fc5c   Chao Yu   f2fs: introduce i...
211
  		.in_list = false,
6dc3a1266   Chao Yu   f2fs: fix wrong _...
212
  		.is_por = (type == META_POR),
662befda2   Chao Yu   f2fs: introduce r...
213
  	};
e9f5b8b8d   Chao Yu   f2fs: enhance IO ...
214
  	struct blk_plug plug;
ce4c638cd   Chao Yu   f2fs: fix to hand...
215
  	int err;
662befda2   Chao Yu   f2fs: introduce r...
216

2b947003f   Chao Yu   f2fs: don't tag R...
217
  	if (unlikely(type == META_POR))
04d328def   Mike Christie   f2fs: use bio op ...
218
  		fio.op_flags &= ~REQ_META;
2b947003f   Chao Yu   f2fs: don't tag R...
219

e9f5b8b8d   Chao Yu   f2fs: enhance IO ...
220
  	blk_start_plug(&plug);
662befda2   Chao Yu   f2fs: introduce r...
221
  	for (; nrpages-- > 0; blkno++) {
662befda2   Chao Yu   f2fs: introduce r...
222

e1da7872f   Chao Yu   f2fs: introduce a...
223
  		if (!f2fs_is_valid_blkaddr(sbi, blkno, type))
66b00c186   Chao Yu   f2fs: introduce i...
224
  			goto out;
662befda2   Chao Yu   f2fs: introduce r...
225
226
  		switch (type) {
  		case META_NAT:
66b00c186   Chao Yu   f2fs: introduce i...
227
228
  			if (unlikely(blkno >=
  					NAT_BLOCK_OFFSET(NM_I(sbi)->max_nid)))
662befda2   Chao Yu   f2fs: introduce r...
229
  				blkno = 0;
66b00c186   Chao Yu   f2fs: introduce i...
230
  			/* get nat block addr */
7a9d75481   Chao Yu   f2fs: trace old b...
231
  			fio.new_blkaddr = current_nat_addr(sbi,
662befda2   Chao Yu   f2fs: introduce r...
232
233
234
  					blkno * NAT_ENTRY_PER_BLOCK);
  			break;
  		case META_SIT:
6a257471f   Chao Yu   f2fs: fix to chec...
235
236
  			if (unlikely(blkno >= TOTAL_SEGS(sbi)))
  				goto out;
662befda2   Chao Yu   f2fs: introduce r...
237
  			/* get sit block addr */
7a9d75481   Chao Yu   f2fs: trace old b...
238
  			fio.new_blkaddr = current_sit_addr(sbi,
662befda2   Chao Yu   f2fs: introduce r...
239
  					blkno * SIT_ENTRY_PER_BLOCK);
662befda2   Chao Yu   f2fs: introduce r...
240
  			break;
81c1a0f13   Chao Yu   f2fs: readahead c...
241
  		case META_SSA:
662befda2   Chao Yu   f2fs: introduce r...
242
  		case META_CP:
4c521f493   Jaegeuk Kim   f2fs: use meta_in...
243
  		case META_POR:
7a9d75481   Chao Yu   f2fs: trace old b...
244
  			fio.new_blkaddr = blkno;
662befda2   Chao Yu   f2fs: introduce r...
245
246
247
248
  			break;
  		default:
  			BUG();
  		}
300e129c1   Jaegeuk Kim   f2fs: use f2fs_gr...
249
250
  		page = f2fs_grab_cache_page(META_MAPPING(sbi),
  						fio.new_blkaddr, false);
662befda2   Chao Yu   f2fs: introduce r...
251
252
253
  		if (!page)
  			continue;
  		if (PageUptodate(page)) {
662befda2   Chao Yu   f2fs: introduce r...
254
255
256
  			f2fs_put_page(page, 1);
  			continue;
  		}
05ca3632e   Jaegeuk Kim   f2fs: add sbi and...
257
  		fio.page = page;
ce4c638cd   Chao Yu   f2fs: fix to hand...
258
259
  		err = f2fs_submit_page_bio(&fio);
  		f2fs_put_page(page, err ? 1 : 0);
8b83ac81f   Chao Yu   f2fs: support rea...
260
261
262
  
  		if (!err)
  			f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
662befda2   Chao Yu   f2fs: introduce r...
263
264
  	}
  out:
e9f5b8b8d   Chao Yu   f2fs: enhance IO ...
265
  	blk_finish_plug(&plug);
662befda2   Chao Yu   f2fs: introduce r...
266
267
  	return blkno - start;
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
268
  void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index)
635aee1fe   Chao Yu   f2fs: avoid to ra...
269
270
271
272
273
  {
  	struct page *page;
  	bool readahead = false;
  
  	page = find_get_page(META_MAPPING(sbi), index);
4da7bf5a4   Jaegeuk Kim   f2fs: remove redu...
274
  	if (!page || !PageUptodate(page))
635aee1fe   Chao Yu   f2fs: avoid to ra...
275
276
277
278
  		readahead = true;
  	f2fs_put_page(page, 0);
  
  	if (readahead)
4d57b86dd   Chao Yu   f2fs: clean up sy...
279
  		f2fs_ra_meta_pages(sbi, index, BIO_MAX_PAGES, META_POR, true);
635aee1fe   Chao Yu   f2fs: avoid to ra...
280
  }
b0af6d491   Chao Yu   f2fs: add app/fs ...
281
282
283
  static int __f2fs_write_meta_page(struct page *page,
  				struct writeback_control *wbc,
  				enum iostat_type io_type)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
284
  {
4081363fb   Jaegeuk Kim   f2fs: introduce F...
285
  	struct f2fs_sb_info *sbi = F2FS_P_SB(page);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
286

ecda0de34   Chao Yu   f2fs: add a trace...
287
  	trace_f2fs_writepage(page, META);
af697c0f5   Jaegeuk Kim   f2fs: keep meta p...
288
289
  	if (unlikely(f2fs_cp_error(sbi)))
  		goto redirty_out;
caf0047e7   Chao Yu   f2fs: merge flags...
290
  	if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
cfb271d48   Chao Yu   f2fs: add unlikel...
291
  		goto redirty_out;
857dc4e05   Jaegeuk Kim   f2fs: write SSA p...
292
  	if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0))
cfb271d48   Chao Yu   f2fs: add unlikel...
293
  		goto redirty_out;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
294

4d57b86dd   Chao Yu   f2fs: clean up sy...
295
  	f2fs_do_write_meta_page(sbi, page, io_type);
577e34951   Jaegeuk Kim   f2fs: prevent che...
296
  	dec_page_count(sbi, F2FS_DIRTY_META);
0c3a57975   Chao Yu   f2fs: introduce f...
297
298
  
  	if (wbc->for_reclaim)
bab475c54   Chao Yu   Revert: "f2fs: ch...
299
  		f2fs_submit_merged_write_cond(sbi, NULL, page, 0, META);
0c3a57975   Chao Yu   f2fs: introduce f...
300

577e34951   Jaegeuk Kim   f2fs: prevent che...
301
  	unlock_page(page);
857dc4e05   Jaegeuk Kim   f2fs: write SSA p...
302

0c3a57975   Chao Yu   f2fs: introduce f...
303
  	if (unlikely(f2fs_cp_error(sbi)))
b9109b0e4   Jaegeuk Kim   f2fs: remove unne...
304
  		f2fs_submit_merged_write(sbi, META);
0c3a57975   Chao Yu   f2fs: introduce f...
305

577e34951   Jaegeuk Kim   f2fs: prevent che...
306
  	return 0;
cfb271d48   Chao Yu   f2fs: add unlikel...
307
308
  
  redirty_out:
76f60268e   Jaegeuk Kim   f2fs: call redirt...
309
  	redirty_page_for_writepage(wbc, page);
cfb271d48   Chao Yu   f2fs: add unlikel...
310
  	return AOP_WRITEPAGE_ACTIVATE;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
311
  }
b0af6d491   Chao Yu   f2fs: add app/fs ...
312
313
314
315
316
  static int f2fs_write_meta_page(struct page *page,
  				struct writeback_control *wbc)
  {
  	return __f2fs_write_meta_page(page, wbc, FS_META_IO);
  }
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
317
318
319
  static int f2fs_write_meta_pages(struct address_space *mapping,
  				struct writeback_control *wbc)
  {
4081363fb   Jaegeuk Kim   f2fs: introduce F...
320
  	struct f2fs_sb_info *sbi = F2FS_M_SB(mapping);
50c8cdb35   Jaegeuk Kim   f2fs: introduce n...
321
  	long diff, written;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
322

0771fcc71   Chao Yu   f2fs: skip ->writ...
323
324
  	if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
  		goto skip_write;
5459aa977   Jaegeuk Kim   f2fs: write dirty...
325
  	/* collect a number of dirty meta pages and write together */
812a95977   Jaegeuk Kim   f2fs: sync filesy...
326
327
328
  	if (wbc->sync_mode != WB_SYNC_ALL &&
  			get_pages(sbi, F2FS_DIRTY_META) <
  					nr_pages_to_skip(sbi, META))
d3baf95da   Jaegeuk Kim   f2fs: increase pa...
329
  		goto skip_write;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
330

a29d0e0bc   Yunlei He   f2fs: skip writeb...
331
  	/* if locked failed, cp will flush dirty pages instead */
301e31717   Sahitya Tummala   f2fs: change to u...
332
  	if (!down_write_trylock(&sbi->cp_global_sem))
a29d0e0bc   Yunlei He   f2fs: skip writeb...
333
  		goto skip_write;
d31c7c3f0   Yunlei He   f2fs: fix missing...
334

a29d0e0bc   Yunlei He   f2fs: skip writeb...
335
  	trace_f2fs_writepages(mapping->host, wbc, META);
50c8cdb35   Jaegeuk Kim   f2fs: introduce n...
336
  	diff = nr_pages_to_write(sbi, META, wbc);
4d57b86dd   Chao Yu   f2fs: clean up sy...
337
  	written = f2fs_sync_meta_pages(sbi, META, wbc->nr_to_write, FS_META_IO);
301e31717   Sahitya Tummala   f2fs: change to u...
338
  	up_write(&sbi->cp_global_sem);
50c8cdb35   Jaegeuk Kim   f2fs: introduce n...
339
  	wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
340
  	return 0;
d3baf95da   Jaegeuk Kim   f2fs: increase pa...
341
342
343
  
  skip_write:
  	wbc->pages_skipped += get_pages(sbi, F2FS_DIRTY_META);
d31c7c3f0   Yunlei He   f2fs: fix missing...
344
  	trace_f2fs_writepages(mapping->host, wbc, META);
d3baf95da   Jaegeuk Kim   f2fs: increase pa...
345
  	return 0;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
346
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
347
  long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
b0af6d491   Chao Yu   f2fs: add app/fs ...
348
  				long nr_to_write, enum iostat_type io_type)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
349
  {
9df27d982   Gu Zheng   f2fs: add help fu...
350
  	struct address_space *mapping = META_MAPPING(sbi);
028a63a6e   Jan Kara   f2fs: simplify pa...
351
  	pgoff_t index = 0, prev = ULONG_MAX;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
352
353
  	struct pagevec pvec;
  	long nwritten = 0;
028a63a6e   Jan Kara   f2fs: simplify pa...
354
  	int nr_pages;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
355
356
357
  	struct writeback_control wbc = {
  		.for_reclaim = 0,
  	};
e9f5b8b8d   Chao Yu   f2fs: enhance IO ...
358
  	struct blk_plug plug;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
359

866798201   Mel Gorman   mm, pagevec: remo...
360
  	pagevec_init(&pvec);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
361

e9f5b8b8d   Chao Yu   f2fs: enhance IO ...
362
  	blk_start_plug(&plug);
028a63a6e   Jan Kara   f2fs: simplify pa...
363
  	while ((nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
67fd707f4   Jan Kara   mm: remove nr_pag...
364
  				PAGECACHE_TAG_DIRTY))) {
028a63a6e   Jan Kara   f2fs: simplify pa...
365
  		int i;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
366
367
368
  
  		for (i = 0; i < nr_pages; i++) {
  			struct page *page = pvec.pages[i];
203681f65   Jaegeuk Kim   f2fs: fix f2fs_wr...
369

80dd9c0e9   Chao Yu   f2fs: fix incorre...
370
  			if (prev == ULONG_MAX)
6066d8cdb   Jaegeuk Kim   f2fs: merge meta ...
371
372
373
374
375
  				prev = page->index - 1;
  			if (nr_to_write != LONG_MAX && page->index != prev + 1) {
  				pagevec_release(&pvec);
  				goto stop;
  			}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
376
  			lock_page(page);
203681f65   Jaegeuk Kim   f2fs: fix f2fs_wr...
377
378
379
380
381
382
383
384
385
386
  
  			if (unlikely(page->mapping != mapping)) {
  continue_unlock:
  				unlock_page(page);
  				continue;
  			}
  			if (!PageDirty(page)) {
  				/* someone wrote it for us */
  				goto continue_unlock;
  			}
bae0ee7a7   Chao Yu   f2fs: check PageW...
387
  			f2fs_wait_on_page_writeback(page, META, true, true);
fa3d2bdf9   Jaegeuk Kim   f2fs: wait on pag...
388

203681f65   Jaegeuk Kim   f2fs: fix f2fs_wr...
389
390
  			if (!clear_page_dirty_for_io(page))
  				goto continue_unlock;
b0af6d491   Chao Yu   f2fs: add app/fs ...
391
  			if (__f2fs_write_meta_page(page, &wbc, io_type)) {
577e34951   Jaegeuk Kim   f2fs: prevent che...
392
393
394
  				unlock_page(page);
  				break;
  			}
cfb271d48   Chao Yu   f2fs: add unlikel...
395
  			nwritten++;
6066d8cdb   Jaegeuk Kim   f2fs: merge meta ...
396
  			prev = page->index;
cfb271d48   Chao Yu   f2fs: add unlikel...
397
  			if (unlikely(nwritten >= nr_to_write))
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
398
399
400
401
402
  				break;
  		}
  		pagevec_release(&pvec);
  		cond_resched();
  	}
6066d8cdb   Jaegeuk Kim   f2fs: merge meta ...
403
  stop:
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
404
  	if (nwritten)
b9109b0e4   Jaegeuk Kim   f2fs: remove unne...
405
  		f2fs_submit_merged_write(sbi, type);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
406

e9f5b8b8d   Chao Yu   f2fs: enhance IO ...
407
  	blk_finish_plug(&plug);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
408
409
410
411
412
  	return nwritten;
  }
  
  static int f2fs_set_meta_page_dirty(struct page *page)
  {
26c6b8879   Jaegeuk Kim   f2fs: add tracepo...
413
  	trace_f2fs_set_page_dirty(page, META);
237c0790e   Jaegeuk Kim   f2fs: call SetPag...
414
415
  	if (!PageUptodate(page))
  		SetPageUptodate(page);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
416
  	if (!PageDirty(page)) {
b87078ad3   Jaegeuk Kim   Revert "f2fs: int...
417
  		__set_page_dirty_nobuffers(page);
4081363fb   Jaegeuk Kim   f2fs: introduce F...
418
  		inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_META);
240a59156   Chao Yu   f2fs: fix to add ...
419
  		f2fs_set_page_private(page, 0);
9e4ded3f3   Jaegeuk Kim   f2fs: activate f2...
420
  		f2fs_trace_pid(page);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
421
422
423
424
425
426
427
428
429
  		return 1;
  	}
  	return 0;
  }
  
  const struct address_space_operations f2fs_meta_aops = {
  	.writepage	= f2fs_write_meta_page,
  	.writepages	= f2fs_write_meta_pages,
  	.set_page_dirty	= f2fs_set_meta_page_dirty,
487261f39   Chao Yu   f2fs: merge {inva...
430
431
  	.invalidatepage = f2fs_invalidate_page,
  	.releasepage	= f2fs_release_page,
5b7a487cf   Weichao Guo   f2fs: add customi...
432
433
434
  #ifdef CONFIG_MIGRATION
  	.migratepage    = f2fs_migrate_page,
  #endif
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
435
  };
39d787bec   Chao Yu   f2fs: enhance mul...
436
437
  static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino,
  						unsigned int devidx, int type)
953e6cc6b   Jaegeuk Kim   f2fs: punch the c...
438
  {
67298804f   Chao Yu   f2fs: introduce s...
439
  	struct inode_management *im = &sbi->im[type];
80c545055   Jaegeuk Kim   f2fs: use __GFP_N...
440
441
442
  	struct ino_entry *e, *tmp;
  
  	tmp = f2fs_kmem_cache_alloc(ino_entry_slab, GFP_NOFS);
19526d74c   Chao Yu   f2fs: avoid opene...
443

80c545055   Jaegeuk Kim   f2fs: use __GFP_N...
444
  	radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
769ec6e5b   Jaegeuk Kim   f2fs: call radix_...
445

67298804f   Chao Yu   f2fs: introduce s...
446
  	spin_lock(&im->ino_lock);
67298804f   Chao Yu   f2fs: introduce s...
447
  	e = radix_tree_lookup(&im->ino_root, ino);
39efac41f   Jaegeuk Kim   f2fs: use radix_t...
448
  	if (!e) {
80c545055   Jaegeuk Kim   f2fs: use __GFP_N...
449
  		e = tmp;
19526d74c   Chao Yu   f2fs: avoid opene...
450
451
  		if (unlikely(radix_tree_insert(&im->ino_root, ino, e)))
  			f2fs_bug_on(sbi, 1);
39efac41f   Jaegeuk Kim   f2fs: use radix_t...
452
453
  		memset(e, 0, sizeof(struct ino_entry));
  		e->ino = ino;
953e6cc6b   Jaegeuk Kim   f2fs: punch the c...
454

67298804f   Chao Yu   f2fs: introduce s...
455
  		list_add_tail(&e->list, &im->ino_list);
8c402946f   Jaegeuk Kim   f2fs: introduce t...
456
  		if (type != ORPHAN_INO)
67298804f   Chao Yu   f2fs: introduce s...
457
  			im->ino_num++;
39efac41f   Jaegeuk Kim   f2fs: use radix_t...
458
  	}
39d787bec   Chao Yu   f2fs: enhance mul...
459
460
461
  
  	if (type == FLUSH_INO)
  		f2fs_set_bit(devidx, (char *)&e->dirty_device);
67298804f   Chao Yu   f2fs: introduce s...
462
  	spin_unlock(&im->ino_lock);
769ec6e5b   Jaegeuk Kim   f2fs: call radix_...
463
  	radix_tree_preload_end();
80c545055   Jaegeuk Kim   f2fs: use __GFP_N...
464
465
466
  
  	if (e != tmp)
  		kmem_cache_free(ino_entry_slab, tmp);
953e6cc6b   Jaegeuk Kim   f2fs: punch the c...
467
  }
6451e041c   Jaegeuk Kim   f2fs: add infra f...
468
  static void __remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
953e6cc6b   Jaegeuk Kim   f2fs: punch the c...
469
  {
67298804f   Chao Yu   f2fs: introduce s...
470
  	struct inode_management *im = &sbi->im[type];
6451e041c   Jaegeuk Kim   f2fs: add infra f...
471
  	struct ino_entry *e;
953e6cc6b   Jaegeuk Kim   f2fs: punch the c...
472

67298804f   Chao Yu   f2fs: introduce s...
473
474
  	spin_lock(&im->ino_lock);
  	e = radix_tree_lookup(&im->ino_root, ino);
39efac41f   Jaegeuk Kim   f2fs: use radix_t...
475
476
  	if (e) {
  		list_del(&e->list);
67298804f   Chao Yu   f2fs: introduce s...
477
478
479
  		radix_tree_delete(&im->ino_root, ino);
  		im->ino_num--;
  		spin_unlock(&im->ino_lock);
39efac41f   Jaegeuk Kim   f2fs: use radix_t...
480
481
  		kmem_cache_free(ino_entry_slab, e);
  		return;
953e6cc6b   Jaegeuk Kim   f2fs: punch the c...
482
  	}
67298804f   Chao Yu   f2fs: introduce s...
483
  	spin_unlock(&im->ino_lock);
953e6cc6b   Jaegeuk Kim   f2fs: punch the c...
484
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
485
  void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
fff04f90c   Jaegeuk Kim   f2fs: add info of...
486
487
  {
  	/* add new dirty ino entry into list */
39d787bec   Chao Yu   f2fs: enhance mul...
488
  	__add_ino_entry(sbi, ino, 0, type);
fff04f90c   Jaegeuk Kim   f2fs: add info of...
489
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
490
  void f2fs_remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
fff04f90c   Jaegeuk Kim   f2fs: add info of...
491
492
493
494
  {
  	/* remove dirty ino entry from list */
  	__remove_ino_entry(sbi, ino, type);
  }
1f07cc58b   Jack Qiu   f2fs: correct com...
495
  /* mode should be APPEND_INO, UPDATE_INO or TRANS_DIR_INO */
4d57b86dd   Chao Yu   f2fs: clean up sy...
496
  bool f2fs_exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode)
fff04f90c   Jaegeuk Kim   f2fs: add info of...
497
  {
67298804f   Chao Yu   f2fs: introduce s...
498
  	struct inode_management *im = &sbi->im[mode];
fff04f90c   Jaegeuk Kim   f2fs: add info of...
499
  	struct ino_entry *e;
67298804f   Chao Yu   f2fs: introduce s...
500
501
502
503
  
  	spin_lock(&im->ino_lock);
  	e = radix_tree_lookup(&im->ino_root, ino);
  	spin_unlock(&im->ino_lock);
fff04f90c   Jaegeuk Kim   f2fs: add info of...
504
505
  	return e ? true : false;
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
506
  void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all)
fff04f90c   Jaegeuk Kim   f2fs: add info of...
507
508
509
  {
  	struct ino_entry *e, *tmp;
  	int i;
39d787bec   Chao Yu   f2fs: enhance mul...
510
  	for (i = all ? ORPHAN_INO : APPEND_INO; i < MAX_INO_ENTRY; i++) {
67298804f   Chao Yu   f2fs: introduce s...
511
512
513
514
  		struct inode_management *im = &sbi->im[i];
  
  		spin_lock(&im->ino_lock);
  		list_for_each_entry_safe(e, tmp, &im->ino_list, list) {
fff04f90c   Jaegeuk Kim   f2fs: add info of...
515
  			list_del(&e->list);
67298804f   Chao Yu   f2fs: introduce s...
516
  			radix_tree_delete(&im->ino_root, e->ino);
fff04f90c   Jaegeuk Kim   f2fs: add info of...
517
  			kmem_cache_free(ino_entry_slab, e);
67298804f   Chao Yu   f2fs: introduce s...
518
  			im->ino_num--;
fff04f90c   Jaegeuk Kim   f2fs: add info of...
519
  		}
67298804f   Chao Yu   f2fs: introduce s...
520
  		spin_unlock(&im->ino_lock);
fff04f90c   Jaegeuk Kim   f2fs: add info of...
521
522
  	}
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
523
  void f2fs_set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
39d787bec   Chao Yu   f2fs: enhance mul...
524
525
526
527
  					unsigned int devidx, int type)
  {
  	__add_ino_entry(sbi, ino, devidx, type);
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
528
  bool f2fs_is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
39d787bec   Chao Yu   f2fs: enhance mul...
529
530
531
532
533
534
535
536
537
538
539
540
541
  					unsigned int devidx, int type)
  {
  	struct inode_management *im = &sbi->im[type];
  	struct ino_entry *e;
  	bool is_dirty = false;
  
  	spin_lock(&im->ino_lock);
  	e = radix_tree_lookup(&im->ino_root, ino);
  	if (e && f2fs_test_bit(devidx, (char *)&e->dirty_device))
  		is_dirty = true;
  	spin_unlock(&im->ino_lock);
  	return is_dirty;
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
542
  int f2fs_acquire_orphan_inode(struct f2fs_sb_info *sbi)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
543
  {
67298804f   Chao Yu   f2fs: introduce s...
544
  	struct inode_management *im = &sbi->im[ORPHAN_INO];
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
545
  	int err = 0;
67298804f   Chao Yu   f2fs: introduce s...
546
  	spin_lock(&im->ino_lock);
cb78942b8   Jaegeuk Kim   f2fs: inject ENOS...
547

1ecc0c5c5   Chao Yu   f2fs: support con...
548
  	if (time_to_inject(sbi, FAULT_ORPHAN)) {
cb78942b8   Jaegeuk Kim   f2fs: inject ENOS...
549
  		spin_unlock(&im->ino_lock);
c45d6002f   Chao Yu   f2fs: show f2fs i...
550
  		f2fs_show_injection_info(sbi, FAULT_ORPHAN);
cb78942b8   Jaegeuk Kim   f2fs: inject ENOS...
551
552
  		return -ENOSPC;
  	}
7fa750a16   Arnd Bergmann   f2fs: rework faul...
553

67298804f   Chao Yu   f2fs: introduce s...
554
  	if (unlikely(im->ino_num >= sbi->max_orphans))
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
555
  		err = -ENOSPC;
cbd56e7d2   Jaegeuk Kim   f2fs: fix handlin...
556
  	else
67298804f   Chao Yu   f2fs: introduce s...
557
558
  		im->ino_num++;
  	spin_unlock(&im->ino_lock);
0d47c1adc   Gu Zheng   f2fs: convert max...
559

127e670ab   Jaegeuk Kim   f2fs: add checkpo...
560
561
  	return err;
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
562
  void f2fs_release_orphan_inode(struct f2fs_sb_info *sbi)
cbd56e7d2   Jaegeuk Kim   f2fs: fix handlin...
563
  {
67298804f   Chao Yu   f2fs: introduce s...
564
565
566
567
568
569
  	struct inode_management *im = &sbi->im[ORPHAN_INO];
  
  	spin_lock(&im->ino_lock);
  	f2fs_bug_on(sbi, im->ino_num == 0);
  	im->ino_num--;
  	spin_unlock(&im->ino_lock);
cbd56e7d2   Jaegeuk Kim   f2fs: fix handlin...
570
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
571
  void f2fs_add_orphan_inode(struct inode *inode)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
572
  {
39efac41f   Jaegeuk Kim   f2fs: use radix_t...
573
  	/* add new orphan ino entry into list */
39d787bec   Chao Yu   f2fs: enhance mul...
574
  	__add_ino_entry(F2FS_I_SB(inode), inode->i_ino, 0, ORPHAN_INO);
4d57b86dd   Chao Yu   f2fs: clean up sy...
575
  	f2fs_update_inode_page(inode);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
576
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
577
  void f2fs_remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
578
  {
953e6cc6b   Jaegeuk Kim   f2fs: punch the c...
579
  	/* remove orphan entry from orphan list */
6451e041c   Jaegeuk Kim   f2fs: add infra f...
580
  	__remove_ino_entry(sbi, ino, ORPHAN_INO);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
581
  }
8c14bfade   Chao Yu   f2fs: handle erro...
582
  static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
583
  {
8c14bfade   Chao Yu   f2fs: handle erro...
584
  	struct inode *inode;
5905f9afa   Jaegeuk Kim   f2fs: handle erro...
585
  	struct node_info ni;
76a45e3c4   Chao Yu   f2fs: don't acqui...
586
  	int err;
8c14bfade   Chao Yu   f2fs: handle erro...
587

5905f9afa   Jaegeuk Kim   f2fs: handle erro...
588
  	inode = f2fs_iget_retry(sbi->sb, ino);
8c14bfade   Chao Yu   f2fs: handle erro...
589
590
591
592
593
594
595
596
  	if (IS_ERR(inode)) {
  		/*
  		 * there should be a bug that we can't find the entry
  		 * to orphan inode.
  		 */
  		f2fs_bug_on(sbi, PTR_ERR(inode) == -ENOENT);
  		return PTR_ERR(inode);
  	}
0f9ec2a8f   Jaegeuk Kim   f2fs: handle quot...
597
  	err = dquot_initialize(inode);
a515d12f1   Sheng Yong   f2fs: remove dupl...
598
599
  	if (err) {
  		iput(inode);
0f9ec2a8f   Jaegeuk Kim   f2fs: handle quot...
600
  		goto err_out;
a515d12f1   Sheng Yong   f2fs: remove dupl...
601
  	}
0f9ec2a8f   Jaegeuk Kim   f2fs: handle quot...
602

127e670ab   Jaegeuk Kim   f2fs: add checkpo...
603
604
605
606
  	clear_nlink(inode);
  
  	/* truncate all the data during iput */
  	iput(inode);
5905f9afa   Jaegeuk Kim   f2fs: handle erro...
607

7735730d3   Chao Yu   f2fs: fix to prop...
608
609
610
  	err = f2fs_get_node_info(sbi, ino, &ni);
  	if (err)
  		goto err_out;
5905f9afa   Jaegeuk Kim   f2fs: handle erro...
611
612
613
  
  	/* ENOMEM was fully retried in f2fs_evict_inode. */
  	if (ni.blk_addr != NULL_ADDR) {
0f9ec2a8f   Jaegeuk Kim   f2fs: handle quot...
614
615
  		err = -EIO;
  		goto err_out;
5905f9afa   Jaegeuk Kim   f2fs: handle erro...
616
  	}
8c14bfade   Chao Yu   f2fs: handle erro...
617
  	return 0;
0f9ec2a8f   Jaegeuk Kim   f2fs: handle quot...
618
619
620
  
  err_out:
  	set_sbi_flag(sbi, SBI_NEED_FSCK);
dcbb4c10e   Joe Perches   f2fs: introduce f...
621
622
  	f2fs_warn(sbi, "%s: orphan failed (ino=%x), run fsck to fix.",
  		  __func__, ino);
0f9ec2a8f   Jaegeuk Kim   f2fs: handle quot...
623
  	return err;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
624
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
625
  int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
626
  {
3c6429857   Wanpeng Li   f2fs: fix the num...
627
  	block_t start_blk, orphan_blocks, i, j;
4b2414d04   Chao Yu   f2fs: support jou...
628
629
  	unsigned int s_flags = sbi->sb->s_flags;
  	int err = 0;
ea6767337   Jaegeuk Kim   f2fs: support quo...
630
631
632
  #ifdef CONFIG_QUOTA
  	int quota_enabled;
  #endif
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
633

aaec2b1d1   Chao Yu   f2fs: introduce c...
634
  	if (!is_set_ckpt_flags(sbi, CP_ORPHAN_PRESENT_FLAG))
8c14bfade   Chao Yu   f2fs: handle erro...
635
  		return 0;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
636

b61af314c   Chao Yu   f2fs: fix to skip...
637
  	if (bdev_read_only(sbi->sb->s_bdev)) {
dcbb4c10e   Joe Perches   f2fs: introduce f...
638
  		f2fs_info(sbi, "write access unavailable, skipping orphan cleanup");
b61af314c   Chao Yu   f2fs: fix to skip...
639
640
  		return 0;
  	}
1751e8a6c   Linus Torvalds   Rename superblock...
641
  	if (s_flags & SB_RDONLY) {
dcbb4c10e   Joe Perches   f2fs: introduce f...
642
  		f2fs_info(sbi, "orphan cleanup on readonly fs");
1751e8a6c   Linus Torvalds   Rename superblock...
643
  		sbi->sb->s_flags &= ~SB_RDONLY;
4b2414d04   Chao Yu   f2fs: support jou...
644
645
646
647
  	}
  
  #ifdef CONFIG_QUOTA
  	/* Needed for iput() to work correctly and not trash data */
1751e8a6c   Linus Torvalds   Rename superblock...
648
  	sbi->sb->s_flags |= SB_ACTIVE;
ea6767337   Jaegeuk Kim   f2fs: support quo...
649

76cf05d79   Sheng Yong   f2fs: quota: fix ...
650
651
652
653
  	/*
  	 * Turn on quotas which were not enabled for read-only mounts if
  	 * filesystem has quota feature, so that they are updated correctly.
  	 */
1751e8a6c   Linus Torvalds   Rename superblock...
654
  	quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY);
4b2414d04   Chao Yu   f2fs: support jou...
655
  #endif
551414861   Wanpeng Li   f2fs: introduce m...
656
  	start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi);
3c6429857   Wanpeng Li   f2fs: fix the num...
657
  	orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
658

4d57b86dd   Chao Yu   f2fs: clean up sy...
659
  	f2fs_ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true);
662befda2   Chao Yu   f2fs: introduce r...
660

3c6429857   Wanpeng Li   f2fs: fix the num...
661
  	for (i = 0; i < orphan_blocks; i++) {
7735730d3   Chao Yu   f2fs: fix to prop...
662
  		struct page *page;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
663
  		struct f2fs_orphan_block *orphan_blk;
7735730d3   Chao Yu   f2fs: fix to prop...
664
665
666
667
668
  		page = f2fs_get_meta_page(sbi, start_blk + i);
  		if (IS_ERR(page)) {
  			err = PTR_ERR(page);
  			goto out;
  		}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
669
670
671
  		orphan_blk = (struct f2fs_orphan_block *)page_address(page);
  		for (j = 0; j < le32_to_cpu(orphan_blk->entry_count); j++) {
  			nid_t ino = le32_to_cpu(orphan_blk->ino[j]);
8c14bfade   Chao Yu   f2fs: handle erro...
672
673
674
  			err = recover_orphan_inode(sbi, ino);
  			if (err) {
  				f2fs_put_page(page, 1);
4b2414d04   Chao Yu   f2fs: support jou...
675
  				goto out;
8c14bfade   Chao Yu   f2fs: handle erro...
676
  			}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
677
678
679
680
  		}
  		f2fs_put_page(page, 1);
  	}
  	/* clear Orphan Flag */
aaec2b1d1   Chao Yu   f2fs: introduce c...
681
  	clear_ckpt_flags(sbi, CP_ORPHAN_PRESENT_FLAG);
4b2414d04   Chao Yu   f2fs: support jou...
682
  out:
1378752b9   Chao Yu   f2fs: fix to flus...
683
  	set_sbi_flag(sbi, SBI_IS_RECOVERED);
4b2414d04   Chao Yu   f2fs: support jou...
684
685
  #ifdef CONFIG_QUOTA
  	/* Turn quotas off */
ea6767337   Jaegeuk Kim   f2fs: support quo...
686
687
  	if (quota_enabled)
  		f2fs_quota_off_umount(sbi->sb);
4b2414d04   Chao Yu   f2fs: support jou...
688
  #endif
1751e8a6c   Linus Torvalds   Rename superblock...
689
  	sbi->sb->s_flags = s_flags; /* Restore SB_RDONLY status */
4b2414d04   Chao Yu   f2fs: support jou...
690
691
  
  	return err;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
692
693
694
695
  }
  
  static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk)
  {
502c6e0bc   Gu Zheng   f2fs: simplify wr...
696
  	struct list_head *head;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
697
  	struct f2fs_orphan_block *orphan_blk = NULL;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
698
  	unsigned int nentries = 0;
bd936f840   Chao Yu   f2fs: cleanup wri...
699
  	unsigned short index = 1;
8c402946f   Jaegeuk Kim   f2fs: introduce t...
700
  	unsigned short orphan_blocks;
4531929e3   Gu Zheng   f2fs: move grabin...
701
  	struct page *page = NULL;
6451e041c   Jaegeuk Kim   f2fs: add infra f...
702
  	struct ino_entry *orphan = NULL;
67298804f   Chao Yu   f2fs: introduce s...
703
  	struct inode_management *im = &sbi->im[ORPHAN_INO];
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
704

67298804f   Chao Yu   f2fs: introduce s...
705
  	orphan_blocks = GET_ORPHAN_BLOCKS(im->ino_num);
8c402946f   Jaegeuk Kim   f2fs: introduce t...
706

d6c67a4fe   Jaegeuk Kim   f2fs: revmove spi...
707
708
709
710
711
  	/*
  	 * we don't need to do spin_lock(&im->ino_lock) here, since all the
  	 * orphan inode operations are covered under f2fs_lock_op().
  	 * And, spin_lock should be avoided due to page operations below.
  	 */
67298804f   Chao Yu   f2fs: introduce s...
712
  	head = &im->ino_list;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
713
714
  
  	/* loop for each orphan inode entry and write them in Jornal block */
502c6e0bc   Gu Zheng   f2fs: simplify wr...
715
716
  	list_for_each_entry(orphan, head, list) {
  		if (!page) {
4d57b86dd   Chao Yu   f2fs: clean up sy...
717
  			page = f2fs_grab_meta_page(sbi, start_blk++);
502c6e0bc   Gu Zheng   f2fs: simplify wr...
718
719
720
721
  			orphan_blk =
  				(struct f2fs_orphan_block *)page_address(page);
  			memset(orphan_blk, 0, sizeof(*orphan_blk));
  		}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
722

367955679   Gu Zheng   f2fs: fix a poten...
723
  		orphan_blk->ino[nentries++] = cpu_to_le32(orphan->ino);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
724

367955679   Gu Zheng   f2fs: fix a poten...
725
  		if (nentries == F2FS_ORPHANS_PER_BLOCK) {
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
726
727
728
729
730
731
732
733
734
735
736
  			/*
  			 * an orphan block is full of 1020 entries,
  			 * then we need to flush current orphan blocks
  			 * and bring another one in memory
  			 */
  			orphan_blk->blk_addr = cpu_to_le16(index);
  			orphan_blk->blk_count = cpu_to_le16(orphan_blocks);
  			orphan_blk->entry_count = cpu_to_le32(nentries);
  			set_page_dirty(page);
  			f2fs_put_page(page, 1);
  			index++;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
737
738
739
  			nentries = 0;
  			page = NULL;
  		}
502c6e0bc   Gu Zheng   f2fs: simplify wr...
740
  	}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
741

502c6e0bc   Gu Zheng   f2fs: simplify wr...
742
743
744
745
746
747
  	if (page) {
  		orphan_blk->blk_addr = cpu_to_le16(index);
  		orphan_blk->blk_count = cpu_to_le16(orphan_blocks);
  		orphan_blk->entry_count = cpu_to_le32(nentries);
  		set_page_dirty(page);
  		f2fs_put_page(page, 1);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
748
  	}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
749
  }
d7eb8f1cd   Chao Yu   f2fs: allow unfix...
750
751
752
753
754
755
756
757
758
759
760
761
762
763
  static __u32 f2fs_checkpoint_chksum(struct f2fs_sb_info *sbi,
  						struct f2fs_checkpoint *ckpt)
  {
  	unsigned int chksum_ofs = le32_to_cpu(ckpt->checksum_offset);
  	__u32 chksum;
  
  	chksum = f2fs_crc32(sbi, ckpt, chksum_ofs);
  	if (chksum_ofs < CP_CHKSUM_OFFSET) {
  		chksum_ofs += sizeof(chksum);
  		chksum = f2fs_chksum(sbi, chksum, (__u8 *)ckpt + chksum_ofs,
  						F2FS_BLKSIZE - chksum_ofs);
  	}
  	return chksum;
  }
fc0065adb   Tiezhu Yang   f2fs: introduce g...
764
765
766
  static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr,
  		struct f2fs_checkpoint **cp_block, struct page **cp_page,
  		unsigned long long *version)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
767
  {
fc0065adb   Tiezhu Yang   f2fs: introduce g...
768
  	size_t crc_offset = 0;
d7eb8f1cd   Chao Yu   f2fs: allow unfix...
769
  	__u32 crc;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
770

4d57b86dd   Chao Yu   f2fs: clean up sy...
771
  	*cp_page = f2fs_get_meta_page(sbi, cp_addr);
7735730d3   Chao Yu   f2fs: fix to prop...
772
773
  	if (IS_ERR(*cp_page))
  		return PTR_ERR(*cp_page);
fc0065adb   Tiezhu Yang   f2fs: introduce g...
774
  	*cp_block = (struct f2fs_checkpoint *)page_address(*cp_page);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
775

fc0065adb   Tiezhu Yang   f2fs: introduce g...
776
  	crc_offset = le32_to_cpu((*cp_block)->checksum_offset);
d7eb8f1cd   Chao Yu   f2fs: allow unfix...
777
778
  	if (crc_offset < CP_MIN_CHKSUM_OFFSET ||
  			crc_offset > CP_CHKSUM_OFFSET) {
d3f07c049   Chao Yu   f2fs: fix invalid...
779
  		f2fs_put_page(*cp_page, 1);
dcbb4c10e   Joe Perches   f2fs: introduce f...
780
  		f2fs_warn(sbi, "invalid crc_offset: %zu", crc_offset);
fc0065adb   Tiezhu Yang   f2fs: introduce g...
781
782
  		return -EINVAL;
  	}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
783

d7eb8f1cd   Chao Yu   f2fs: allow unfix...
784
785
  	crc = f2fs_checkpoint_chksum(sbi, *cp_block);
  	if (crc != cur_cp_crc(*cp_block)) {
d3f07c049   Chao Yu   f2fs: fix invalid...
786
  		f2fs_put_page(*cp_page, 1);
dcbb4c10e   Joe Perches   f2fs: introduce f...
787
  		f2fs_warn(sbi, "invalid crc value");
fc0065adb   Tiezhu Yang   f2fs: introduce g...
788
789
  		return -EINVAL;
  	}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
790

fc0065adb   Tiezhu Yang   f2fs: introduce g...
791
792
793
  	*version = cur_cp_version(*cp_block);
  	return 0;
  }
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
794

fc0065adb   Tiezhu Yang   f2fs: introduce g...
795
796
797
798
799
800
801
  static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
  				block_t cp_addr, unsigned long long *version)
  {
  	struct page *cp_page_1 = NULL, *cp_page_2 = NULL;
  	struct f2fs_checkpoint *cp_block = NULL;
  	unsigned long long cur_version = 0, pre_version = 0;
  	int err;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
802

fc0065adb   Tiezhu Yang   f2fs: introduce g...
803
804
805
  	err = get_checkpoint_version(sbi, cp_addr, &cp_block,
  					&cp_page_1, version);
  	if (err)
d3f07c049   Chao Yu   f2fs: fix invalid...
806
  		return NULL;
c9b60788f   Chao Yu   f2fs: fix to do s...
807
808
809
  
  	if (le32_to_cpu(cp_block->cp_pack_total_block_count) >
  					sbi->blocks_per_seg) {
dcbb4c10e   Joe Perches   f2fs: introduce f...
810
811
  		f2fs_warn(sbi, "invalid cp_pack_total_block_count:%u",
  			  le32_to_cpu(cp_block->cp_pack_total_block_count));
d3f07c049   Chao Yu   f2fs: fix invalid...
812
  		goto invalid_cp;
c9b60788f   Chao Yu   f2fs: fix to do s...
813
  	}
fc0065adb   Tiezhu Yang   f2fs: introduce g...
814
  	pre_version = *version;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
815

fc0065adb   Tiezhu Yang   f2fs: introduce g...
816
817
818
819
  	cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1;
  	err = get_checkpoint_version(sbi, cp_addr, &cp_block,
  					&cp_page_2, version);
  	if (err)
d3f07c049   Chao Yu   f2fs: fix invalid...
820
  		goto invalid_cp;
fc0065adb   Tiezhu Yang   f2fs: introduce g...
821
  	cur_version = *version;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
822
823
824
825
826
827
  
  	if (cur_version == pre_version) {
  		*version = cur_version;
  		f2fs_put_page(cp_page_2, 1);
  		return cp_page_1;
  	}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
828
  	f2fs_put_page(cp_page_2, 1);
d3f07c049   Chao Yu   f2fs: fix invalid...
829
  invalid_cp:
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
830
831
832
  	f2fs_put_page(cp_page_1, 1);
  	return NULL;
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
833
  int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
834
835
836
837
838
839
840
  {
  	struct f2fs_checkpoint *cp_block;
  	struct f2fs_super_block *fsb = sbi->raw_super;
  	struct page *cp1, *cp2, *cur_page;
  	unsigned long blk_size = sbi->blocksize;
  	unsigned long long cp1_version = 0, cp2_version = 0;
  	unsigned long long cp_start_blk_no;
551414861   Wanpeng Li   f2fs: introduce m...
841
  	unsigned int cp_blks = 1 + __cp_payload(sbi);
1dbe41521   Changman Lee   f2fs: large volum...
842
843
  	block_t cp_blk_no;
  	int i;
10f966bbf   Chao Yu   f2fs: use generic...
844
  	int err;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
845

0b6d4ca04   Eric Biggers   f2fs: don't retur...
846
847
  	sbi->ckpt = f2fs_kvzalloc(sbi, array_size(blk_size, cp_blks),
  				  GFP_KERNEL);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
848
849
850
851
  	if (!sbi->ckpt)
  		return -ENOMEM;
  	/*
  	 * Finding out valid cp block involves read both
7a88ddb56   Chao Yu   f2fs: fix inconsi...
852
  	 * sets( cp pack 1 and cp pack 2)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
853
854
855
856
857
  	 */
  	cp_start_blk_no = le32_to_cpu(fsb->cp_blkaddr);
  	cp1 = validate_checkpoint(sbi, cp_start_blk_no, &cp1_version);
  
  	/* The second checkpoint pack should start at the next segment */
f9a4e6df5   Jaegeuk Kim   f2fs: bug fix on ...
858
859
  	cp_start_blk_no += ((unsigned long long)1) <<
  				le32_to_cpu(fsb->log_blocks_per_seg);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
860
861
862
863
864
865
866
867
868
869
870
871
  	cp2 = validate_checkpoint(sbi, cp_start_blk_no, &cp2_version);
  
  	if (cp1 && cp2) {
  		if (ver_after(cp2_version, cp1_version))
  			cur_page = cp2;
  		else
  			cur_page = cp1;
  	} else if (cp1) {
  		cur_page = cp1;
  	} else if (cp2) {
  		cur_page = cp2;
  	} else {
10f966bbf   Chao Yu   f2fs: use generic...
872
  		err = -EFSCORRUPTED;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
873
874
875
876
877
  		goto fail_no_cp;
  	}
  
  	cp_block = (struct f2fs_checkpoint *)page_address(cur_page);
  	memcpy(sbi->ckpt, cp_block, blk_size);
8508e44ae   Jaegeuk Kim   f2fs: fix to dete...
878
879
880
881
  	if (cur_page == cp1)
  		sbi->cur_cp_pack = 1;
  	else
  		sbi->cur_cp_pack = 2;
984ec63c5   Shawn Lin   f2fs: move sanity...
882

e494c2f99   Chao Yu   f2fs: fix to do s...
883
  	/* Sanity checking of checkpoint */
10f966bbf   Chao Yu   f2fs: use generic...
884
885
  	if (f2fs_sanity_check_ckpt(sbi)) {
  		err = -EFSCORRUPTED;
e494c2f99   Chao Yu   f2fs: fix to do s...
886
  		goto free_fail_no_cp;
10f966bbf   Chao Yu   f2fs: use generic...
887
  	}
e494c2f99   Chao Yu   f2fs: fix to do s...
888

1dbe41521   Changman Lee   f2fs: large volum...
889
890
891
892
893
894
895
896
897
898
  	if (cp_blks <= 1)
  		goto done;
  
  	cp_blk_no = le32_to_cpu(fsb->cp_blkaddr);
  	if (cur_page == cp2)
  		cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg);
  
  	for (i = 1; i < cp_blks; i++) {
  		void *sit_bitmap_ptr;
  		unsigned char *ckpt = (unsigned char *)sbi->ckpt;
4d57b86dd   Chao Yu   f2fs: clean up sy...
899
  		cur_page = f2fs_get_meta_page(sbi, cp_blk_no + i);
10f966bbf   Chao Yu   f2fs: use generic...
900
901
  		if (IS_ERR(cur_page)) {
  			err = PTR_ERR(cur_page);
7735730d3   Chao Yu   f2fs: fix to prop...
902
  			goto free_fail_no_cp;
10f966bbf   Chao Yu   f2fs: use generic...
903
  		}
1dbe41521   Changman Lee   f2fs: large volum...
904
905
906
907
908
  		sit_bitmap_ptr = page_address(cur_page);
  		memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size);
  		f2fs_put_page(cur_page, 1);
  	}
  done:
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
909
910
911
  	f2fs_put_page(cp1, 1);
  	f2fs_put_page(cp2, 1);
  	return 0;
a2125ff7d   Jaegeuk Kim   f2fs: free meta p...
912
913
914
  free_fail_no_cp:
  	f2fs_put_page(cp1, 1);
  	f2fs_put_page(cp2, 1);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
915
  fail_no_cp:
5222595d0   Jaegeuk Kim   f2fs: use kvmallo...
916
  	kvfree(sbi->ckpt);
10f966bbf   Chao Yu   f2fs: use generic...
917
  	return err;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
918
  }
c227f9127   Chao Yu   f2fs: record dirt...
919
  static void __add_dirty_inode(struct inode *inode, enum inode_type type)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
920
  {
4081363fb   Jaegeuk Kim   f2fs: introduce F...
921
  	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
c227f9127   Chao Yu   f2fs: record dirt...
922
  	int flag = (type == DIR_INODE) ? FI_DIRTY_DIR : FI_DIRTY_FILE;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
923

91942321e   Jaegeuk Kim   f2fs: use inode p...
924
  	if (is_inode_flag_set(inode, flag))
2710fd7e0   Chao Yu   f2fs: introduce d...
925
  		return;
2d7b822ad   Chao Yu   f2fs: use list_fo...
926

91942321e   Jaegeuk Kim   f2fs: use inode p...
927
  	set_inode_flag(inode, flag);
99f4b917b   Chao Yu   f2fs: don't track...
928
929
930
  	if (!f2fs_is_volatile_file(inode))
  		list_add_tail(&F2FS_I(inode)->dirty_list,
  						&sbi->inode_list[type]);
33fbd5100   Chao Yu   f2fs: stat dirty ...
931
  	stat_inc_dirty_inode(sbi, type);
5deb82671   Jaegeuk Kim   f2fs: fix iget/ip...
932
  }
c227f9127   Chao Yu   f2fs: record dirt...
933
  static void __remove_dirty_inode(struct inode *inode, enum inode_type type)
6ad7609a1   Chao Yu   f2fs: introduce _...
934
  {
c227f9127   Chao Yu   f2fs: record dirt...
935
  	int flag = (type == DIR_INODE) ? FI_DIRTY_DIR : FI_DIRTY_FILE;
6ad7609a1   Chao Yu   f2fs: introduce _...
936

91942321e   Jaegeuk Kim   f2fs: use inode p...
937
  	if (get_dirty_pages(inode) || !is_inode_flag_set(inode, flag))
6ad7609a1   Chao Yu   f2fs: introduce _...
938
  		return;
91942321e   Jaegeuk Kim   f2fs: use inode p...
939
940
  	list_del_init(&F2FS_I(inode)->dirty_list);
  	clear_inode_flag(inode, flag);
33fbd5100   Chao Yu   f2fs: stat dirty ...
941
  	stat_dec_dirty_inode(F2FS_I_SB(inode), type);
6ad7609a1   Chao Yu   f2fs: introduce _...
942
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
943
  void f2fs_update_dirty_page(struct inode *inode, struct page *page)
5deb82671   Jaegeuk Kim   f2fs: fix iget/ip...
944
  {
4081363fb   Jaegeuk Kim   f2fs: introduce F...
945
  	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
c227f9127   Chao Yu   f2fs: record dirt...
946
  	enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE;
5deb82671   Jaegeuk Kim   f2fs: fix iget/ip...
947

5ac9f36fc   Chao Yu   f2fs: fix to reco...
948
949
  	if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) &&
  			!S_ISLNK(inode->i_mode))
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
950
  		return;
7bd59381c   Gu Zheng   f2fs: introduce f...
951

1c4bf7630   Jaegeuk Kim   Revert "f2fs: no ...
952
953
  	spin_lock(&sbi->inode_lock[type]);
  	if (type != FILE_INODE || test_opt(sbi, DATA_FLUSH))
10aa97c37   Jaegeuk Kim   f2fs: manipulate ...
954
  		__add_dirty_inode(inode, type);
b951a4ec1   Yunlei He   f2fs: no need inc...
955
  	inode_inc_dirty_pages(inode);
1c4bf7630   Jaegeuk Kim   Revert "f2fs: no ...
956
  	spin_unlock(&sbi->inode_lock[type]);
240a59156   Chao Yu   f2fs: fix to add ...
957
  	f2fs_set_page_private(page, 0);
9e4ded3f3   Jaegeuk Kim   f2fs: activate f2...
958
  	f2fs_trace_pid(page);
5deb82671   Jaegeuk Kim   f2fs: fix iget/ip...
959
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
960
  void f2fs_remove_dirty_inode(struct inode *inode)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
961
  {
4081363fb   Jaegeuk Kim   f2fs: introduce F...
962
  	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
c227f9127   Chao Yu   f2fs: record dirt...
963
  	enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
964

c227f9127   Chao Yu   f2fs: record dirt...
965
966
  	if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) &&
  			!S_ISLNK(inode->i_mode))
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
967
  		return;
10aa97c37   Jaegeuk Kim   f2fs: manipulate ...
968
969
  	if (type == FILE_INODE && !test_opt(sbi, DATA_FLUSH))
  		return;
c227f9127   Chao Yu   f2fs: record dirt...
970
971
972
  	spin_lock(&sbi->inode_lock[type]);
  	__remove_dirty_inode(inode, type);
  	spin_unlock(&sbi->inode_lock[type]);
74d0b917e   Jaegeuk Kim   f2fs: fix BUG_ON ...
973
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
974
  int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
975
  {
ce3b7d80e   Gu Zheng   f2fs: move the li...
976
  	struct list_head *head;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
977
  	struct inode *inode;
2710fd7e0   Chao Yu   f2fs: introduce d...
978
  	struct f2fs_inode_info *fi;
4cf185379   Chao Yu   f2fs: add a trace...
979
  	bool is_dir = (type == DIR_INODE);
4db08d016   Jaegeuk Kim   f2fs: avoid cpu l...
980
  	unsigned long ino = 0;
4cf185379   Chao Yu   f2fs: add a trace...
981
982
983
984
  
  	trace_f2fs_sync_dirty_inodes_enter(sbi->sb, is_dir,
  				get_pages(sbi, is_dir ?
  				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA));
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
985
  retry:
9b6648228   Zhang Qilong   f2fs: add trace e...
986
987
988
989
  	if (unlikely(f2fs_cp_error(sbi))) {
  		trace_f2fs_sync_dirty_inodes_exit(sbi->sb, is_dir,
  				get_pages(sbi, is_dir ?
  				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA));
6d5a1495e   Chao Yu   f2fs: let user be...
990
  		return -EIO;
9b6648228   Zhang Qilong   f2fs: add trace e...
991
  	}
af41d3ee0   Jaegeuk Kim   f2fs: avoid infin...
992

c227f9127   Chao Yu   f2fs: record dirt...
993
  	spin_lock(&sbi->inode_lock[type]);
ce3b7d80e   Gu Zheng   f2fs: move the li...
994

c227f9127   Chao Yu   f2fs: record dirt...
995
  	head = &sbi->inode_list[type];
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
996
  	if (list_empty(head)) {
c227f9127   Chao Yu   f2fs: record dirt...
997
  		spin_unlock(&sbi->inode_lock[type]);
4cf185379   Chao Yu   f2fs: add a trace...
998
999
1000
  		trace_f2fs_sync_dirty_inodes_exit(sbi->sb, is_dir,
  				get_pages(sbi, is_dir ?
  				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA));
6d5a1495e   Chao Yu   f2fs: let user be...
1001
  		return 0;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1002
  	}
939afa943   Chao Yu   f2fs: clean up wi...
1003
  	fi = list_first_entry(head, struct f2fs_inode_info, dirty_list);
2710fd7e0   Chao Yu   f2fs: introduce d...
1004
  	inode = igrab(&fi->vfs_inode);
c227f9127   Chao Yu   f2fs: record dirt...
1005
  	spin_unlock(&sbi->inode_lock[type]);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1006
  	if (inode) {
4db08d016   Jaegeuk Kim   f2fs: avoid cpu l...
1007
  		unsigned long cur_ino = inode->i_ino;
186857c5a   Chao Yu   f2fs: fix potenti...
1008
  		F2FS_I(inode)->cp_task = current;
b0af6d491   Chao Yu   f2fs: add app/fs ...
1009

87d6f8909   Jaegeuk Kim   f2fs: avoid small...
1010
  		filemap_fdatawrite(inode->i_mapping);
b0af6d491   Chao Yu   f2fs: add app/fs ...
1011

186857c5a   Chao Yu   f2fs: fix potenti...
1012
  		F2FS_I(inode)->cp_task = NULL;
b0af6d491   Chao Yu   f2fs: add app/fs ...
1013

127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1014
  		iput(inode);
4db08d016   Jaegeuk Kim   f2fs: avoid cpu l...
1015
  		/* We need to give cpu to another writers. */
2a63531a6   Yunlei He   f2fs: fix a hungt...
1016
  		if (ino == cur_ino)
4db08d016   Jaegeuk Kim   f2fs: avoid cpu l...
1017
  			cond_resched();
2a63531a6   Yunlei He   f2fs: fix a hungt...
1018
  		else
4db08d016   Jaegeuk Kim   f2fs: avoid cpu l...
1019
  			ino = cur_ino;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1020
1021
1022
1023
1024
  	} else {
  		/*
  		 * We should submit bio, since it exists several
  		 * wribacking dentry pages in the freeing inode.
  		 */
b9109b0e4   Jaegeuk Kim   f2fs: remove unne...
1025
  		f2fs_submit_merged_write(sbi, DATA);
7ecebe5e0   Sebastian Andrzej Siewior   f2fs: add cond_re...
1026
  		cond_resched();
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1027
1028
1029
  	}
  	goto retry;
  }
0f18b462b   Jaegeuk Kim   f2fs: flush inode...
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
  int f2fs_sync_inode_meta(struct f2fs_sb_info *sbi)
  {
  	struct list_head *head = &sbi->inode_list[DIRTY_META];
  	struct inode *inode;
  	struct f2fs_inode_info *fi;
  	s64 total = get_pages(sbi, F2FS_DIRTY_IMETA);
  
  	while (total--) {
  		if (unlikely(f2fs_cp_error(sbi)))
  			return -EIO;
  
  		spin_lock(&sbi->inode_lock[DIRTY_META]);
  		if (list_empty(head)) {
  			spin_unlock(&sbi->inode_lock[DIRTY_META]);
  			return 0;
  		}
939afa943   Chao Yu   f2fs: clean up wi...
1046
  		fi = list_first_entry(head, struct f2fs_inode_info,
0f18b462b   Jaegeuk Kim   f2fs: flush inode...
1047
1048
1049
1050
  							gdirty_list);
  		inode = igrab(&fi->vfs_inode);
  		spin_unlock(&sbi->inode_lock[DIRTY_META]);
  		if (inode) {
18340edc8   Jaegeuk Kim   f2fs: make clean ...
1051
1052
1053
1054
  			sync_inode_metadata(inode, 0);
  
  			/* it's on eviction */
  			if (is_inode_flag_set(inode, FI_DIRTY_INODE))
4d57b86dd   Chao Yu   f2fs: clean up sy...
1055
  				f2fs_update_inode_page(inode);
0f18b462b   Jaegeuk Kim   f2fs: flush inode...
1056
1057
  			iput(inode);
  		}
dee668c14   Chao Yu   f2fs: remove unne...
1058
  	}
0f18b462b   Jaegeuk Kim   f2fs: flush inode...
1059
1060
  	return 0;
  }
59c9081bc   Yunlei He   f2fs: allow write...
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
  static void __prepare_cp_block(struct f2fs_sb_info *sbi)
  {
  	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
  	struct f2fs_nm_info *nm_i = NM_I(sbi);
  	nid_t last_nid = nm_i->next_scan_nid;
  
  	next_free_nid(sbi, &last_nid);
  	ckpt->valid_block_count = cpu_to_le64(valid_user_blocks(sbi));
  	ckpt->valid_node_count = cpu_to_le32(valid_node_count(sbi));
  	ckpt->valid_inode_count = cpu_to_le32(valid_inode_count(sbi));
  	ckpt->next_free_nid = cpu_to_le32(last_nid);
  }
af033b2aa   Chao Yu   f2fs: guarantee j...
1073
1074
  static bool __need_flush_quota(struct f2fs_sb_info *sbi)
  {
db6ec53b7   Jaegeuk Kim   f2fs: add a rw_se...
1075
  	bool ret = false;
af033b2aa   Chao Yu   f2fs: guarantee j...
1076
1077
  	if (!is_journalled_quota(sbi))
  		return false;
db6ec53b7   Jaegeuk Kim   f2fs: add a rw_se...
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
  
  	down_write(&sbi->quota_sem);
  	if (is_sbi_flag_set(sbi, SBI_QUOTA_SKIP_FLUSH)) {
  		ret = false;
  	} else if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_REPAIR)) {
  		ret = false;
  	} else if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_FLUSH)) {
  		clear_sbi_flag(sbi, SBI_QUOTA_NEED_FLUSH);
  		ret = true;
  	} else if (get_pages(sbi, F2FS_DIRTY_QDATA)) {
  		ret = true;
  	}
  	up_write(&sbi->quota_sem);
  	return ret;
af033b2aa   Chao Yu   f2fs: guarantee j...
1092
  }
0a8165d7c   Jaegeuk Kim   f2fs: adjust kern...
1093
  /*
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1094
1095
   * Freeze all the FS-operations for checkpoint.
   */
cf779cab1   Jaegeuk Kim   f2fs: handle EIO ...
1096
  static int block_operations(struct f2fs_sb_info *sbi)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1097
  {
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1098
1099
1100
1101
1102
  	struct writeback_control wbc = {
  		.sync_mode = WB_SYNC_ALL,
  		.nr_to_write = LONG_MAX,
  		.for_reclaim = 0,
  	};
af033b2aa   Chao Yu   f2fs: guarantee j...
1103
  	int err = 0, cnt = 0;
c718379b6   Jaegeuk Kim   f2fs: give a chan...
1104

34c061ad8   Sayali Lokhande   f2fs: Avoid doubl...
1105
1106
1107
1108
  	/*
  	 * Let's flush inline_data in dirty node pages.
  	 */
  	f2fs_flush_inline_data(sbi);
af033b2aa   Chao Yu   f2fs: guarantee j...
1109
  retry_flush_quotas:
db6ec53b7   Jaegeuk Kim   f2fs: add a rw_se...
1110
  	f2fs_lock_all(sbi);
af033b2aa   Chao Yu   f2fs: guarantee j...
1111
1112
1113
1114
1115
  	if (__need_flush_quota(sbi)) {
  		int locked;
  
  		if (++cnt > DEFAULT_RETRY_QUOTA_FLUSH_COUNT) {
  			set_sbi_flag(sbi, SBI_QUOTA_SKIP_FLUSH);
db6ec53b7   Jaegeuk Kim   f2fs: add a rw_se...
1116
  			set_sbi_flag(sbi, SBI_QUOTA_NEED_FLUSH);
af033b2aa   Chao Yu   f2fs: guarantee j...
1117
1118
  			goto retry_flush_dents;
  		}
db6ec53b7   Jaegeuk Kim   f2fs: add a rw_se...
1119
  		f2fs_unlock_all(sbi);
af033b2aa   Chao Yu   f2fs: guarantee j...
1120
1121
1122
1123
1124
1125
  
  		/* only failed during mount/umount/freeze/quotactl */
  		locked = down_read_trylock(&sbi->sb->s_umount);
  		f2fs_quota_sync(sbi->sb, -1);
  		if (locked)
  			up_read(&sbi->sb->s_umount);
af033b2aa   Chao Yu   f2fs: guarantee j...
1126
1127
1128
1129
1130
  		cond_resched();
  		goto retry_flush_quotas;
  	}
  
  retry_flush_dents:
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1131
  	/* write all the dirty dentry pages */
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1132
  	if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
e479556bf   Gu Zheng   f2fs: use rw_sem ...
1133
  		f2fs_unlock_all(sbi);
4d57b86dd   Chao Yu   f2fs: clean up sy...
1134
  		err = f2fs_sync_dirty_inodes(sbi, DIR_INODE);
6d5a1495e   Chao Yu   f2fs: let user be...
1135
  		if (err)
1f5f11a3c   Jaegeuk Kim   f2fs: remove blk_...
1136
  			return err;
309738835   Jaegeuk Kim   f2fs: give time t...
1137
  		cond_resched();
af033b2aa   Chao Yu   f2fs: guarantee j...
1138
  		goto retry_flush_quotas;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1139
  	}
59c9081bc   Yunlei He   f2fs: allow write...
1140
1141
1142
1143
1144
  	/*
  	 * POR: we should ensure that there are no dirty node pages
  	 * until finishing nat/sit flush. inode->i_blocks can be updated.
  	 */
  	down_write(&sbi->node_change);
0f18b462b   Jaegeuk Kim   f2fs: flush inode...
1145
  	if (get_pages(sbi, F2FS_DIRTY_IMETA)) {
59c9081bc   Yunlei He   f2fs: allow write...
1146
  		up_write(&sbi->node_change);
0f18b462b   Jaegeuk Kim   f2fs: flush inode...
1147
1148
1149
  		f2fs_unlock_all(sbi);
  		err = f2fs_sync_inode_meta(sbi);
  		if (err)
1f5f11a3c   Jaegeuk Kim   f2fs: remove blk_...
1150
  			return err;
309738835   Jaegeuk Kim   f2fs: give time t...
1151
  		cond_resched();
af033b2aa   Chao Yu   f2fs: guarantee j...
1152
  		goto retry_flush_quotas;
0f18b462b   Jaegeuk Kim   f2fs: flush inode...
1153
  	}
399368372   Jaegeuk Kim   f2fs: introduce a...
1154
  retry_flush_nodes:
b3582c689   Chao Yu   f2fs: reduce comp...
1155
  	down_write(&sbi->node_write);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1156
1157
  
  	if (get_pages(sbi, F2FS_DIRTY_NODES)) {
b3582c689   Chao Yu   f2fs: reduce comp...
1158
  		up_write(&sbi->node_write);
c29fd0c0e   Chao Yu   f2fs: let sync no...
1159
  		atomic_inc(&sbi->wb_sync_req[NODE]);
4d57b86dd   Chao Yu   f2fs: clean up sy...
1160
  		err = f2fs_sync_node_pages(sbi, &wbc, false, FS_CP_NODE_IO);
c29fd0c0e   Chao Yu   f2fs: let sync no...
1161
  		atomic_dec(&sbi->wb_sync_req[NODE]);
6d5a1495e   Chao Yu   f2fs: let user be...
1162
  		if (err) {
59c9081bc   Yunlei He   f2fs: allow write...
1163
  			up_write(&sbi->node_change);
cf779cab1   Jaegeuk Kim   f2fs: handle EIO ...
1164
  			f2fs_unlock_all(sbi);
1f5f11a3c   Jaegeuk Kim   f2fs: remove blk_...
1165
  			return err;
cf779cab1   Jaegeuk Kim   f2fs: handle EIO ...
1166
  		}
309738835   Jaegeuk Kim   f2fs: give time t...
1167
  		cond_resched();
399368372   Jaegeuk Kim   f2fs: introduce a...
1168
  		goto retry_flush_nodes;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1169
  	}
59c9081bc   Yunlei He   f2fs: allow write...
1170
1171
1172
1173
1174
1175
1176
  
  	/*
  	 * sbi->node_change is used only for AIO write_begin path which produces
  	 * dirty node blocks and some checkpoint values by block allocation.
  	 */
  	__prepare_cp_block(sbi);
  	up_write(&sbi->node_change);
cf779cab1   Jaegeuk Kim   f2fs: handle EIO ...
1177
  	return err;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1178
1179
1180
1181
  }
  
  static void unblock_operations(struct f2fs_sb_info *sbi)
  {
b3582c689   Chao Yu   f2fs: reduce comp...
1182
  	up_write(&sbi->node_write);
e479556bf   Gu Zheng   f2fs: use rw_sem ...
1183
  	f2fs_unlock_all(sbi);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1184
  }
bf22c3cc8   Sahitya Tummala   f2fs: fix the pan...
1185
  void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type)
fb51b5ef9   Changman Lee   f2fs: cleanup wai...
1186
1187
1188
1189
  {
  	DEFINE_WAIT(wait);
  
  	for (;;) {
bf22c3cc8   Sahitya Tummala   f2fs: fix the pan...
1190
  		if (!get_pages(sbi, type))
fb51b5ef9   Changman Lee   f2fs: cleanup wai...
1191
  			break;
af697c0f5   Jaegeuk Kim   f2fs: keep meta p...
1192
1193
  		if (unlikely(f2fs_cp_error(sbi)))
  			break;
9c30df7c5   Jaegeuk Kim   f2fs: flush dirty...
1194
1195
1196
  		if (type == F2FS_DIRTY_META)
  			f2fs_sync_meta_pages(sbi, META, LONG_MAX,
  							FS_CP_META_IO);
1fd280188   Jaegeuk Kim   f2fs: fix deadloc...
1197
1198
  		else if (type == F2FS_WB_CP_DATA)
  			f2fs_submit_merged_write(sbi, DATA);
828add774   Jaegeuk Kim   f2fs: prepare a w...
1199
1200
  
  		prepare_to_wait(&sbi->cp_wait, &wait, TASK_UNINTERRUPTIBLE);
5df7731f6   Chao Yu   f2fs: introduce D...
1201
  		io_schedule_timeout(DEFAULT_IO_TIMEOUT);
fb51b5ef9   Changman Lee   f2fs: cleanup wai...
1202
1203
1204
  	}
  	finish_wait(&sbi->cp_wait, &wait);
  }
e4c5d8489   Jaegeuk Kim   f2fs: introduce u...
1205
1206
1207
1208
  static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc)
  {
  	unsigned long orphan_num = sbi->im[ORPHAN_INO].ino_num;
  	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
d1aa24535   Chao Yu   f2fs: use spin_{,...
1209
  	unsigned long flags;
e4c5d8489   Jaegeuk Kim   f2fs: introduce u...
1210

d1aa24535   Chao Yu   f2fs: use spin_{,...
1211
  	spin_lock_irqsave(&sbi->cp_lock, flags);
e4c5d8489   Jaegeuk Kim   f2fs: introduce u...
1212

c473f1a96   Chao Yu   f2fs: allow cpc->...
1213
  	if ((cpc->reason & CP_UMOUNT) &&
10047f537   Kinglong Mee   f2fs: le32_to_cpu...
1214
  			le32_to_cpu(ckpt->cp_pack_total_block_count) >
22ad0b6ab   Jaegeuk Kim   f2fs: add bitmaps...
1215
1216
  			sbi->blocks_per_seg - NM_I(sbi)->nat_bits_blocks)
  		disable_nat_bits(sbi, false);
1f43e2ad7   Chao Yu   f2fs: introduce C...
1217
1218
  	if (cpc->reason & CP_TRIMMED)
  		__set_ckpt_flags(ckpt, CP_TRIMMED_FLAG);
cd36d7a17   Chao Yu   f2fs: fix to clea...
1219
1220
  	else
  		__clear_ckpt_flags(ckpt, CP_TRIMMED_FLAG);
1f43e2ad7   Chao Yu   f2fs: introduce C...
1221

c473f1a96   Chao Yu   f2fs: allow cpc->...
1222
  	if (cpc->reason & CP_UMOUNT)
e4c5d8489   Jaegeuk Kim   f2fs: introduce u...
1223
1224
1225
  		__set_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
  	else
  		__clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
c473f1a96   Chao Yu   f2fs: allow cpc->...
1226
  	if (cpc->reason & CP_FASTBOOT)
e4c5d8489   Jaegeuk Kim   f2fs: introduce u...
1227
1228
1229
1230
1231
1232
1233
1234
  		__set_ckpt_flags(ckpt, CP_FASTBOOT_FLAG);
  	else
  		__clear_ckpt_flags(ckpt, CP_FASTBOOT_FLAG);
  
  	if (orphan_num)
  		__set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG);
  	else
  		__clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG);
c84ef3c5e   Sahitya Tummala   f2fs: Add a new C...
1235
  	if (is_sbi_flag_set(sbi, SBI_NEED_FSCK))
e4c5d8489   Jaegeuk Kim   f2fs: introduce u...
1236
  		__set_ckpt_flags(ckpt, CP_FSCK_FLAG);
c84ef3c5e   Sahitya Tummala   f2fs: Add a new C...
1237
1238
1239
1240
  	if (is_sbi_flag_set(sbi, SBI_IS_RESIZEFS))
  		__set_ckpt_flags(ckpt, CP_RESIZEFS_FLAG);
  	else
  		__clear_ckpt_flags(ckpt, CP_RESIZEFS_FLAG);
4354994f0   Daniel Rosenberg   f2fs: checkpoint ...
1241
1242
1243
1244
  	if (is_sbi_flag_set(sbi, SBI_CP_DISABLED))
  		__set_ckpt_flags(ckpt, CP_DISABLED_FLAG);
  	else
  		__clear_ckpt_flags(ckpt, CP_DISABLED_FLAG);
db610a640   Jaegeuk Kim   f2fs: add quick m...
1245
1246
1247
1248
  	if (is_sbi_flag_set(sbi, SBI_CP_DISABLED_QUICK))
  		__set_ckpt_flags(ckpt, CP_DISABLED_QUICK_FLAG);
  	else
  		__clear_ckpt_flags(ckpt, CP_DISABLED_QUICK_FLAG);
af033b2aa   Chao Yu   f2fs: guarantee j...
1249
1250
  	if (is_sbi_flag_set(sbi, SBI_QUOTA_SKIP_FLUSH))
  		__set_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG);
bc88ac96a   Jaegeuk Kim   f2fs: link f2fs q...
1251
1252
  	else
  		__clear_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG);
af033b2aa   Chao Yu   f2fs: guarantee j...
1253
1254
1255
  
  	if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_REPAIR))
  		__set_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG);
e4c5d8489   Jaegeuk Kim   f2fs: introduce u...
1256
1257
  	/* set this flag to activate crc|cp_ver for recovery */
  	__set_ckpt_flags(ckpt, CP_CRC_RECOVERY_FLAG);
f23679231   Jaegeuk Kim   f2fs: allow to re...
1258
  	__clear_ckpt_flags(ckpt, CP_NOCRC_RECOVERY_FLAG);
e4c5d8489   Jaegeuk Kim   f2fs: introduce u...
1259

d1aa24535   Chao Yu   f2fs: use spin_{,...
1260
  	spin_unlock_irqrestore(&sbi->cp_lock, flags);
e4c5d8489   Jaegeuk Kim   f2fs: introduce u...
1261
  }
46706d591   Gao Xiang   f2fs: flush cp pa...
1262
1263
1264
1265
1266
1267
1268
1269
1270
  static void commit_checkpoint(struct f2fs_sb_info *sbi,
  	void *src, block_t blk_addr)
  {
  	struct writeback_control wbc = {
  		.for_reclaim = 0,
  	};
  
  	/*
  	 * pagevec_lookup_tag and lock_page again will take
4d57b86dd   Chao Yu   f2fs: clean up sy...
1271
1272
  	 * some extra time. Therefore, f2fs_update_meta_pages and
  	 * f2fs_sync_meta_pages are combined in this function.
46706d591   Gao Xiang   f2fs: flush cp pa...
1273
  	 */
4d57b86dd   Chao Yu   f2fs: clean up sy...
1274
  	struct page *page = f2fs_grab_meta_page(sbi, blk_addr);
46706d591   Gao Xiang   f2fs: flush cp pa...
1275
  	int err;
bae0ee7a7   Chao Yu   f2fs: check PageW...
1276
  	f2fs_wait_on_page_writeback(page, META, true, true);
8d64d365a   Chao Yu   f2fs: fix to reor...
1277
1278
1279
1280
  
  	memcpy(page_address(page), src, PAGE_SIZE);
  
  	set_page_dirty(page);
46706d591   Gao Xiang   f2fs: flush cp pa...
1281
1282
1283
1284
1285
  	if (unlikely(!clear_page_dirty_for_io(page)))
  		f2fs_bug_on(sbi, 1);
  
  	/* writeout cp pack 2 page */
  	err = __f2fs_write_meta_page(page, &wbc, FS_CP_META_IO);
af697c0f5   Jaegeuk Kim   f2fs: keep meta p...
1286
1287
1288
1289
  	if (unlikely(err && f2fs_cp_error(sbi))) {
  		f2fs_put_page(page, 1);
  		return;
  	}
46706d591   Gao Xiang   f2fs: flush cp pa...
1290

af697c0f5   Jaegeuk Kim   f2fs: keep meta p...
1291
  	f2fs_bug_on(sbi, err);
46706d591   Gao Xiang   f2fs: flush cp pa...
1292
1293
1294
1295
1296
  	f2fs_put_page(page, 0);
  
  	/* submit checkpoint (with barrier if NOBARRIER is not set) */
  	f2fs_submit_merged_write(sbi, META_FLUSH);
  }
5a1197544   Chao Yu   f2fs: fix kbytes ...
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
  static inline u64 get_sectors_written(struct block_device *bdev)
  {
  	return bdev->bd_part ?
  		(u64)part_stat_read(bdev->bd_part, sectors[STAT_WRITE]) : 0;
  }
  
  u64 f2fs_get_sectors_written(struct f2fs_sb_info *sbi)
  {
  	if (f2fs_is_multi_device(sbi)) {
  		u64 sectors = 0;
  		int i;
  
  		for (i = 0; i < sbi->s_ndevs; i++)
  			sectors += get_sectors_written(FDEV(i).bdev);
  
  		return sectors;
  	}
  
  	return get_sectors_written(sbi->sb->s_bdev);
  }
c34f42e2c   Chao Yu   f2fs: report erro...
1317
  static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1318
1319
  {
  	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
770418238   Huang Ying   f2fs: use nm_i->n...
1320
  	struct f2fs_nm_info *nm_i = NM_I(sbi);
d1aa24535   Chao Yu   f2fs: use spin_{,...
1321
  	unsigned long orphan_num = sbi->im[ORPHAN_INO].ino_num, flags;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1322
  	block_t start_blk;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1323
  	unsigned int data_sum_blocks, orphan_blocks;
7e586fa02   Jaegeuk Kim   f2fs: fix crc end...
1324
  	__u32 crc32 = 0;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1325
  	int i;
551414861   Wanpeng Li   f2fs: introduce m...
1326
  	int cp_payload_blks = __cp_payload(sbi);
8f1dbbbbd   Shuoran Liu   f2fs: introduce l...
1327
1328
  	struct curseg_info *seg_i = CURSEG_I(sbi, CURSEG_HOT_NODE);
  	u64 kbytes_written;
1228b482c   Chao Yu   f2fs: fix to flus...
1329
  	int err;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1330
1331
  
  	/* Flush all the NAT/SIT pages */
8ec18bff7   Chao Yu   f2fs: clean up ch...
1332
  	f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1333

7a88ddb56   Chao Yu   f2fs: fix inconsi...
1334
  	/* start to update checkpoint, cp ver is already updated previously */
a1f72ac2c   Chao Yu   f2fs: fix to upda...
1335
  	ckpt->elapsed_time = cpu_to_le64(get_mtime(sbi, true));
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1336
  	ckpt->free_segment_count = cpu_to_le32(free_segments(sbi));
b5b822050   Chao Yu   f2fs: use macro f...
1337
  	for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) {
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1338
1339
1340
1341
1342
1343
1344
  		ckpt->cur_node_segno[i] =
  			cpu_to_le32(curseg_segno(sbi, i + CURSEG_HOT_NODE));
  		ckpt->cur_node_blkoff[i] =
  			cpu_to_le16(curseg_blkoff(sbi, i + CURSEG_HOT_NODE));
  		ckpt->alloc_type[i + CURSEG_HOT_NODE] =
  				curseg_alloc_type(sbi, i + CURSEG_HOT_NODE);
  	}
b5b822050   Chao Yu   f2fs: use macro f...
1345
  	for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) {
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1346
1347
1348
1349
1350
1351
1352
  		ckpt->cur_data_segno[i] =
  			cpu_to_le32(curseg_segno(sbi, i + CURSEG_HOT_DATA));
  		ckpt->cur_data_blkoff[i] =
  			cpu_to_le16(curseg_blkoff(sbi, i + CURSEG_HOT_DATA));
  		ckpt->alloc_type[i + CURSEG_HOT_DATA] =
  				curseg_alloc_type(sbi, i + CURSEG_HOT_DATA);
  	}
a87aff1d4   Jack Qiu   f2fs: space relat...
1353
  	/* 2 cp + n data seg summary + orphan inode blocks */
4d57b86dd   Chao Yu   f2fs: clean up sy...
1354
  	data_sum_blocks = f2fs_npages_for_summary_flush(sbi, false);
d1aa24535   Chao Yu   f2fs: use spin_{,...
1355
  	spin_lock_irqsave(&sbi->cp_lock, flags);
b5b822050   Chao Yu   f2fs: use macro f...
1356
  	if (data_sum_blocks < NR_CURSEG_DATA_TYPE)
aaec2b1d1   Chao Yu   f2fs: introduce c...
1357
  		__set_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1358
  	else
aaec2b1d1   Chao Yu   f2fs: introduce c...
1359
  		__clear_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG);
d1aa24535   Chao Yu   f2fs: use spin_{,...
1360
  	spin_unlock_irqrestore(&sbi->cp_lock, flags);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1361

67298804f   Chao Yu   f2fs: introduce s...
1362
  	orphan_blocks = GET_ORPHAN_BLOCKS(orphan_num);
1dbe41521   Changman Lee   f2fs: large volum...
1363
1364
  	ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks +
  			orphan_blocks);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1365

119ee9144   Jaegeuk Kim   f2fs: split UMOUN...
1366
  	if (__remain_node_summaries(cpc->reason))
b5b822050   Chao Yu   f2fs: use macro f...
1367
  		ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS+
1dbe41521   Changman Lee   f2fs: large volum...
1368
1369
  				cp_payload_blks + data_sum_blocks +
  				orphan_blocks + NR_CURSEG_NODE_TYPE);
119ee9144   Jaegeuk Kim   f2fs: split UMOUN...
1370
  	else
b5b822050   Chao Yu   f2fs: use macro f...
1371
  		ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS +
1dbe41521   Changman Lee   f2fs: large volum...
1372
1373
  				cp_payload_blks + data_sum_blocks +
  				orphan_blocks);
119ee9144   Jaegeuk Kim   f2fs: split UMOUN...
1374

e4c5d8489   Jaegeuk Kim   f2fs: introduce u...
1375
1376
  	/* update ckpt flag for checkpoint */
  	update_ckpt_flags(sbi, cpc);
a468f0ef5   Jaegeuk Kim   f2fs: use crc and...
1377

127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1378
1379
1380
  	/* update SIT/NAT bitmap */
  	get_sit_bitmap(sbi, __bitmap_ptr(sbi, SIT_BITMAP));
  	get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP));
d7eb8f1cd   Chao Yu   f2fs: allow unfix...
1381
  	crc32 = f2fs_checkpoint_chksum(sbi, ckpt);
7e586fa02   Jaegeuk Kim   f2fs: fix crc end...
1382
1383
  	*((__le32 *)((unsigned char *)ckpt +
  				le32_to_cpu(ckpt->checksum_offset)))
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1384
  				= cpu_to_le32(crc32);
8508e44ae   Jaegeuk Kim   f2fs: fix to dete...
1385
  	start_blk = __start_cp_next_addr(sbi);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1386

22ad0b6ab   Jaegeuk Kim   f2fs: add bitmaps...
1387
1388
1389
  	/* write nat bits */
  	if (enabled_nat_bits(sbi, cpc)) {
  		__u64 cp_ver = cur_cp_version(ckpt);
22ad0b6ab   Jaegeuk Kim   f2fs: add bitmaps...
1390
1391
1392
1393
1394
1395
1396
  		block_t blk;
  
  		cp_ver |= ((__u64)crc32 << 32);
  		*(__le64 *)nm_i->nat_bits = cpu_to_le64(cp_ver);
  
  		blk = start_blk + sbi->blocks_per_seg - nm_i->nat_bits_blocks;
  		for (i = 0; i < nm_i->nat_bits_blocks; i++)
4d57b86dd   Chao Yu   f2fs: clean up sy...
1397
  			f2fs_update_meta_page(sbi, nm_i->nat_bits +
22ad0b6ab   Jaegeuk Kim   f2fs: add bitmaps...
1398
  					(i << F2FS_BLKSIZE_BITS), blk + i);
22ad0b6ab   Jaegeuk Kim   f2fs: add bitmaps...
1399
  	}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1400
  	/* write out checkpoint buffer at block 0 */
4d57b86dd   Chao Yu   f2fs: clean up sy...
1401
  	f2fs_update_meta_page(sbi, ckpt, start_blk++);
381722d2a   Chao Yu   f2fs: introduce u...
1402
1403
  
  	for (i = 1; i < 1 + cp_payload_blks; i++)
4d57b86dd   Chao Yu   f2fs: clean up sy...
1404
  		f2fs_update_meta_page(sbi, (char *)ckpt + i * F2FS_BLKSIZE,
381722d2a   Chao Yu   f2fs: introduce u...
1405
  							start_blk++);
1dbe41521   Changman Lee   f2fs: large volum...
1406

67298804f   Chao Yu   f2fs: introduce s...
1407
  	if (orphan_num) {
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1408
1409
1410
  		write_orphan_inodes(sbi, start_blk);
  		start_blk += orphan_blocks;
  	}
4d57b86dd   Chao Yu   f2fs: clean up sy...
1411
  	f2fs_write_data_summaries(sbi, start_blk);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1412
  	start_blk += data_sum_blocks;
8f1dbbbbd   Shuoran Liu   f2fs: introduce l...
1413
1414
1415
  
  	/* Record write statistics in the hot node summary */
  	kbytes_written = sbi->kbytes_written;
5a1197544   Chao Yu   f2fs: fix kbytes ...
1416
1417
  	kbytes_written += (f2fs_get_sectors_written(sbi) -
  				sbi->sectors_written_start) >> 1;
b7ad7512b   Chao Yu   f2fs: split journ...
1418
  	seg_i->journal->info.kbytes_written = cpu_to_le64(kbytes_written);
8f1dbbbbd   Shuoran Liu   f2fs: introduce l...
1419

119ee9144   Jaegeuk Kim   f2fs: split UMOUN...
1420
  	if (__remain_node_summaries(cpc->reason)) {
4d57b86dd   Chao Yu   f2fs: clean up sy...
1421
  		f2fs_write_node_summaries(sbi, start_blk);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1422
1423
  		start_blk += NR_CURSEG_NODE_TYPE;
  	}
46706d591   Gao Xiang   f2fs: flush cp pa...
1424
1425
1426
  	/* update user_block_counts */
  	sbi->last_valid_block_count = sbi->total_valid_block_count;
  	percpu_counter_set(&sbi->alloc_valid_block_count, 0);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1427

46706d591   Gao Xiang   f2fs: flush cp pa...
1428
  	/* Here, we have one bio having CP pack except cp pack 2 page */
4d57b86dd   Chao Yu   f2fs: clean up sy...
1429
  	f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
bf22c3cc8   Sahitya Tummala   f2fs: fix the pan...
1430
1431
  	/* Wait for all dirty meta pages to be submitted for IO */
  	f2fs_wait_on_all_pages(sbi, F2FS_DIRTY_META);
46706d591   Gao Xiang   f2fs: flush cp pa...
1432
1433
  
  	/* wait for previous submitted meta pages writeback */
bf22c3cc8   Sahitya Tummala   f2fs: fix the pan...
1434
  	f2fs_wait_on_all_pages(sbi, F2FS_WB_CP_DATA);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1435

46706d591   Gao Xiang   f2fs: flush cp pa...
1436
1437
1438
1439
  	/* flush all device cache */
  	err = f2fs_flush_device_cache(sbi);
  	if (err)
  		return err;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1440

46706d591   Gao Xiang   f2fs: flush cp pa...
1441
1442
  	/* barrier and flush checkpoint cp pack 2 page if it can */
  	commit_checkpoint(sbi, ckpt, start_blk);
bf22c3cc8   Sahitya Tummala   f2fs: fix the pan...
1443
  	f2fs_wait_on_all_pages(sbi, F2FS_WB_CP_DATA);
6a8f8ca58   Jaegeuk Kim   f2fs: avoid race ...
1444

18767e626   Chao Yu   f2fs: don't keep ...
1445
  	/*
542989b67   Eric Biggers   f2fs: don't keep ...
1446
  	 * invalidate intermediate page cache borrowed from meta inode which are
aff6fbbe8   Chao Yu   f2fs: don't keep ...
1447
  	 * used for migration of encrypted, verity or compressed inode's blocks.
18767e626   Chao Yu   f2fs: don't keep ...
1448
  	 */
aff6fbbe8   Chao Yu   f2fs: don't keep ...
1449
1450
  	if (f2fs_sb_has_encrypt(sbi) || f2fs_sb_has_verity(sbi) ||
  		f2fs_sb_has_compression(sbi))
18767e626   Chao Yu   f2fs: don't keep ...
1451
1452
  		invalidate_mapping_pages(META_MAPPING(sbi),
  				MAIN_BLKADDR(sbi), MAX_BLKADDR(sbi) - 1);
4d57b86dd   Chao Yu   f2fs: clean up sy...
1453
  	f2fs_release_ino_entry(sbi, false);
cf779cab1   Jaegeuk Kim   f2fs: handle EIO ...
1454

50fa53ecc   Chao Yu   f2fs: fix to avoi...
1455
  	f2fs_reset_fsync_node_info(sbi);
caf0047e7   Chao Yu   f2fs: merge flags...
1456
  	clear_sbi_flag(sbi, SBI_IS_DIRTY);
bbf156f7a   Jaegeuk Kim   f2fs: fix lost xa...
1457
  	clear_sbi_flag(sbi, SBI_NEED_CP);
af033b2aa   Chao Yu   f2fs: guarantee j...
1458
  	clear_sbi_flag(sbi, SBI_QUOTA_SKIP_FLUSH);
c9c8ed50d   Chao Yu   f2fs: fix to avoi...
1459
1460
  
  	spin_lock(&sbi->stat_lock);
4354994f0   Daniel Rosenberg   f2fs: checkpoint ...
1461
  	sbi->unusable_block_count = 0;
c9c8ed50d   Chao Yu   f2fs: fix to avoi...
1462
  	spin_unlock(&sbi->stat_lock);
8508e44ae   Jaegeuk Kim   f2fs: fix to dete...
1463
  	__set_cp_next_pack(sbi);
c34f42e2c   Chao Yu   f2fs: report erro...
1464

c2a080aef   Chao Yu   f2fs: fix to set ...
1465
1466
1467
1468
1469
1470
1471
1472
1473
  	/*
  	 * redirty superblock if metadata like node page or inode cache is
  	 * updated during writing checkpoint.
  	 */
  	if (get_pages(sbi, F2FS_DIRTY_NODES) ||
  			get_pages(sbi, F2FS_DIRTY_IMETA))
  		set_sbi_flag(sbi, SBI_IS_DIRTY);
  
  	f2fs_bug_on(sbi, get_pages(sbi, F2FS_DIRTY_DENTS));
af697c0f5   Jaegeuk Kim   f2fs: keep meta p...
1474
  	return unlikely(f2fs_cp_error(sbi)) ? -EIO : 0;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1475
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
1476
  int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1477
1478
1479
  {
  	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
  	unsigned long long ckpt_ver;
c34f42e2c   Chao Yu   f2fs: report erro...
1480
  	int err = 0;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1481

f5a131bb2   Chao Yu   f2fs: fix to be a...
1482
1483
  	if (f2fs_readonly(sbi->sb) || f2fs_hw_is_readonly(sbi))
  		return -EROFS;
4354994f0   Daniel Rosenberg   f2fs: checkpoint ...
1484
1485
1486
  	if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
  		if (cpc->reason != CP_PAUSE)
  			return 0;
dcbb4c10e   Joe Perches   f2fs: introduce f...
1487
  		f2fs_warn(sbi, "Start checkpoint disabled!");
4354994f0   Daniel Rosenberg   f2fs: checkpoint ...
1488
  	}
b4b10061e   Jaegeuk Kim   f2fs: refactor re...
1489
  	if (cpc->reason != CP_RESIZE)
301e31717   Sahitya Tummala   f2fs: change to u...
1490
  		down_write(&sbi->cp_global_sem);
8501017e5   Jaegeuk Kim   f2fs: check s_dir...
1491

caf0047e7   Chao Yu   f2fs: merge flags...
1492
  	if (!is_sbi_flag_set(sbi, SBI_IS_DIRTY) &&
c473f1a96   Chao Yu   f2fs: allow cpc->...
1493
1494
  		((cpc->reason & CP_FASTBOOT) || (cpc->reason & CP_SYNC) ||
  		((cpc->reason & CP_DISCARD) && !sbi->discard_blks)))
8501017e5   Jaegeuk Kim   f2fs: check s_dir...
1495
  		goto out;
c34f42e2c   Chao Yu   f2fs: report erro...
1496
1497
  	if (unlikely(f2fs_cp_error(sbi))) {
  		err = -EIO;
cf779cab1   Jaegeuk Kim   f2fs: handle EIO ...
1498
  		goto out;
c34f42e2c   Chao Yu   f2fs: report erro...
1499
  	}
2bda542d5   Wanpeng Li   f2fs: fix block_o...
1500
1501
  
  	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "start block_ops");
c34f42e2c   Chao Yu   f2fs: report erro...
1502
1503
  	err = block_operations(sbi);
  	if (err)
cf779cab1   Jaegeuk Kim   f2fs: handle EIO ...
1504
  		goto out;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1505

75ab4cb83   Jaegeuk Kim   f2fs: introduce c...
1506
  	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish block_ops");
2af4bd6ca   Namjae Jeon   f2fs: add tracepo...
1507

b9109b0e4   Jaegeuk Kim   f2fs: remove unne...
1508
  	f2fs_flush_merged_writes(sbi);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1509

58cce381f   Yunlei He   f2fs: skip new ch...
1510
  	/* this is the case of multiple fstrims without any changes */
c473f1a96   Chao Yu   f2fs: allow cpc->...
1511
  	if (cpc->reason & CP_DISCARD) {
4d57b86dd   Chao Yu   f2fs: clean up sy...
1512
  		if (!f2fs_exist_trim_candidates(sbi, cpc)) {
25290fa55   Jaegeuk Kim   f2fs: return fs_t...
1513
1514
1515
  			unblock_operations(sbi);
  			goto out;
  		}
317c4f58d   Jaegeuk Kim   f2fs: avoid race ...
1516
  		if (NM_I(sbi)->nat_cnt[DIRTY_NAT] == 0 &&
0333ad4e4   Jaegeuk Kim   f2fs: avoid needl...
1517
1518
  				SIT_I(sbi)->dirty_sentries == 0 &&
  				prefree_segments(sbi) == 0) {
4d57b86dd   Chao Yu   f2fs: clean up sy...
1519
1520
  			f2fs_flush_sit_entries(sbi, cpc);
  			f2fs_clear_prefree_segments(sbi, cpc);
0333ad4e4   Jaegeuk Kim   f2fs: avoid needl...
1521
1522
1523
  			unblock_operations(sbi);
  			goto out;
  		}
58cce381f   Yunlei He   f2fs: skip new ch...
1524
  	}
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1525
1526
1527
1528
1529
  	/*
  	 * update checkpoint pack index
  	 * Increase the version number so that
  	 * SIT entries and seg summaries are written at correct place
  	 */
d71b5564c   Jaegeuk Kim   f2fs: introduce c...
1530
  	ckpt_ver = cur_cp_version(ckpt);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1531
1532
1533
  	ckpt->checkpoint_ver = cpu_to_le64(++ckpt_ver);
  
  	/* write cached NAT/SIT entries to NAT/SIT area */
edc55aaf0   Jaegeuk Kim   f2fs: avoid f2fs_...
1534
1535
1536
  	err = f2fs_flush_nat_entries(sbi, cpc);
  	if (err)
  		goto stop;
4d57b86dd   Chao Yu   f2fs: clean up sy...
1537
  	f2fs_flush_sit_entries(sbi, cpc);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1538

d0b9e42ab   Chao Yu   f2fs: introduce i...
1539
  	/* save inmem log status */
093749e29   Chao Yu   f2fs: support age...
1540
  	f2fs_save_inmem_curseg(sbi);
d0b9e42ab   Chao Yu   f2fs: introduce i...
1541

c34f42e2c   Chao Yu   f2fs: report erro...
1542
  	err = do_checkpoint(sbi, cpc);
4e6a8d9b2   Jaegeuk Kim   f2fs: relax async...
1543
  	if (err)
4d57b86dd   Chao Yu   f2fs: clean up sy...
1544
  		f2fs_release_discard_addrs(sbi);
4e6a8d9b2   Jaegeuk Kim   f2fs: relax async...
1545
  	else
4d57b86dd   Chao Yu   f2fs: clean up sy...
1546
  		f2fs_clear_prefree_segments(sbi, cpc);
d0b9e42ab   Chao Yu   f2fs: introduce i...
1547

093749e29   Chao Yu   f2fs: support age...
1548
  	f2fs_restore_inmem_curseg(sbi);
edc55aaf0   Jaegeuk Kim   f2fs: avoid f2fs_...
1549
  stop:
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1550
  	unblock_operations(sbi);
942e0be62   Changman Lee   f2fs: show counts...
1551
  	stat_inc_cp_count(sbi->stat_info);
10027551c   Jaegeuk Kim   f2fs: pass checkp...
1552

c473f1a96   Chao Yu   f2fs: allow cpc->...
1553
  	if (cpc->reason & CP_RECOVERY)
dcbb4c10e   Joe Perches   f2fs: introduce f...
1554
  		f2fs_notice(sbi, "checkpoint: version = %llx", ckpt_ver);
60b99b486   Jaegeuk Kim   f2fs: introduce a...
1555

7a88ddb56   Chao Yu   f2fs: fix inconsi...
1556
  	/* update CP_TIME to trigger checkpoint periodically */
6beceb542   Jaegeuk Kim   f2fs: introduce t...
1557
  	f2fs_update_time(sbi, CP_TIME);
55d1cdb25   Jaegeuk Kim   f2fs: relocate tr...
1558
  	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint");
8501017e5   Jaegeuk Kim   f2fs: check s_dir...
1559
  out:
b4b10061e   Jaegeuk Kim   f2fs: refactor re...
1560
  	if (cpc->reason != CP_RESIZE)
301e31717   Sahitya Tummala   f2fs: change to u...
1561
  		up_write(&sbi->cp_global_sem);
c34f42e2c   Chao Yu   f2fs: report erro...
1562
  	return err;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1563
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
1564
  void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1565
  {
6451e041c   Jaegeuk Kim   f2fs: add infra f...
1566
1567
1568
  	int i;
  
  	for (i = 0; i < MAX_INO_ENTRY; i++) {
67298804f   Chao Yu   f2fs: introduce s...
1569
1570
1571
1572
1573
1574
  		struct inode_management *im = &sbi->im[i];
  
  		INIT_RADIX_TREE(&im->ino_root, GFP_ATOMIC);
  		spin_lock_init(&im->ino_lock);
  		INIT_LIST_HEAD(&im->ino_list);
  		im->ino_num = 0;
6451e041c   Jaegeuk Kim   f2fs: add infra f...
1575
  	}
b5b822050   Chao Yu   f2fs: use macro f...
1576
  	sbi->max_orphans = (sbi->blocks_per_seg - F2FS_CP_PACKS -
d0b9e42ab   Chao Yu   f2fs: introduce i...
1577
  			NR_CURSEG_PERSIST_TYPE - __cp_payload(sbi)) *
14b428177   Wanpeng Li   f2fs: fix max orp...
1578
  				F2FS_ORPHANS_PER_BLOCK;
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1579
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
1580
  int __init f2fs_create_checkpoint_caches(void)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1581
  {
6451e041c   Jaegeuk Kim   f2fs: add infra f...
1582
1583
1584
  	ino_entry_slab = f2fs_kmem_cache_create("f2fs_ino_entry",
  			sizeof(struct ino_entry));
  	if (!ino_entry_slab)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1585
  		return -ENOMEM;
4d57b86dd   Chao Yu   f2fs: clean up sy...
1586
  	f2fs_inode_entry_slab = f2fs_kmem_cache_create("f2fs_inode_entry",
062920734   Chao Yu   f2fs: reuse inode...
1587
  			sizeof(struct inode_entry));
4d57b86dd   Chao Yu   f2fs: clean up sy...
1588
  	if (!f2fs_inode_entry_slab) {
6451e041c   Jaegeuk Kim   f2fs: add infra f...
1589
  		kmem_cache_destroy(ino_entry_slab);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1590
1591
1592
1593
  		return -ENOMEM;
  	}
  	return 0;
  }
4d57b86dd   Chao Yu   f2fs: clean up sy...
1594
  void f2fs_destroy_checkpoint_caches(void)
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1595
  {
6451e041c   Jaegeuk Kim   f2fs: add infra f...
1596
  	kmem_cache_destroy(ino_entry_slab);
4d57b86dd   Chao Yu   f2fs: clean up sy...
1597
  	kmem_cache_destroy(f2fs_inode_entry_slab);
127e670ab   Jaegeuk Kim   f2fs: add checkpo...
1598
  }