diff options
| -rw-r--r-- | fs/f2fs/checkpoint.c | 45 | ||||
| -rw-r--r-- | fs/f2fs/f2fs.h | 13 | ||||
| -rw-r--r-- | include/linux/f2fs_fs.h | 2 |
3 files changed, 53 insertions, 7 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index fe968c7bfc90..ecba8da3308b 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
| @@ -371,7 +371,9 @@ void recover_orphan_inodes(struct f2fs_sb_info *sbi) | |||
| 371 | return; | 371 | return; |
| 372 | 372 | ||
| 373 | sbi->por_doing = true; | 373 | sbi->por_doing = true; |
| 374 | start_blk = __start_cp_addr(sbi) + 1; | 374 | |
| 375 | start_blk = __start_cp_addr(sbi) + 1 + | ||
| 376 | le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload); | ||
| 375 | orphan_blkaddr = __start_sum_addr(sbi) - 1; | 377 | orphan_blkaddr = __start_sum_addr(sbi) - 1; |
| 376 | 378 | ||
| 377 | ra_meta_pages(sbi, start_blk, orphan_blkaddr, META_CP); | 379 | ra_meta_pages(sbi, start_blk, orphan_blkaddr, META_CP); |
| @@ -512,8 +514,11 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) | |||
| 512 | unsigned long blk_size = sbi->blocksize; | 514 | unsigned long blk_size = sbi->blocksize; |
| 513 | unsigned long long cp1_version = 0, cp2_version = 0; | 515 | unsigned long long cp1_version = 0, cp2_version = 0; |
| 514 | unsigned long long cp_start_blk_no; | 516 | unsigned long long cp_start_blk_no; |
| 517 | unsigned int cp_blks = 1 + le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload); | ||
| 518 | block_t cp_blk_no; | ||
| 519 | int i; | ||
| 515 | 520 | ||
| 516 | sbi->ckpt = kzalloc(blk_size, GFP_KERNEL); | 521 | sbi->ckpt = kzalloc(cp_blks * blk_size, GFP_KERNEL); |
| 517 | if (!sbi->ckpt) | 522 | if (!sbi->ckpt) |
| 518 | return -ENOMEM; | 523 | return -ENOMEM; |
| 519 | /* | 524 | /* |
| @@ -544,6 +549,23 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) | |||
| 544 | cp_block = (struct f2fs_checkpoint *)page_address(cur_page); | 549 | cp_block = (struct f2fs_checkpoint *)page_address(cur_page); |
| 545 | memcpy(sbi->ckpt, cp_block, blk_size); | 550 | memcpy(sbi->ckpt, cp_block, blk_size); |
| 546 | 551 | ||
| 552 | if (cp_blks <= 1) | ||
| 553 | goto done; | ||
| 554 | |||
| 555 | cp_blk_no = le32_to_cpu(fsb->cp_blkaddr); | ||
| 556 | if (cur_page == cp2) | ||
| 557 | cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg); | ||
| 558 | |||
| 559 | for (i = 1; i < cp_blks; i++) { | ||
| 560 | void *sit_bitmap_ptr; | ||
| 561 | unsigned char *ckpt = (unsigned char *)sbi->ckpt; | ||
| 562 | |||
| 563 | cur_page = get_meta_page(sbi, cp_blk_no + i); | ||
| 564 | sit_bitmap_ptr = page_address(cur_page); | ||
| 565 | memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); | ||
| 566 | f2fs_put_page(cur_page, 1); | ||
| 567 | } | ||
| 568 | done: | ||
| 547 | f2fs_put_page(cp1, 1); | 569 | f2fs_put_page(cp1, 1); |
| 548 | f2fs_put_page(cp2, 1); | 570 | f2fs_put_page(cp2, 1); |
| 549 | return 0; | 571 | return 0; |
| @@ -736,6 +758,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) | |||
| 736 | __u32 crc32 = 0; | 758 | __u32 crc32 = 0; |
| 737 | void *kaddr; | 759 | void *kaddr; |
| 738 | int i; | 760 | int i; |
| 761 | int cp_payload_blks = le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload); | ||
| 739 | 762 | ||
| 740 | /* | 763 | /* |
| 741 | * This avoids to conduct wrong roll-forward operations and uses | 764 | * This avoids to conduct wrong roll-forward operations and uses |
| @@ -786,16 +809,19 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) | |||
| 786 | 809 | ||
| 787 | orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1) | 810 | orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1) |
| 788 | / F2FS_ORPHANS_PER_BLOCK; | 811 | / F2FS_ORPHANS_PER_BLOCK; |
| 789 | ckpt->cp_pack_start_sum = cpu_to_le32(1 + orphan_blocks); | 812 | ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks + |
| 813 | orphan_blocks); | ||
| 790 | 814 | ||
| 791 | if (is_umount) { | 815 | if (is_umount) { |
| 792 | set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); | 816 | set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); |
| 793 | ckpt->cp_pack_total_block_count = cpu_to_le32(2 + | 817 | ckpt->cp_pack_total_block_count = cpu_to_le32(2 + |
| 794 | data_sum_blocks + orphan_blocks + NR_CURSEG_NODE_TYPE); | 818 | cp_payload_blks + data_sum_blocks + |
| 819 | orphan_blocks + NR_CURSEG_NODE_TYPE); | ||
| 795 | } else { | 820 | } else { |
| 796 | clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); | 821 | clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); |
| 797 | ckpt->cp_pack_total_block_count = cpu_to_le32(2 + | 822 | ckpt->cp_pack_total_block_count = cpu_to_le32(2 + |
| 798 | data_sum_blocks + orphan_blocks); | 823 | cp_payload_blks + data_sum_blocks + |
| 824 | orphan_blocks); | ||
| 799 | } | 825 | } |
| 800 | 826 | ||
| 801 | if (sbi->n_orphans) | 827 | if (sbi->n_orphans) |
| @@ -821,6 +847,15 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) | |||
| 821 | set_page_dirty(cp_page); | 847 | set_page_dirty(cp_page); |
| 822 | f2fs_put_page(cp_page, 1); | 848 | f2fs_put_page(cp_page, 1); |
| 823 | 849 | ||
| 850 | for (i = 1; i < 1 + cp_payload_blks; i++) { | ||
| 851 | cp_page = grab_meta_page(sbi, start_blk++); | ||
| 852 | kaddr = page_address(cp_page); | ||
| 853 | memcpy(kaddr, (char *)ckpt + i * F2FS_BLKSIZE, | ||
| 854 | (1 << sbi->log_blocksize)); | ||
| 855 | set_page_dirty(cp_page); | ||
| 856 | f2fs_put_page(cp_page, 1); | ||
| 857 | } | ||
| 858 | |||
| 824 | if (sbi->n_orphans) { | 859 | if (sbi->n_orphans) { |
| 825 | write_orphan_inodes(sbi, start_blk); | 860 | write_orphan_inodes(sbi, start_blk); |
| 826 | start_blk += orphan_blocks; | 861 | start_blk += orphan_blocks; |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 676a2c6ccec7..9684b1f77a7d 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
| @@ -764,9 +764,18 @@ static inline unsigned long __bitmap_size(struct f2fs_sb_info *sbi, int flag) | |||
| 764 | static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) | 764 | static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) |
| 765 | { | 765 | { |
| 766 | struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); | 766 | struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); |
| 767 | int offset = (flag == NAT_BITMAP) ? | 767 | int offset; |
| 768 | |||
| 769 | if (le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload) > 0) { | ||
| 770 | if (flag == NAT_BITMAP) | ||
| 771 | return &ckpt->sit_nat_version_bitmap; | ||
| 772 | else | ||
| 773 | return ((unsigned char *)ckpt + F2FS_BLKSIZE); | ||
| 774 | } else { | ||
| 775 | offset = (flag == NAT_BITMAP) ? | ||
| 768 | le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0; | 776 | le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0; |
| 769 | return &ckpt->sit_nat_version_bitmap + offset; | 777 | return &ckpt->sit_nat_version_bitmap + offset; |
| 778 | } | ||
| 770 | } | 779 | } |
| 771 | 780 | ||
| 772 | static inline block_t __start_cp_addr(struct f2fs_sb_info *sbi) | 781 | static inline block_t __start_cp_addr(struct f2fs_sb_info *sbi) |
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index ba6f3127738f..6ff0b0b42d47 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #define F2FS_LOG_SECTORS_PER_BLOCK 3 /* 4KB: F2FS_BLKSIZE */ | 19 | #define F2FS_LOG_SECTORS_PER_BLOCK 3 /* 4KB: F2FS_BLKSIZE */ |
| 20 | #define F2FS_BLKSIZE 4096 /* support only 4KB block */ | 20 | #define F2FS_BLKSIZE 4096 /* support only 4KB block */ |
| 21 | #define F2FS_MAX_EXTENSION 64 /* # of extension entries */ | 21 | #define F2FS_MAX_EXTENSION 64 /* # of extension entries */ |
| 22 | #define F2FS_BLK_ALIGN(x) (((x) + F2FS_BLKSIZE - 1) / F2FS_BLKSIZE) | ||
| 22 | 23 | ||
| 23 | #define NULL_ADDR ((block_t)0) /* used as block_t addresses */ | 24 | #define NULL_ADDR ((block_t)0) /* used as block_t addresses */ |
| 24 | #define NEW_ADDR ((block_t)-1) /* used as block_t addresses */ | 25 | #define NEW_ADDR ((block_t)-1) /* used as block_t addresses */ |
| @@ -75,6 +76,7 @@ struct f2fs_super_block { | |||
| 75 | __le16 volume_name[512]; /* volume name */ | 76 | __le16 volume_name[512]; /* volume name */ |
| 76 | __le32 extension_count; /* # of extensions below */ | 77 | __le32 extension_count; /* # of extensions below */ |
| 77 | __u8 extension_list[F2FS_MAX_EXTENSION][8]; /* extension array */ | 78 | __u8 extension_list[F2FS_MAX_EXTENSION][8]; /* extension array */ |
| 79 | __le32 cp_payload; | ||
| 78 | } __packed; | 80 | } __packed; |
| 79 | 81 | ||
| 80 | /* | 82 | /* |
