recovery.c (c59400a68c53374179cdc5f99fa77afbd092dcf8) recovery.c (430f163b01888dc26696365d9c1053ba9d6c7d92)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * fs/f2fs/recovery.c
4 *
5 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
6 * http://www.samsung.com/
7 */
8#include <asm/unaligned.h>

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

41 *
42 * 8. CP | dnode(F) | inode(x)
43 * -> If f2fs_iget fails, then goto next to find inode(DF).
44 * But it will fail due to no inode(DF).
45 */
46
47static struct kmem_cache *fsync_entry_slab;
48
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * fs/f2fs/recovery.c
4 *
5 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
6 * http://www.samsung.com/
7 */
8#include <asm/unaligned.h>

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

41 *
42 * 8. CP | dnode(F) | inode(x)
43 * -> If f2fs_iget fails, then goto next to find inode(DF).
44 * But it will fail due to no inode(DF).
45 */
46
47static struct kmem_cache *fsync_entry_slab;
48
49#if IS_ENABLED(CONFIG_UNICODE)
49#ifdef CONFIG_UNICODE
50extern struct kmem_cache *f2fs_cf_name_slab;
51#endif
52
53bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi)
54{
55 s64 nalloc = percpu_counter_sum_positive(&sbi->alloc_valid_block_count);
56
57 if (sbi->last_valid_block_count + nalloc > sbi->user_block_count)

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

144 return -EINVAL;
145 fname->hash = get_unaligned((f2fs_hash_t *)
146 &raw_inode->i_name[fname->disk_name.len]);
147 } else if (IS_CASEFOLDED(dir)) {
148 err = f2fs_init_casefolded_name(dir, fname);
149 if (err)
150 return err;
151 f2fs_hash_filename(dir, fname);
50extern struct kmem_cache *f2fs_cf_name_slab;
51#endif
52
53bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi)
54{
55 s64 nalloc = percpu_counter_sum_positive(&sbi->alloc_valid_block_count);
56
57 if (sbi->last_valid_block_count + nalloc > sbi->user_block_count)

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

144 return -EINVAL;
145 fname->hash = get_unaligned((f2fs_hash_t *)
146 &raw_inode->i_name[fname->disk_name.len]);
147 } else if (IS_CASEFOLDED(dir)) {
148 err = f2fs_init_casefolded_name(dir, fname);
149 if (err)
150 return err;
151 f2fs_hash_filename(dir, fname);
152#if IS_ENABLED(CONFIG_UNICODE)
152#ifdef CONFIG_UNICODE
153 /* Case-sensitive match is fine for recovery */
154 kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name);
155 fname->cf_name.name = NULL;
156#endif
157 } else {
158 f2fs_hash_filename(dir, fname);
159 }
160 return 0;

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

338 else
339 name = F2FS_INODE(page)->i_name;
340
341 f2fs_notice(F2FS_I_SB(inode), "recover_inode: ino = %x, name = %s, inline = %x",
342 ino_of_node(page), name, raw->i_inline);
343 return 0;
344}
345
153 /* Case-sensitive match is fine for recovery */
154 kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name);
155 fname->cf_name.name = NULL;
156#endif
157 } else {
158 f2fs_hash_filename(dir, fname);
159 }
160 return 0;

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

