recovery.c 16.6 KB
Newer Older
J
Jaegeuk Kim 已提交
1
/*
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
 * fs/f2fs/recovery.c
 *
 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
 *             http://www.samsung.com/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/fs.h>
#include <linux/f2fs_fs.h>
#include "f2fs.h"
#include "node.h"
#include "segment.h"

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
/*
 * Roll forward recovery scenarios.
 *
 * [Term] F: fsync_mark, D: dentry_mark
 *
 * 1. inode(x) | CP | inode(x) | dnode(F)
 * -> Update the latest inode(x).
 *
 * 2. inode(x) | CP | inode(F) | dnode(F)
 * -> No problem.
 *
 * 3. inode(x) | CP | dnode(F) | inode(x)
 * -> Recover to the latest dnode(F), and drop the last inode(x)
 *
 * 4. inode(x) | CP | dnode(F) | inode(F)
 * -> No problem.
 *
 * 5. CP | inode(x) | dnode(F)
 * -> The inode(DF) was missing. Should drop this dnode(F).
 *
 * 6. CP | inode(DF) | dnode(F)
 * -> No problem.
 *
 * 7. CP | dnode(F) | inode(DF)
 * -> If f2fs_iget fails, then goto next to find inode(DF).
 *
 * 8. CP | dnode(F) | inode(x)
 * -> If f2fs_iget fails, then goto next to find inode(DF).
 *    But it will fail due to no inode(DF).
 */

48 49
static struct kmem_cache *fsync_entry_slab;

C
Chao Yu 已提交
50
bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi)
51
{
52 53 54
	s64 nalloc = percpu_counter_sum_positive(&sbi->alloc_valid_block_count);

	if (sbi->last_valid_block_count + nalloc > sbi->user_block_count)
55 56 57 58 59 60 61 62 63
		return false;
	return true;
}

static struct fsync_inode_entry *get_fsync_inode(struct list_head *head,
								nid_t ino)
{
	struct fsync_inode_entry *entry;

64
	list_for_each_entry(entry, head, list)
65 66
		if (entry->inode->i_ino == ino)
			return entry;
67

68 69 70
	return NULL;
}

71
static struct fsync_inode_entry *add_fsync_inode(struct f2fs_sb_info *sbi,
C
Chao Yu 已提交
72
			struct list_head *head, nid_t ino, bool quota_inode)
73
{
74
	struct inode *inode;
75
	struct fsync_inode_entry *entry;
C
Chao Yu 已提交
76
	int err;
77

78
	inode = f2fs_iget_retry(sbi->sb, ino);
79 80 81
	if (IS_ERR(inode))
		return ERR_CAST(inode);

C
Chao Yu 已提交
82 83 84 85 86 87 88 89 90 91
	err = dquot_initialize(inode);
	if (err)
		goto err_out;

	if (quota_inode) {
		err = dquot_alloc_inode(inode);
		if (err)
			goto err_out;
	}

92
	entry = f2fs_kmem_cache_alloc(fsync_entry_slab, GFP_F2FS_ZERO);
93 94 95 96
	entry->inode = inode;
	list_add_tail(&entry->list, head);

	return entry;
C
Chao Yu 已提交
97 98 99
err_out:
	iput(inode);
	return ERR_PTR(err);
100 101 102 103 104 105 106 107 108
}

static void del_fsync_inode(struct fsync_inode_entry *entry)
{
	iput(entry->inode);
	list_del(&entry->list);
	kmem_cache_free(fsync_entry_slab, entry);
}

C
Chao Yu 已提交
109 110
static int recover_dentry(struct inode *inode, struct page *ipage,
						struct list_head *dir_list)
