recovery.c (27fd38c5226ed0f1712d071880fa8e739eb78650) recovery.c (41382ec43255b502321c3c27f1347efeb3279290)
1/*
2 * fs/f2fs/recovery.c
3 *
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as

--- 35 unchanged lines hidden (view full) ---

44 * -> If f2fs_iget fails, then goto next to find inode(DF).
45 * But it will fail due to no inode(DF).
46 */
47
48static struct kmem_cache *fsync_entry_slab;
49
50bool space_for_roll_forward(struct f2fs_sb_info *sbi)
51{
1/*
2 * fs/f2fs/recovery.c
3 *
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as

--- 35 unchanged lines hidden (view full) ---

44 * -> If f2fs_iget fails, then goto next to find inode(DF).
45 * But it will fail due to no inode(DF).
46 */
47
48static struct kmem_cache *fsync_entry_slab;
49
50bool space_for_roll_forward(struct f2fs_sb_info *sbi)
51{
52 if (sbi->last_valid_block_count + sbi->alloc_valid_block_count
53 > sbi->user_block_count)
52 s64 nalloc = percpu_counter_sum_positive(&sbi->alloc_valid_block_count);
53
54 if (sbi->last_valid_block_count + nalloc > sbi->user_block_count)
54 return false;
55 return true;
56}
57
58static struct fsync_inode_entry *get_fsync_inode(struct list_head *head,
59 nid_t ino)
60{
61 struct fsync_inode_entry *entry;
62
63 list_for_each_entry(entry, head, list)
64 if (entry->inode->i_ino == ino)
65 return entry;
66
67 return NULL;
68}
69
55 return false;
56 return true;
57}
58
59static struct fsync_inode_entry *get_fsync_inode(struct list_head *head,
60 nid_t ino)
61{
62 struct fsync_inode_entry *entry;
63
64 list_for_each_entry(entry, head, list)
65 if (entry->inode->i_ino == ino)
66 return entry;
67
68 return NULL;
69}
70
70static int recover_dentry(struct inode *inode, struct page *ipage)
71static struct fsync_inode_entry *add_fsync_inode(struct list_head *head,
72 struct inode *inode)
71{
73{
74 struct fsync_inode_entry *entry;
75
76 entry = kmem_cache_alloc(fsync_entry_slab, GFP_F2FS_ZERO);
77 if (!entry)
78 return NULL;
79
80 entry->inode = inode;
81 list_add_tail(&entry->list, head);
82
83 return entry;
84}
85
86static void del_fsync_inode(struct fsync_inode_entry *entry)
87{
88 iput(entry->inode);
89 list_del(&entry->list);
90 kmem_cache_free(fsync_entry_slab, entry);
91}
92
93static int recover_dentry(struct inode *inode, struct page *ipage,
94 struct list_head *dir_list)
95{
72 struct f2fs_inode *raw_inode = F2FS_INODE(ipage);
73 nid_t pino = le32_to_cpu(raw_inode->i_pino);
74 struct f2fs_dir_entry *de;
75 struct qstr name;
76 struct page *page;
77 struct inode *dir, *einode;
96 struct f2fs_inode *raw_inode = F2FS_INODE(ipage);
97 nid_t pino = le32_to_cpu(raw_inode->i_pino);
98 struct f2fs_dir_entry *de;
99 struct qstr name;
100 struct page *page;
101 struct inode *dir, *einode;
102 struct fsync_inode_entry *entry;
78 int err = 0;
79
103 int err = 0;
104
80 dir = f2fs_iget(inode->i_sb, pino);
81 if (IS_ERR(dir)) {
82 err = PTR_ERR(dir);
83 goto out;
105 entry = get_fsync_inode(dir_list, pino);
106 if (!entry) {
107 dir = f2fs_iget(inode->i_sb, pino);
108 if (IS_ERR(dir)) {
109 err = PTR_ERR(dir);
110 goto out;
111 }
112
113 entry = add_fsync_inode(dir_list, dir);
114 if (!entry) {
115 err = -ENOMEM;
116 iput(dir);
117 goto out;
118 }
84 }
85
119 }
120
86 if (file_enc_name(inode)) {
87 iput(dir);
121 dir = entry->inode;
122
123 if (file_enc_name(inode))
88 return 0;
124 return 0;
89 }
90
91 name.len = le32_to_cpu(raw_inode->i_namelen);
92 name.name = raw_inode->i_name;
93
94 if (unlikely(name.len > F2FS_NAME_LEN)) {
95 WARN_ON(1);
96 err = -ENAMETOOLONG;
125
126 name.len = le32_to_cpu(raw_inode->i_namelen);
127 name.name = raw_inode->i_name;
128
129 if (unlikely(name.len > F2FS_NAME_LEN)) {
130 WARN_ON(1);
131 err = -ENAMETOOLONG;
97 goto out_err;
132 goto out;
98 }
99retry:
100 de = f2fs_find_entry(dir, &name, &page);
101 if (de && inode->i_ino == le32_to_cpu(de->ino))
102 goto out_unmap_put;
103
104 if (de) {
105 einode = f2fs_iget(inode->i_sb, le32_to_cpu(de->ino));

--- 9 unchanged lines hidden (view full) ---

115 iput(einode);
116 goto out_unmap_put;
117 }
118 f2fs_delete_entry(de, page, dir, einode);
119 iput(einode);
120 goto retry;
121 }
122 err = __f2fs_add_link(dir, &name, inode, inode->i_ino, inode->i_mode);
133 }
134retry:
135 de = f2fs_find_entry(dir, &name, &page);
136 if (de && inode->i_ino == le32_to_cpu(de->ino))
137 goto out_unmap_put;
138
139 if (de) {
140 einode = f2fs_iget(inode->i_sb, le32_to_cpu(de->ino));

--- 9 unchanged lines hidden (view full) ---

150 iput(einode);
151 goto out_unmap_put;
152 }
153 f2fs_delete_entry(de, page, dir, einode);
154 iput(einode);
155 goto retry;
156 }
157 err = __f2fs_add_link(dir, &name, inode, inode->i_ino, inode->i_mode);
123 if (err)
124 goto out_err;
125
158
126 if (is_inode_flag_set(F2FS_I(dir), FI_DELAY_IPUT)) {
127 iput(dir);
128 } else {
129 add_dirty_dir_inode(dir);
130 set_inode_flag(F2FS_I(dir), FI_DELAY_IPUT);
131 }
132
133 goto out;
134
135out_unmap_put:
136 f2fs_dentry_kunmap(dir, page);
137 f2fs_put_page(page, 0);
159 goto out;
160
161out_unmap_put:
162 f2fs_dentry_kunmap(dir, page);
163 f2fs_put_page(page, 0);
138out_err:
139 iput(dir);
140out:
141 f2fs_msg(inode->i_sb, KERN_NOTICE,
142 "%s: ino = %x, name = %s, dir = %lx, err = %d",
143 __func__, ino_of_node(ipage), raw_inode->i_name,
144 IS_ERR(dir) ? 0 : dir->i_ino, err);
145 return err;
146}
147

