diff options
author | Changman Lee <cm224.lee@samsung.com> | 2014-05-11 23:27:43 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-06-04 00:34:30 -0400 |
commit | 1dbe4152168d44fa164edbdc9f1243de70b98f7a (patch) | |
tree | 205318206e29db519ad1aad5e8042ae879c77184 /fs/f2fs/checkpoint.c | |
parent | bac4eef6537a663585f3fb3d633a629c72e3b73d (diff) |
f2fs: large volume support
f2fs's cp has one page which consists of struct f2fs_checkpoint and
version bitmap of sit and nat. To support lots of segments, we need more
blocks for sit bitmap. So let's arrange sit bitmap as following:
+-----------------+------------+
| f2fs_checkpoint | sit bitmap |
| + nat bitmap | |
+-----------------+------------+
0 4k N blocks
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
[Jaegeuk Kim: simple code change for readability]
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/checkpoint.c')
-rw-r--r-- | fs/f2fs/checkpoint.c | 45 |
1 files changed, 40 insertions, 5 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; |