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 --- |