111
{
112
	struct f2fs_inode *raw_inode = F2FS_INODE(ipage);
113
	nid_t pino = le32_to_cpu(raw_inode->i_pino);
J
Jaegeuk Kim 已提交
114
	struct f2fs_dir_entry *de;
115
	struct fscrypt_name fname;
116
	struct page *page;
J
Jaegeuk Kim 已提交
117
	struct inode *dir, *einode;
C
Chao Yu 已提交
118
	struct fsync_inode_entry *entry;
119
	int err = 0;
120
	char *name;
121

C
Chao Yu 已提交
122 123
	entry = get_fsync_inode(dir_list, pino);
	if (!entry) {
C
Chao Yu 已提交
124 125
		entry = add_fsync_inode(F2FS_I_SB(inode), dir_list,
							pino, false);
126 127 128
		if (IS_ERR(entry)) {
			dir = ERR_CAST(entry);
			err = PTR_ERR(entry);
C
Chao Yu 已提交
129 130
			goto out;
		}
131 132
	}

C
Chao Yu 已提交
133 134
	dir = entry->inode;

135 136 137
	memset(&fname, 0, sizeof(struct fscrypt_name));
	fname.disk_name.len = le32_to_cpu(raw_inode->i_namelen);
	fname.disk_name.name = raw_inode->i_name;
138

139
	if (unlikely(fname.disk_name.len > F2FS_NAME_LEN)) {
140 141
		WARN_ON(1);
		err = -ENAMETOOLONG;
C
Chao Yu 已提交
142
		goto out;
143
	}
J
Jaegeuk Kim 已提交
144
retry:
145
	de = __f2fs_find_entry(dir, &fname, &page);
146
	if (de && inode->i_ino == le32_to_cpu(de->ino))
147
		goto out_put;
148

J
Jaegeuk Kim 已提交
149
	if (de) {
150
		einode = f2fs_iget_retry(inode->i_sb, le32_to_cpu(de->ino));
J
Jaegeuk Kim 已提交
151 152
		if (IS_ERR(einode)) {
			WARN_ON(1);
153 154
			err = PTR_ERR(einode);
			if (err == -ENOENT)
J
Jaegeuk Kim 已提交
155
				err = -EEXIST;
156
			goto out_put;
157
		}
C
Chao Yu 已提交
158 159 160 161

		err = dquot_initialize(einode);
		if (err) {
			iput(einode);
162
			goto out_put;
C
Chao Yu 已提交
163 164
		}

C
Chao Yu 已提交
165
		err = f2fs_acquire_orphan_inode(F2FS_I_SB(inode));
166 167
		if (err) {
			iput(einode);
168
			goto out_put;
J
Jaegeuk Kim 已提交
169
		}
170
		f2fs_delete_entry(de, page, dir, einode);
J
Jaegeuk Kim 已提交
171 172
		iput(einode);
		goto retry;
173 174 175
	} else if (IS_ERR(page)) {
		err = PTR_ERR(page);
	} else {
C
Chao Yu 已提交
176
		err = f2fs_add_dentry(dir, &fname, inode,
177
					inode->i_ino, inode->i_mode);
178
	}
179 180
	if (err == -ENOMEM)
		goto retry;
181 182
	goto out;

183
out_put:
184
	f2fs_put_page(page, 0);
185
out:
186 187 188 189
	if (file_enc_name(inode))
		name = "<encrypted>";
	else
		name = raw_inode->i_name;
C
Chris Fries 已提交
190 191
	f2fs_msg(inode->i_sb, KERN_NOTICE,
			"%s: ino = %x, name = %s, dir = %lx, err = %d",
192
			__func__, ino_of_node(ipage), name,
D
Dan Carpenter 已提交
193
			IS_ERR(dir) ? 0 : dir->i_ino, err);
194 195 196
	return err;
}

J
Jaegeuk Kim 已提交
197 198 199 200 201 202 203 204 205 206 207 208
static void recover_inline_flags(struct inode *inode, struct f2fs_inode *ri)
{
	if (ri->i_inline & F2FS_PIN_FILE)
		set_inode_flag(inode, FI_PIN_FILE);
	else
		clear_inode_flag(inode, FI_PIN_FILE);
	if (ri->i_inline & F2FS_DATA_EXIST)
		set_inode_flag(inode, FI_DATA_EXIST);
	else
		clear_inode_flag(inode, FI_DATA_EXIST);
}

