aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChangman Lee <cm224.lee@samsung.com>2014-05-11 23:27:43 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2014-06-04 00:34:30 -0400
commit1dbe4152168d44fa164edbdc9f1243de70b98f7a (patch)
tree205318206e29db519ad1aad5e8042ae879c77184
parentbac4eef6537a663585f3fb3d633a629c72e3b73d (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>
-rw-r--r--fs/f2fs/checkpoint.c45
-rw-r--r--fs/f2fs/f2fs.h13
-rw-r--r--include/linux/f2fs_fs.h2
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 }
568done:
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)
764static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) 764static 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
772static inline block_t __start_cp_addr(struct f2fs_sb_info *sbi) 781static 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/*