--- 45 unchanged lines hidden (view full) ---

193
194 return true;
195}
196
197static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
198{
199 unsigned long long cp_ver = cur_cp_version(F2FS_CKPT(sbi));
200 struct curseg_info *curseg;
164out:
165 f2fs_msg(inode->i_sb, KERN_NOTICE,
166 "%s: ino = %x, name = %s, dir = %lx, err = %d",
167 __func__, ino_of_node(ipage), raw_inode->i_name,
168 IS_ERR(dir) ? 0 : dir->i_ino, err);
169 return err;
170}
171

--- 45 unchanged lines hidden (view full) ---

217
218 return true;
219}
220
221static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
222{
223 unsigned long long cp_ver = cur_cp_version(F2FS_CKPT(sbi));
224 struct curseg_info *curseg;
225 struct inode *inode;
201 struct page *page = NULL;
202 block_t blkaddr;
203 int err = 0;
204
205 /* get node pages in the current segment */
206 curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
207 blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
208
226 struct page *page = NULL;
227 block_t blkaddr;
228 int err = 0;
229
230 /* get node pages in the current segment */
231 curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
232 blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
233
209 ra_meta_pages(sbi, blkaddr, 1, META_POR, true);
210
211 while (1) {
212 struct fsync_inode_entry *entry;
213
214 if (!is_valid_blkaddr(sbi, blkaddr, META_POR))
215 return 0;
216
217 page = get_tmp_page(sbi, blkaddr);
218

--- 9 unchanged lines hidden (view full) ---

228 goto next;
229 } else {
230 if (IS_INODE(page) && is_dent_dnode(page)) {
231 err = recover_inode_page(sbi, page);
232 if (err)
233 break;
234 }
235
234 while (1) {
235 struct fsync_inode_entry *entry;
236
237 if (!is_valid_blkaddr(sbi, blkaddr, META_POR))
238 return 0;
239
240 page = get_tmp_page(sbi, blkaddr);
241

--- 9 unchanged lines hidden (view full) ---

251 goto next;
252 } else {
253 if (IS_INODE(page) && is_dent_dnode(page)) {
254 err = recover_inode_page(sbi, page);
255 if (err)
256 break;
257 }
258
236 /* add this fsync inode to the list */
237 entry = kmem_cache_alloc(fsync_entry_slab, GFP_F2FS_ZERO);
238 if (!entry) {
239 err = -ENOMEM;
240 break;
241 }
242 /*
243 * CP | dnode(F) | inode(DF)
244 * For this case, we should not give up now.
245 */
259 /*
260 * CP | dnode(F) | inode(DF)
261 * For this case, we should not give up now.
262 */
246 entry->inode = f2fs_iget(sbi->sb, ino_of_node(page));
247 if (IS_ERR(entry->inode)) {
248 err = PTR_ERR(entry->inode);
249 kmem_cache_free(fsync_entry_slab, entry);
263 inode = f2fs_iget(sbi->sb, ino_of_node(page));
264 if (IS_ERR(inode)) {
265 err = PTR_ERR(inode);
250 if (err == -ENOENT) {
251 err = 0;
252 goto next;
253 }
254 break;
255 }
266 if (err == -ENOENT) {
267 err = 0;
268 goto next;
269 }
270 break;
271 }
256 list_add_tail(&entry->list, head);
272
273 /* add this fsync inode to the list */
274 entry = add_fsync_inode(head, inode);
275 if (!entry) {
276 err = -ENOMEM;
277 iput(inode);
278 break;
279 }
257 }
258 entry->blkaddr = blkaddr;
259
280 }
281 entry->blkaddr = blkaddr;
282
260 if (IS_INODE(page)) {
261 entry->last_inode = blkaddr;
262 if (is_dent_dnode(page))
263 entry->last_dentry = blkaddr;
264 }
283 if (IS_INODE(page) && is_dent_dnode(page))
284 entry->last_dentry = blkaddr;
265next:
266 /* check next segment */
267 blkaddr = next_blkaddr_of_node(page);
268 f2fs_put_page(page, 1);
269
270 ra_meta_pages_cond(sbi, blkaddr);
271 }
272 f2fs_put_page(page, 1);
273 return err;
274}
275
276static void destroy_fsync_dnodes(struct list_head *head)
277{
278 struct fsync_inode_entry *entry, *tmp;
279
285next:
286 /* check next segment */
287 blkaddr = next_blkaddr_of_node(page);
288 f2fs_put_page(page, 1);
289
290 ra_meta_pages_cond(sbi, blkaddr);
291 }
292 f2fs_put_page(page, 1);
293 return err;
294}
295
296static void destroy_fsync_dnodes(struct list_head *head)
297{
298 struct fsync_inode_entry *entry, *tmp;
299
280 list_for_each_entry_safe(entry, tmp, head, list) {
281 iput(entry->inode);
282 list_del(&entry->list);
283 kmem_cache_free(fsync_entry_slab, entry);
284 }
300 list_for_each_entry_safe(entry, tmp, head, list)
301 del_fsync_inode(entry);
285}
286
287static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
288 block_t blkaddr, struct dnode_of_data *dn)
289{
290 struct seg_entry *sentry;
291 unsigned int segno = GET_SEGNO(sbi, blkaddr);
292 unsigned short blkoff = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);