209
static void recover_inode(struct inode *inode, struct page *page)
210
{
211
	struct f2fs_inode *raw = F2FS_INODE(page);
212
	char *name;
213 214

	inode->i_mode = le16_to_cpu(raw->i_mode);
215
	f2fs_i_size_write(inode, le64_to_cpu(raw->i_size));
C
Chao Yu 已提交
216
	inode->i_atime.tv_sec = le64_to_cpu(raw->i_atime);
217 218
	inode->i_ctime.tv_sec = le64_to_cpu(raw->i_ctime);
	inode->i_mtime.tv_sec = le64_to_cpu(raw->i_mtime);
C
Chao Yu 已提交
219
	inode->i_atime.tv_nsec = le32_to_cpu(raw->i_atime_nsec);
220 221
	inode->i_ctime.tv_nsec = le32_to_cpu(raw->i_ctime_nsec);
	inode->i_mtime.tv_nsec = le32_to_cpu(raw->i_mtime_nsec);
222

223 224
	F2FS_I(inode)->i_advise = raw->i_advise;

J
Jaegeuk Kim 已提交
225 226
	recover_inline_flags(inode, raw);

227 228 229 230 231
	if (file_enc_name(inode))
		name = "<encrypted>";
	else
		name = F2FS_INODE(page)->i_name;

J
Jaegeuk Kim 已提交
232 233 234
	f2fs_msg(inode->i_sb, KERN_NOTICE,
		"recover_inode: ino = %x, name = %s, inline = %x",
			ino_of_node(page), name, raw->i_inline);
235 236
}

237 238
static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
				bool check_only)
239 240
{
	struct curseg_info *curseg;
241
	struct page *page = NULL;
242
	block_t blkaddr;
243
	unsigned int loop_cnt = 0;
244 245
	unsigned int free_blocks = MAIN_SEGS(sbi) * sbi->blocks_per_seg -
						valid_user_blocks(sbi);
246 247 248 249
	int err = 0;

	/* get node pages in the current segment */
	curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
250
	blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
251 252 253 254

	while (1) {
		struct fsync_inode_entry *entry;

255
		if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR))
256
			return 0;
257

C
Chao Yu 已提交
258
		page = f2fs_get_tmp_page(sbi, blkaddr);
259

260
		if (!is_recoverable_dnode(page))
261
			break;
262 263 264 265 266

		if (!is_fsync_dnode(page))
			goto next;

		entry = get_fsync_inode(head, ino_of_node(page));
267
		if (!entry) {
C
Chao Yu 已提交
268 269
			bool quota_inode = false;

270 271
			if (!check_only &&
					IS_INODE(page) && is_dent_dnode(page)) {
C
Chao Yu 已提交
272
				err = f2fs_recover_inode_page(sbi, page);
273
				if (err)
274
					break;
C
Chao Yu 已提交
275
				quota_inode = true;
276 277
			}

278 279 280 281
			/*
			 * CP | dnode(F) | inode(DF)
			 * For this case, we should not give up now.
			 */
C
Chao Yu 已提交
282 283
			entry = add_fsync_inode(sbi, head, ino_of_node(page),
								quota_inode);
284 285
			if (IS_ERR(entry)) {
				err = PTR_ERR(entry);
286 287
				if (err == -ENOENT) {
					err = 0;
288
					goto next;
289
				}
290
				break;
291 292
			}
		}
J
Jaegeuk Kim 已提交
293 294
		entry->blkaddr = blkaddr;

295 296
		if (IS_INODE(page) && is_dent_dnode(page))
			entry->last_dentry = blkaddr;
297
next:
298 299 300 301 302 303 304 305 306 307 308
		/* sanity check in order to detect looped node chain */
		if (++loop_cnt >= free_blocks ||
			blkaddr == next_blkaddr_of_node(page)) {
			f2fs_msg(sbi->sb, KERN_NOTICE,
				"%s: detect looped node chain, "
				"blkaddr:%u, next:%u",
				__func__, blkaddr, next_blkaddr_of_node(page));
			err = -EINVAL;
			break;
		}