338 else
339 name = F2FS_INODE(page)->i_name;
340
341 f2fs_notice(F2FS_I_SB(inode), "recover_inode: ino = %x, name = %s, inline = %x",
342 ino_of_node(page), name, raw->i_inline);
343 return 0;
344}
345
346static unsigned int adjust_por_ra_blocks(struct f2fs_sb_info *sbi,
347 unsigned int ra_blocks, unsigned int blkaddr,
348 unsigned int next_blkaddr)
349{
350 if (blkaddr + 1 == next_blkaddr)
351 ra_blocks = min_t(unsigned int, RECOVERY_MAX_RA_BLOCKS,
352 ra_blocks * 2);
353 else if (next_blkaddr % sbi->blocks_per_seg)
354 ra_blocks = max_t(unsigned int, RECOVERY_MIN_RA_BLOCKS,
355 ra_blocks / 2);
356 return ra_blocks;
357}
358
346static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
347 bool check_only)
348{
349 struct curseg_info *curseg;
350 struct page *page = NULL;
351 block_t blkaddr;
352 unsigned int loop_cnt = 0;
359static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
360 bool check_only)
361{
362 struct curseg_info *curseg;
363 struct page *page = NULL;
364 block_t blkaddr;
365 unsigned int loop_cnt = 0;
366 unsigned int ra_blocks = RECOVERY_MAX_RA_BLOCKS;
353 unsigned int free_blocks = MAIN_SEGS(sbi) * sbi->blocks_per_seg -
354 valid_user_blocks(sbi);
355 int err = 0;
356
357 /* get node pages in the current segment */
358 curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
359 blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
360

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

419 f2fs_notice(sbi, "%s: detect looped node chain, blkaddr:%u, next:%u",
420 __func__, blkaddr,
421 next_blkaddr_of_node(page));
422 f2fs_put_page(page, 1);
423 err = -EINVAL;
424 break;
425 }
426
367 unsigned int free_blocks = MAIN_SEGS(sbi) * sbi->blocks_per_seg -
368 valid_user_blocks(sbi);
369 int err = 0;
370
371 /* get node pages in the current segment */
372 curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
373 blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
374

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