--- 146 unchanged lines hidden (view full) ---

439 }
440
441 /*
442 * dest is reserved block, invalidate src block
443 * and then reserve one new block in dnode page.
444 */
445 if (dest == NEW_ADDR) {
446 truncate_data_blocks_range(&dn, 1);
302}
303
304static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
305 block_t blkaddr, struct dnode_of_data *dn)
306{
307 struct seg_entry *sentry;
308 unsigned int segno = GET_SEGNO(sbi, blkaddr);
309 unsigned short blkoff = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);

--- 146 unchanged lines hidden (view full) ---

456 }
457
458 /*
459 * dest is reserved block, invalidate src block
460 * and then reserve one new block in dnode page.
461 */
462 if (dest == NEW_ADDR) {
463 truncate_data_blocks_range(&dn, 1);
447 err = reserve_new_block(&dn);
448 f2fs_bug_on(sbi, err);
464 reserve_new_block(&dn);
449 continue;
450 }
451
452 /* dest is valid block, try to recover from src to dest */
453 if (is_valid_blkaddr(sbi, dest, META_POR)) {
454
455 if (src == NULL_ADDR) {
456 err = reserve_new_block(&dn);

--- 24 unchanged lines hidden (view full) ---

481 f2fs_put_dnode(&dn);
482out:
483 f2fs_msg(sbi->sb, KERN_NOTICE,
484 "recover_data: ino = %lx, recovered = %d blocks, err = %d",
485 inode->i_ino, recovered, err);
486 return err;
487}
488
465 continue;
466 }
467
468 /* dest is valid block, try to recover from src to dest */
469 if (is_valid_blkaddr(sbi, dest, META_POR)) {
470
471 if (src == NULL_ADDR) {
472 err = reserve_new_block(&dn);

--- 24 unchanged lines hidden (view full) ---

497 f2fs_put_dnode(&dn);
498out:
499 f2fs_msg(sbi->sb, KERN_NOTICE,
500 "recover_data: ino = %lx, recovered = %d blocks, err = %d",
501 inode->i_ino, recovered, err);
502 return err;
503}
504
489static int recover_data(struct f2fs_sb_info *sbi, struct list_head *head)
505static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
506 struct list_head *dir_list)
490{
491 unsigned long long cp_ver = cur_cp_version(F2FS_CKPT(sbi));
492 struct curseg_info *curseg;
493 struct page *page = NULL;
494 int err = 0;
495 block_t blkaddr;
496
497 /* get node pages in the current segment */

--- 10 unchanged lines hidden (view full) ---

508
509 page = get_tmp_page(sbi, blkaddr);
510
511 if (cp_ver != cpver_of_node(page)) {
512 f2fs_put_page(page, 1);
513 break;
514 }
515
507{
508 unsigned long long cp_ver = cur_cp_version(F2FS_CKPT(sbi));
509 struct curseg_info *curseg;
510 struct page *page = NULL;
511 int err = 0;
512 block_t blkaddr;
513
514 /* get node pages in the current segment */

--- 10 unchanged lines hidden (view full) ---

525
526 page = get_tmp_page(sbi, blkaddr);
527
528 if (cp_ver != cpver_of_node(page)) {
529 f2fs_put_page(page, 1);
530 break;
531 }
532
516 entry = get_fsync_inode(head, ino_of_node(page));
533 entry = get_fsync_inode(inode_list, ino_of_node(page));
517 if (!entry)
518 goto next;
519 /*
520 * inode(x) | CP | inode(x) | dnode(F)
521 * In this case, we can lose the latest inode(x).
522 * So, call recover_inode for the inode update.
523 */
534 if (!entry)
535 goto next;
536 /*
537 * inode(x) | CP | inode(x) | dnode(F)
538 * In this case, we can lose the latest inode(x).
539 * So, call recover_inode for the inode update.
540 */
524 if (entry->last_inode == blkaddr)
541 if (IS_INODE(page))
525 recover_inode(entry->inode, page);
526 if (entry->last_dentry == blkaddr) {
542 recover_inode(entry->inode, page);
543 if (entry->last_dentry == blkaddr) {
527 err = recover_dentry(entry->inode, page);
544 err = recover_dentry(entry->inode, page, dir_list);
528 if (err) {
529 f2fs_put_page(page, 1);
530 break;
531 }
532 }
533 err = do_recover_data(sbi, entry->inode, page, blkaddr);
534 if (err) {
535 f2fs_put_page(page, 1);
536 break;
537 }
538
545 if (err) {
546 f2fs_put_page(page, 1);
547 break;
548 }
549 }
550 err = do_recover_data(sbi, entry->inode, page, blkaddr);
551 if (err) {
552 f2fs_put_page(page, 1);
553 break;
554 }
555
539 if (entry->blkaddr == blkaddr) {
540 iput(entry->inode);
541 list_del(&entry->list);
542 kmem_cache_free(fsync_entry_slab, entry);
543 }
556 if (entry->blkaddr == blkaddr)
557 del_fsync_inode(entry);
544next:
545 /* check next segment */
546 blkaddr = next_blkaddr_of_node(page);
547 f2fs_put_page(page, 1);
548 }
549 if (!err)
550 allocate_new_segments(sbi);
551 return err;
552}
553
558next:
559 /* check next segment */
560 blkaddr = next_blkaddr_of_node(page);
561 f2fs_put_page(page, 1);
562 }
563 if (!err)
564 allocate_new_segments(sbi);
565 return err;
566}
567
554int recover_fsync_data(struct f2fs_sb_info *sbi)
568int recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
555{
556 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
557 struct list_head inode_list;
569{
570 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
571 struct list_head inode_list;
572 struct list_head dir_list;
558 block_t blkaddr;
559 int err;
573 block_t blkaddr;
574 int err;
575 int ret = 0;
560 bool need_writecp = false;
561
562 fsync_entry_slab = f2fs_kmem_cache_create("f2fs_fsync_inode_entry",
563 sizeof(struct fsync_inode_entry));
564 if (!fsync_entry_slab)
565 return -ENOMEM;
566
567 INIT_LIST_HEAD(&inode_list);
576 bool need_writecp = false;
577
578 fsync_entry_slab = f2fs_kmem_cache_create("f2fs_fsync_inode_entry",
579 sizeof(struct fsync_inode_entry));
580 if (!fsync_entry_slab)
581 return -ENOMEM;
582
583 INIT_LIST_HEAD(&inode_list);
584 INIT_LIST_HEAD(&dir_list);
568
569 /* prevent checkpoint */
570 mutex_lock(&sbi->cp_mutex);
571
572 blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
573
574 /* step #1: find fsynced inode numbers */
575 err = find_fsync_dnodes(sbi, &inode_list);
585
586 /* prevent checkpoint */
587 mutex_lock(&sbi->cp_mutex);
588
589 blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
590
591 /* step #1: find fsynced inode numbers */
592 err = find_fsync_dnodes(sbi, &inode_list);
576 if (err)
593 if (err || list_empty(&inode_list))
577 goto out;
578
594 goto out;
595
579 if (list_empty(&inode_list))
596 if (check_only) {
597 ret = 1;
580 goto out;
598 goto out;
599 }
581
582 need_writecp = true;
583
584 /* step #2: recover data */
600
601 need_writecp = true;
602
603 /* step #2: recover data */
585 err = recover_data(sbi, &inode_list);
604 err = recover_data(sbi, &inode_list, &dir_list);
586 if (!err)
587 f2fs_bug_on(sbi, !list_empty(&inode_list));
588out:
589 destroy_fsync_dnodes(&inode_list);
605 if (!err)
606 f2fs_bug_on(sbi, !list_empty(&inode_list));
607out:
608 destroy_fsync_dnodes(&inode_list);
590 kmem_cache_destroy(fsync_entry_slab);
591
592 /* truncate meta pages to be used by the recovery */
593 truncate_inode_pages_range(META_MAPPING(sbi),
594 (loff_t)MAIN_BLKADDR(sbi) << PAGE_SHIFT, -1);
595
596 if (err) {
597 truncate_inode_pages_final(NODE_MAPPING(sbi));
598 truncate_inode_pages_final(META_MAPPING(sbi));

--- 21 unchanged lines hidden (view full) ---

620 struct cp_control cpc = {
621 .reason = CP_RECOVERY,
622 };
623 mutex_unlock(&sbi->cp_mutex);
624 err = write_checkpoint(sbi, &cpc);
625 } else {
626 mutex_unlock(&sbi->cp_mutex);
627 }
609
610 /* truncate meta pages to be used by the recovery */
611 truncate_inode_pages_range(META_MAPPING(sbi),
612 (loff_t)MAIN_BLKADDR(sbi) << PAGE_SHIFT, -1);
613
614 if (err) {
615 truncate_inode_pages_final(NODE_MAPPING(sbi));
616 truncate_inode_pages_final(META_MAPPING(sbi));

--- 21 unchanged lines hidden (view full) ---

638 struct cp_control cpc = {
639 .reason = CP_RECOVERY,
640 };
641 mutex_unlock(&sbi->cp_mutex);
642 err = write_checkpoint(sbi, &cpc);
643 } else {
644 mutex_unlock(&sbi->cp_mutex);
645 }
628 return err;
646
647 destroy_fsync_dnodes(&dir_list);
648 kmem_cache_destroy(fsync_entry_slab);
649 return ret ? ret: err;
629}
650}