309 310
		/* check next segment */
		blkaddr = next_blkaddr_of_node(page);
311
		f2fs_put_page(page, 1);
312

C
Chao Yu 已提交
313
		f2fs_ra_meta_pages_cond(sbi, blkaddr);
314
	}
315
	f2fs_put_page(page, 1);
316 317 318
	return err;
}

319
static void destroy_fsync_dnodes(struct list_head *head)
320
{
321 322
	struct fsync_inode_entry *entry, *tmp;

323 324
	list_for_each_entry_safe(entry, tmp, head, list)
		del_fsync_inode(entry);
325 326
}

327
static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
328
			block_t blkaddr, struct dnode_of_data *dn)
329 330 331
{
	struct seg_entry *sentry;
	unsigned int segno = GET_SEGNO(sbi, blkaddr);
J
Jaegeuk Kim 已提交
332
	unsigned short blkoff = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
J
Jaegeuk Kim 已提交
333
	struct f2fs_summary_block *sum_node;
334
	struct f2fs_summary sum;
J
Jaegeuk Kim 已提交
335
	struct page *sum_page, *node_page;
336
	struct dnode_of_data tdn = *dn;
337
	nid_t ino, nid;
338
	struct inode *inode;
339
	unsigned int offset;
340 341 342 343 344
	block_t bidx;
	int i;

	sentry = get_seg_entry(sbi, segno);
	if (!f2fs_test_bit(blkoff, sentry->cur_valid_map))
345
		return 0;
346 347

	/* Get the previous summary */
348
	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
349 350 351
		struct curseg_info *curseg = CURSEG_I(sbi, i);
		if (curseg->segno == segno) {
			sum = curseg->sum_blk->entries[blkoff];
J
Jaegeuk Kim 已提交
352
			goto got_it;
353 354 355
		}
	}

C
Chao Yu 已提交
356
	sum_page = f2fs_get_sum_page(sbi, segno);
J
Jaegeuk Kim 已提交
357 358 359 360
	sum_node = (struct f2fs_summary_block *)page_address(sum_page);
	sum = sum_node->entries[blkoff];
	f2fs_put_page(sum_page, 1);
got_it:
361 362 363 364
	/* Use the locked dnode page and inode */
	nid = le32_to_cpu(sum.nid);
	if (dn->inode->i_ino == nid) {
		tdn.nid = nid;
365 366
		if (!dn->inode_page_locked)
			lock_page(dn->inode_page);
367
		tdn.node_page = dn->inode_page;
368
		tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node);
369
		goto truncate_out;
370
	} else if (dn->nid == nid) {
371
		tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node);
372
		goto truncate_out;
373 374
	}

375
	/* Get the node page */
C
Chao Yu 已提交
376
	node_page = f2fs_get_node_page(sbi, nid);
377 378
	if (IS_ERR(node_page))
		return PTR_ERR(node_page);
379 380

	offset = ofs_of_node(node_page);
381 382 383
	ino = ino_of_node(node_page);
	f2fs_put_page(node_page, 1);

384
	if (ino != dn->inode->i_ino) {
C
Chao Yu 已提交
385 386
		int ret;

387
		/* Deallocate previous index in the node page */
388
		inode = f2fs_iget_retry(sbi->sb, ino);
389 390
		if (IS_ERR(inode))
			return PTR_ERR(inode);
C
Chao Yu 已提交
391 392 393 394 395 396

		ret = dquot_initialize(inode);
		if (ret) {
			iput(inode);
			return ret;
		}
397 398 399
	} else {
		inode = dn->inode;
	}
400

C
Chao Yu 已提交
401 402
	bidx = f2fs_start_bidx_of_node(offset, inode) +
				le16_to_cpu(sum.ofs_in_node);
403

404 405 406 407 408 409 410 411
	/*
	 * if inode page is locked, unlock temporarily, but its reference
	 * count keeps alive.
	 */
	if (ino == dn->inode->i_ino && dn->inode_page_locked)
		unlock_page(dn->inode_page);

	set_new_dnode(&tdn, inode, NULL, NULL, 0);