433 f2fs_notice(sbi, "%s: detect looped node chain, blkaddr:%u, next:%u",
434 __func__, blkaddr,
435 next_blkaddr_of_node(page));
436 f2fs_put_page(page, 1);
437 err = -EINVAL;
438 break;
439 }
440
441 ra_blocks = adjust_por_ra_blocks(sbi, ra_blocks, blkaddr,
442 next_blkaddr_of_node(page));
443
427 /* check next segment */
428 blkaddr = next_blkaddr_of_node(page);
429 f2fs_put_page(page, 1);
430
444 /* check next segment */
445 blkaddr = next_blkaddr_of_node(page);
446 f2fs_put_page(page, 1);
447
431 f2fs_ra_meta_pages_cond(sbi, blkaddr);
448 f2fs_ra_meta_pages_cond(sbi, blkaddr, ra_blocks);
432 }
433 return err;
434}
435
436static void destroy_fsync_dnodes(struct list_head *head, int drop)
437{
438 struct fsync_inode_entry *entry, *tmp;
439

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

699
700static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
701 struct list_head *tmp_inode_list, struct list_head *dir_list)
702{
703 struct curseg_info *curseg;
704 struct page *page = NULL;
705 int err = 0;
706 block_t blkaddr;
449 }
450 return err;
451}
452
453static void destroy_fsync_dnodes(struct list_head *head, int drop)
454{
455 struct fsync_inode_entry *entry, *tmp;
456

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

716
717static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
718 struct list_head *tmp_inode_list, struct list_head *dir_list)
719{
720 struct curseg_info *curseg;
721 struct page *page = NULL;
722 int err = 0;
723 block_t blkaddr;
724 unsigned int ra_blocks = RECOVERY_MAX_RA_BLOCKS;
707
708 /* get node pages in the current segment */
709 curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
710 blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
711
712 while (1) {
713 struct fsync_inode_entry *entry;
714
715 if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR))
716 break;
717
725
726 /* get node pages in the current segment */
727 curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
728 blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
729
730 while (1) {
731 struct fsync_inode_entry *entry;
732
733 if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR))
734 break;
735
718 f2fs_ra_meta_pages_cond(sbi, blkaddr);
719
720 page = f2fs_get_tmp_page(sbi, blkaddr);
721 if (IS_ERR(page)) {
722 err = PTR_ERR(page);
723 break;
724 }
725
726 if (!is_recoverable_dnode(page)) {
727 f2fs_put_page(page, 1);

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

754 if (err) {
755 f2fs_put_page(page, 1);
756 break;
757 }
758
759 if (entry->blkaddr == blkaddr)
760 list_move_tail(&entry->list, tmp_inode_list);
761next:
736 page = f2fs_get_tmp_page(sbi, blkaddr);
737 if (IS_ERR(page)) {
738 err = PTR_ERR(page);
739 break;
740 }
741
742 if (!is_recoverable_dnode(page)) {
743 f2fs_put_page(page, 1);

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

770 if (err) {
771 f2fs_put_page(page, 1);
772 break;
773 }
774
775 if (entry->blkaddr == blkaddr)
776 list_move_tail(&entry->list, tmp_inode_list);
777next:
778 ra_blocks = adjust_por_ra_blocks(sbi, ra_blocks, blkaddr,
779 next_blkaddr_of_node(page));
780
762 /* check next segment */
763 blkaddr = next_blkaddr_of_node(page);
764 f2fs_put_page(page, 1);
781 /* check next segment */
782 blkaddr = next_blkaddr_of_node(page);
783 f2fs_put_page(page, 1);
784
785 f2fs_ra_meta_pages_cond(sbi, blkaddr, ra_blocks);
765 }
766 if (!err)
767 f2fs_allocate_new_segments(sbi);
768 return err;
769}
770
771int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
772{

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

791 quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY);
792#endif
793
794 INIT_LIST_HEAD(&inode_list);
795 INIT_LIST_HEAD(&tmp_inode_list);
796 INIT_LIST_HEAD(&dir_list);
797
798 /* prevent checkpoint */
786 }
787 if (!err)
788 f2fs_allocate_new_segments(sbi);
789 return err;
790}
791
792int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
793{

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

812 quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY);
813#endif
814
815 INIT_LIST_HEAD(&inode_list);
816 INIT_LIST_HEAD(&tmp_inode_list);
817 INIT_LIST_HEAD(&dir_list);
818
819 /* prevent checkpoint */
799 down_write(&sbi->cp_global_sem);
820 f2fs_down_write(&sbi->cp_global_sem);
800
801 /* step #1: find fsynced inode numbers */
802 err = find_fsync_dnodes(sbi, &inode_list, check_only);
803 if (err || list_empty(&inode_list))
804 goto skip;
805
806 if (check_only) {
807 ret = 1;

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

840 f2fs_sb_has_blkzoned(sbi)) {
841 err = f2fs_fix_curseg_write_pointer(sbi);
842 ret = err;
843 }
844
845 if (!err)
846 clear_sbi_flag(sbi, SBI_POR_DOING);
847
821
822 /* step #1: find fsynced inode numbers */
823 err = find_fsync_dnodes(sbi, &inode_list, check_only);
824 if (err || list_empty(&inode_list))
825 goto skip;
826
827 if (check_only) {
828 ret = 1;

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

861 f2fs_sb_has_blkzoned(sbi)) {
862 err = f2fs_fix_curseg_write_pointer(sbi);
863 ret = err;
864 }
865
866 if (!err)
867 clear_sbi_flag(sbi, SBI_POR_DOING);
868
848 up_write(&sbi->cp_global_sem);
869 f2fs_up_write(&sbi->cp_global_sem);
849
850 /* let's drop all the directory inodes for clean checkpoint */
851 destroy_fsync_dnodes(&dir_list, err);
852
853 if (need_writecp) {
854 set_sbi_flag(sbi, SBI_IS_RECOVERED);
855
856 if (!err) {

--- 30 unchanged lines hidden ---
870
871 /* let's drop all the directory inodes for clean checkpoint */
872 destroy_fsync_dnodes(&dir_list, err);
873
874 if (need_writecp) {
875 set_sbi_flag(sbi, SBI_IS_RECOVERED);
876
877 if (!err) {

--- 30 unchanged lines hidden ---