C
Chao Yu 已提交
412
	if (f2fs_get_dnode_of_data(&tdn, bidx, LOOKUP_NODE))
413 414 415
		goto out;

	if (tdn.data_blkaddr == blkaddr)
C
Chao Yu 已提交
416
		f2fs_truncate_data_blocks_range(&tdn, 1);
417 418 419 420

	f2fs_put_dnode(&tdn);
out:
	if (ino != dn->inode->i_ino)
421
		iput(inode);
422 423 424 425 426
	else if (dn->inode_page_locked)
		lock_page(dn->inode_page);
	return 0;

truncate_out:
427 428
	if (datablock_addr(tdn.inode, tdn.node_page,
					tdn.ofs_in_node) == blkaddr)
C
Chao Yu 已提交
429
		f2fs_truncate_data_blocks_range(&tdn, 1);
430 431
	if (dn->inode->i_ino == nid && !dn->inode_page_locked)
		unlock_page(dn->inode_page);
432
	return 0;
433 434
}

435
static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
S
Sheng Yong 已提交
436
					struct page *page)
437 438 439
{
	struct dnode_of_data dn;
	struct node_info ni;
440
	unsigned int start, end;
441
	int err = 0, recovered = 0;
442

443 444
	/* step 1: recover xattr */
	if (IS_INODE(page)) {
C
Chao Yu 已提交
445
		f2fs_recover_inline_xattr(inode, page);
446
	} else if (f2fs_has_xattr_block(ofs_of_node(page))) {
C
Chao Yu 已提交
447
		err = f2fs_recover_xattr_data(inode, page);
448 449
		if (!err)
			recovered++;
450
		goto out;
451
	}
452

453
	/* step 2: recover inline data */
C
Chao Yu 已提交
454
	if (f2fs_recover_inline_data(inode, page))
455 456
		goto out;

457
	/* step 3: recover data indices */
C
Chao Yu 已提交
458
	start = f2fs_start_bidx_of_node(ofs_of_node(page), inode);
459
	end = start + ADDRS_PER_PAGE(page, inode);
460 461

	set_new_dnode(&dn, inode, NULL, NULL, 0);
462
retry_dn:
C
Chao Yu 已提交
463
	err = f2fs_get_dnode_of_data(&dn, start, ALLOC_NODE);
464 465 466 467 468
	if (err) {
		if (err == -ENOMEM) {
			congestion_wait(BLK_RW_ASYNC, HZ/50);
			goto retry_dn;
		}
469
		goto out;
470
	}
471

472
	f2fs_wait_on_page_writeback(dn.node_page, NODE, true);
473

C
Chao Yu 已提交
474
	f2fs_get_node_info(sbi, dn.nid, &ni);
475 476
	f2fs_bug_on(sbi, ni.ino != ino_of_node(page));
	f2fs_bug_on(sbi, ofs_of_node(dn.node_page) != ofs_of_node(page));
477

478
	for (; start < end; start++, dn.ofs_in_node++) {
479 480
		block_t src, dest;

481 482
		src = datablock_addr(dn.inode, dn.node_page, dn.ofs_in_node);
		dest = datablock_addr(dn.inode, page, dn.ofs_in_node);
483

484 485 486 487 488 489
		/* skip recovering if dest is the same as src */
		if (src == dest)
			continue;

		/* dest is invalid, just invalidate src block */
		if (dest == NULL_ADDR) {
C
Chao Yu 已提交
490
			f2fs_truncate_data_blocks_range(&dn, 1);
491 492 493
			continue;
		}

494
		if (!file_keep_isize(inode) &&
495 496 497
			(i_size_read(inode) <= ((loff_t)start << PAGE_SHIFT)))
			f2fs_i_size_write(inode,
				(loff_t)(start + 1) << PAGE_SHIFT);
498

499 500 501 502 503
		/*
		 * dest is reserved block, invalidate src block
		 * and then reserve one new block in dnode page.
		 */
		if (dest == NEW_ADDR) {
C
Chao Yu 已提交
504 505
			f2fs_truncate_data_blocks_range(&dn, 1);
			f2fs_reserve_new_block(&dn);
506 507 508 509
			continue;
		}

		/* dest is valid block, try to recover from src to dest */
510
		if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) {
511

512
			if (src == NULL_ADDR) {
C
Chao Yu 已提交
513
				err = f2fs_reserve_new_block(&dn);
514 515
#ifdef CONFIG_F2FS_FAULT_INJECTION
				while (err)
C
Chao Yu 已提交
516
					err = f2fs_reserve_new_block(&dn);
517
#endif
518
				/* We should not get -ENOSPC */
519
				f2fs_bug_on(sbi, err);
520 521
				if (err)
					goto err;
522
			}
523
retry_prev:
524
			/* Check the previous node page having this index */
525
			err = check_index_in_prev_nodes(sbi, dest, &dn);
526 527 528 529 530
			if (err) {
				if (err == -ENOMEM) {
					congestion_wait(BLK_RW_ASYNC, HZ/50);
					goto retry_prev;
				}
531
				goto err;
532
			}
533 534

			/* write dummy data page */
535
			f2fs_replace_block(sbi, &dn, src, dest,
536
						ni.version, false, false);
537
			recovered++;
538 539 540 541 542 543 544
		}
	}

	copy_node_footer(dn.node_page, page);
	fill_node_footer(dn.node_page, dn.nid, ni.ino,
					ofs_of_node(page), false);
	set_page_dirty(dn.node_page);
545
err:
546
	f2fs_put_dnode(&dn);
547
out:
C
Chris Fries 已提交
548
	f2fs_msg(sbi->sb, KERN_NOTICE,
549 550 551 552
		"recover_data: ino = %lx (i_size: %s) recovered = %d, err = %d",
		inode->i_ino,
		file_keep_isize(inode) ? "keep" : "recover",
		recovered, err);
553
	return err;
554 555
}

C
Chao Yu 已提交
556 557
static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
						struct list_head *dir_list)
558 559
{
	struct curseg_info *curseg;
560
	struct page *page = NULL;
561
	int err = 0;
562 563 564
	block_t blkaddr;

	/* get node pages in the current segment */
C
Chao Yu 已提交
565
	curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
566 567 568 569 570
	blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);

	while (1) {
		struct fsync_inode_entry *entry;

571
		if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR))
572
			break;
573

C
Chao Yu 已提交
574
		f2fs_ra_meta_pages_cond(sbi, blkaddr);
575

C
Chao Yu 已提交
576
		page = f2fs_get_tmp_page(sbi, blkaddr);
577

578
		if (!is_recoverable_dnode(page)) {
579
			f2fs_put_page(page, 1);
580
			break;
581
		}
582

C
Chao Yu 已提交
583
		entry = get_fsync_inode(inode_list, ino_of_node(page));
584 585
		if (!entry)
			goto next;
586 587 588
		/*
		 * inode(x) | CP | inode(x) | dnode(F)
		 * In this case, we can lose the latest inode(x).
589
		 * So, call recover_inode for the inode update.
590
		 */
591
		if (IS_INODE(page))
592 593
			recover_inode(entry->inode, page);
		if (entry->last_dentry == blkaddr) {
C
Chao Yu 已提交
594
			err = recover_dentry(entry->inode, page, dir_list);
595 596 597 598 599
			if (err) {
				f2fs_put_page(page, 1);
				break;
			}
		}
S
Sheng Yong 已提交
600
		err = do_recover_data(sbi, entry->inode, page);
601 602
		if (err) {
			f2fs_put_page(page, 1);
603
			break;
604
		}
605

606 607
		if (entry->blkaddr == blkaddr)
			del_fsync_inode(entry);
608 609 610
next:
		/* check next segment */
		blkaddr = next_blkaddr_of_node(page);
611
		f2fs_put_page(page, 1);
612
	}
613
	if (!err)
C
Chao Yu 已提交
614
		f2fs_allocate_new_segments(sbi);
615
	return err;
616 617
}

C
Chao Yu 已提交
618
int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
619 620
{
	struct list_head inode_list;
C
Chao Yu 已提交
621
	struct list_head dir_list;
622
	int err;
623
	int ret = 0;
C
Chao Yu 已提交
624
	unsigned long s_flags = sbi->sb->s_flags;
H
Haicheng Li 已提交
625
	bool need_writecp = false;
J
Jaegeuk Kim 已提交
626 627 628
#ifdef CONFIG_QUOTA
	int quota_enabled;
#endif
629

630
	if (s_flags & SB_RDONLY) {
C
Chao Yu 已提交
631
		f2fs_msg(sbi->sb, KERN_INFO, "orphan cleanup on readonly fs");
632
		sbi->sb->s_flags &= ~SB_RDONLY;
C
Chao Yu 已提交
633 634 635 636
	}

#ifdef CONFIG_QUOTA
	/* Needed for iput() to work correctly and not trash data */
637
	sbi->sb->s_flags |= SB_ACTIVE;
C
Chao Yu 已提交
638
	/* Turn on quotas so that they are updated correctly */
639
	quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY);
C
Chao Yu 已提交
640 641
#endif

642
	fsync_entry_slab = f2fs_kmem_cache_create("f2fs_fsync_inode_entry",
643
			sizeof(struct fsync_inode_entry));
C
Chao Yu 已提交
644 645 646 647
	if (!fsync_entry_slab) {
		err = -ENOMEM;
		goto out;
	}
648 649

	INIT_LIST_HEAD(&inode_list);
C
Chao Yu 已提交
650
	INIT_LIST_HEAD(&dir_list);
651

652 653 654
	/* prevent checkpoint */
	mutex_lock(&sbi->cp_mutex);

655
	/* step #1: find fsynced inode numbers */
656
	err = find_fsync_dnodes(sbi, &inode_list, check_only);
657
	if (err || list_empty(&inode_list))
C
Chao Yu 已提交
658
		goto skip;
659

660 661
	if (check_only) {
		ret = 1;
C
Chao Yu 已提交
662
		goto skip;
663
	}
664

H
Haicheng Li 已提交
665
	need_writecp = true;
666

667
	/* step #2: recover data */
C
Chao Yu 已提交
668
	err = recover_data(sbi, &inode_list, &dir_list);
669
	if (!err)
670
		f2fs_bug_on(sbi, !list_empty(&inode_list));
C
Chao Yu 已提交
671
skip:
672
	destroy_fsync_dnodes(&inode_list);
673

674 675
	/* truncate meta pages to be used by the recovery */
	truncate_inode_pages_range(META_MAPPING(sbi),
676
			(loff_t)MAIN_BLKADDR(sbi) << PAGE_SHIFT, -1);
677

678 679 680 681 682
	if (err) {
		truncate_inode_pages_final(NODE_MAPPING(sbi));
		truncate_inode_pages_final(META_MAPPING(sbi));
	}

683
	clear_sbi_flag(sbi, SBI_POR_DOING);
684 685
	mutex_unlock(&sbi->cp_mutex);

686 687 688
	/* let's drop all the directory inodes for clean checkpoint */
	destroy_fsync_dnodes(&dir_list);

689
	if (!err && need_writecp) {
690
		struct cp_control cpc = {
691
			.reason = CP_RECOVERY,
692
		};
C
Chao Yu 已提交
693
		err = f2fs_write_checkpoint(sbi, &cpc);
694
	}
C
Chao Yu 已提交
695 696

	kmem_cache_destroy(fsync_entry_slab);
C
Chao Yu 已提交
697 698 699
out:
#ifdef CONFIG_QUOTA
	/* Turn quotas off */
J
Jaegeuk Kim 已提交
700 701
	if (quota_enabled)
		f2fs_quota_off_umount(sbi->sb);
C
Chao Yu 已提交
702
#endif
703
	sbi->sb->s_flags = s_flags; /* Restore SB_RDONLY status */
C
Chao Yu 已提交
704

705
	return ret ? ret: err;
706
}