* [PATCH] f2fs: large volume support @ 2014-05-12 6:59 Changman Lee 2014-05-21 4:33 ` [f2fs-dev] " Jaegeuk Kim 0 siblings, 1 reply; 5+ messages in thread From: Changman Lee @ 2014-05-12 6:59 UTC (permalink / raw) To: linux-f2fs-devel, linux-fsdevel 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> --- fs/f2fs/checkpoint.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- fs/f2fs/f2fs.h | 13 +++++++++++-- include/linux/f2fs_fs.h | 2 ++ 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index fe968c7..f418243 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -544,6 +544,32 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) cp_block = (struct f2fs_checkpoint *)page_address(cur_page); memcpy(sbi->ckpt, cp_block, blk_size); + if (is_set_ckpt_flags(sbi->ckpt, CP_LARGE_VOL_FLAG)) { + int i, cp_blks; + block_t cp_blk_no; + + cp_blk_no = le32_to_cpu(fsb->cp_blkaddr); + if (cur_page == cp2) + cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg); + + cp_blks = 1 + F2FS_BLK_ALIGN(cp_block->sit_ver_bitmap_bytesize); + + kfree(sbi->ckpt); + sbi->ckpt = kzalloc(cp_blks * blk_size, GFP_KERNEL); + + memcpy(sbi->ckpt, cp_block, blk_size); + + for (i = 1; i < cp_blks; i++) { + void *sit_bitmap_ptr; + unsigned char *ckpt = (unsigned char *)sbi->ckpt; + + cur_page = get_meta_page(sbi, cp_blk_no + i); + sit_bitmap_ptr = page_address(cur_page); + memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); + f2fs_put_page(cur_page, 1); + } + } + f2fs_put_page(cp1, 1); f2fs_put_page(cp2, 1); return 0; @@ -736,6 +762,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) __u32 crc32 = 0; void *kaddr; int i; + int sit_bitmap_blks = 0; /* * This avoids to conduct wrong roll-forward operations and uses @@ -786,16 +813,21 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1) / F2FS_ORPHANS_PER_BLOCK; - ckpt->cp_pack_start_sum = cpu_to_le32(1 + orphan_blocks); + if (is_set_ckpt_flags(ckpt, CP_LARGE_VOL_FLAG)) + sit_bitmap_blks = F2FS_BLK_ALIGN(ckpt->sit_ver_bitmap_bytesize); + ckpt->cp_pack_start_sum = cpu_to_le32(1 + sit_bitmap_blks + + orphan_blocks); if (is_umount) { set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); ckpt->cp_pack_total_block_count = cpu_to_le32(2 + - data_sum_blocks + orphan_blocks + NR_CURSEG_NODE_TYPE); + sit_bitmap_blks + data_sum_blocks + + orphan_blocks + NR_CURSEG_NODE_TYPE); } else { clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); ckpt->cp_pack_total_block_count = cpu_to_le32(2 + - data_sum_blocks + orphan_blocks); + sit_bitmap_blks + data_sum_blocks + + orphan_blocks); } if (sbi->n_orphans) @@ -821,6 +853,15 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) set_page_dirty(cp_page); f2fs_put_page(cp_page, 1); + for (i = 1; i < 1 + sit_bitmap_blks; i++) { + cp_page = grab_meta_page(sbi, start_blk++); + kaddr = page_address(cp_page); + memcpy(kaddr, (char *)ckpt + i * F2FS_BLKSIZE, + (1 << sbi->log_blocksize)); + set_page_dirty(cp_page); + f2fs_put_page(cp_page, 1); + } + if (sbi->n_orphans) { write_orphan_inodes(sbi, start_blk); start_blk += orphan_blocks; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 676a2c6..9e147ae 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) static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) { struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); - int offset = (flag == NAT_BITMAP) ? + int offset; + + if (ckpt->ckpt_flags & CP_LARGE_VOL_FLAG) { + if (flag == NAT_BITMAP) + return &ckpt->sit_nat_version_bitmap; + else + return ((unsigned char *)ckpt + F2FS_BLKSIZE); + } else { + offset = (flag == NAT_BITMAP) ? le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0; - return &ckpt->sit_nat_version_bitmap + offset; + return &ckpt->sit_nat_version_bitmap + offset; + } } 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 8c03f71..0f0b788 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -19,6 +19,7 @@ #define F2FS_LOG_SECTORS_PER_BLOCK 3 /* 4KB: F2FS_BLKSIZE */ #define F2FS_BLKSIZE 4096 /* support only 4KB block */ #define F2FS_MAX_EXTENSION 64 /* # of extension entries */ +#define F2FS_BLK_ALIGN(x) (((x) + F2FS_BLKSIZE - 1) / F2FS_BLKSIZE) #define NULL_ADDR ((block_t)0) /* used as block_t addresses */ #define NEW_ADDR ((block_t)-1) /* used as block_t addresses */ @@ -80,6 +81,7 @@ struct f2fs_super_block { /* * For checkpoint */ +#define CP_LARGE_VOL_FLAG 0x00000010 #define CP_ERROR_FLAG 0x00000008 #define CP_COMPACT_SUM_FLAG 0x00000004 #define CP_ORPHAN_PRESENT_FLAG 0x00000002 -- 1.7.9.5 ------------------------------------------------------------------------------ "Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE Instantly run your Selenium tests across 300+ browser/OS combos. Get unparalleled scalability from the best Selenium testing platform available Simple to use. Nothing to install. Get started now for free." http://p.sf.net/sfu/SauceLabs ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [f2fs-dev] [PATCH] f2fs: large volume support 2014-05-12 6:59 [PATCH] f2fs: large volume support Changman Lee @ 2014-05-21 4:33 ` Jaegeuk Kim 2014-05-21 6:46 ` Changman Lee 0 siblings, 1 reply; 5+ messages in thread From: Jaegeuk Kim @ 2014-05-21 4:33 UTC (permalink / raw) To: Changman Lee; +Cc: linux-f2fs-devel, linux-fsdevel [-- Attachment #1: Type: text/plain, Size: 5845 bytes --] Hi Changman, 2014-05-12 (월), 15:59 +0900, Changman Lee: > 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> > --- > fs/f2fs/checkpoint.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- > fs/f2fs/f2fs.h | 13 +++++++++++-- > include/linux/f2fs_fs.h | 2 ++ > 3 files changed, 57 insertions(+), 5 deletions(-) > > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c > index fe968c7..f418243 100644 > --- a/fs/f2fs/checkpoint.c > +++ b/fs/f2fs/checkpoint.c > @@ -544,6 +544,32 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) > cp_block = (struct f2fs_checkpoint *)page_address(cur_page); > memcpy(sbi->ckpt, cp_block, blk_size); > > + if (is_set_ckpt_flags(sbi->ckpt, CP_LARGE_VOL_FLAG)) { > + int i, cp_blks; > + block_t cp_blk_no; > + > + cp_blk_no = le32_to_cpu(fsb->cp_blkaddr); > + if (cur_page == cp2) > + cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg); > + > + cp_blks = 1 + F2FS_BLK_ALIGN(cp_block->sit_ver_bitmap_bytesize); Should covert le32_to_cpu(cp_block->sit_ver_bitmap_bytesize). > + > + kfree(sbi->ckpt); > + sbi->ckpt = kzalloc(cp_blks * blk_size, GFP_KERNEL); Why does it have to reallocate this and not to handle -ENOMEM correctly? > + > + memcpy(sbi->ckpt, cp_block, blk_size); > + > + for (i = 1; i < cp_blks; i++) { > + void *sit_bitmap_ptr; > + unsigned char *ckpt = (unsigned char *)sbi->ckpt; > + > + cur_page = get_meta_page(sbi, cp_blk_no + i); > + sit_bitmap_ptr = page_address(cur_page); > + memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); > + f2fs_put_page(cur_page, 1); > + } > + } > + > f2fs_put_page(cp1, 1); > f2fs_put_page(cp2, 1); > return 0; > @@ -736,6 +762,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) > __u32 crc32 = 0; > void *kaddr; > int i; > + int sit_bitmap_blks = 0; > > /* > * This avoids to conduct wrong roll-forward operations and uses > @@ -786,16 +813,21 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) > > orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1) > / F2FS_ORPHANS_PER_BLOCK; > - ckpt->cp_pack_start_sum = cpu_to_le32(1 + orphan_blocks); > + if (is_set_ckpt_flags(ckpt, CP_LARGE_VOL_FLAG)) > + sit_bitmap_blks = F2FS_BLK_ALIGN(ckpt->sit_ver_bitmap_bytesize); > + ckpt->cp_pack_start_sum = cpu_to_le32(1 + sit_bitmap_blks + > + orphan_blocks); > > if (is_umount) { > set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); > ckpt->cp_pack_total_block_count = cpu_to_le32(2 + > - data_sum_blocks + orphan_blocks + NR_CURSEG_NODE_TYPE); > + sit_bitmap_blks + data_sum_blocks + > + orphan_blocks + NR_CURSEG_NODE_TYPE); > } else { > clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); > ckpt->cp_pack_total_block_count = cpu_to_le32(2 + > - data_sum_blocks + orphan_blocks); > + sit_bitmap_blks + data_sum_blocks + > + orphan_blocks); > } > > if (sbi->n_orphans) > @@ -821,6 +853,15 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) > set_page_dirty(cp_page); > f2fs_put_page(cp_page, 1); > > + for (i = 1; i < 1 + sit_bitmap_blks; i++) { > + cp_page = grab_meta_page(sbi, start_blk++); > + kaddr = page_address(cp_page); > + memcpy(kaddr, (char *)ckpt + i * F2FS_BLKSIZE, > + (1 << sbi->log_blocksize)); > + set_page_dirty(cp_page); > + f2fs_put_page(cp_page, 1); > + } > + > if (sbi->n_orphans) { > write_orphan_inodes(sbi, start_blk); > start_blk += orphan_blocks; > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index 676a2c6..9e147ae 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) > static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) > { > struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); > - int offset = (flag == NAT_BITMAP) ? > + int offset; > + > + if (ckpt->ckpt_flags & CP_LARGE_VOL_FLAG) { Should call is_set_ckpt_flag(ckpt, CP_LARGE_VOL_FLAG) to avoid endian conversion issue. Thanks, > + if (flag == NAT_BITMAP) > + return &ckpt->sit_nat_version_bitmap; > + else > + return ((unsigned char *)ckpt + F2FS_BLKSIZE); > + } else { > + offset = (flag == NAT_BITMAP) ? > le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0; > - return &ckpt->sit_nat_version_bitmap + offset; > + return &ckpt->sit_nat_version_bitmap + offset; > + } > } > > 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 8c03f71..0f0b788 100644 > --- a/include/linux/f2fs_fs.h > +++ b/include/linux/f2fs_fs.h > @@ -19,6 +19,7 @@ > #define F2FS_LOG_SECTORS_PER_BLOCK 3 /* 4KB: F2FS_BLKSIZE */ > #define F2FS_BLKSIZE 4096 /* support only 4KB block */ > #define F2FS_MAX_EXTENSION 64 /* # of extension entries */ > +#define F2FS_BLK_ALIGN(x) (((x) + F2FS_BLKSIZE - 1) / F2FS_BLKSIZE) > > #define NULL_ADDR ((block_t)0) /* used as block_t addresses */ > #define NEW_ADDR ((block_t)-1) /* used as block_t addresses */ > @@ -80,6 +81,7 @@ struct f2fs_super_block { > /* > * For checkpoint > */ > +#define CP_LARGE_VOL_FLAG 0x00000010 > #define CP_ERROR_FLAG 0x00000008 > #define CP_COMPACT_SUM_FLAG 0x00000004 > #define CP_ORPHAN_PRESENT_FLAG 0x00000002 -- Jaegeuk Kim [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [f2fs-dev] [PATCH] f2fs: large volume support 2014-05-21 4:33 ` [f2fs-dev] " Jaegeuk Kim @ 2014-05-21 6:46 ` Changman Lee 2014-05-22 8:31 ` [PATCH V3] " Changman Lee 0 siblings, 1 reply; 5+ messages in thread From: Changman Lee @ 2014-05-21 6:46 UTC (permalink / raw) To: Jaegeuk Kim; +Cc: linux-f2fs-devel, linux-fsdevel On 수, 2014-05-21 at 13:33 +0900, Jaegeuk Kim wrote: > Hi Changman, > > 2014-05-12 (월), 15:59 +0900, Changman Lee: > > 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> > > --- > > fs/f2fs/checkpoint.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- > > fs/f2fs/f2fs.h | 13 +++++++++++-- > > include/linux/f2fs_fs.h | 2 ++ > > 3 files changed, 57 insertions(+), 5 deletions(-) > > > > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c > > index fe968c7..f418243 100644 > > --- a/fs/f2fs/checkpoint.c > > +++ b/fs/f2fs/checkpoint.c > > @@ -544,6 +544,32 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) > > cp_block = (struct f2fs_checkpoint *)page_address(cur_page); > > memcpy(sbi->ckpt, cp_block, blk_size); > > > > + if (is_set_ckpt_flags(sbi->ckpt, CP_LARGE_VOL_FLAG)) { > > + int i, cp_blks; > > + block_t cp_blk_no; > > + > > + cp_blk_no = le32_to_cpu(fsb->cp_blkaddr); > > + if (cur_page == cp2) > > + cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg); > > + > > + cp_blks = 1 + F2FS_BLK_ALIGN(cp_block->sit_ver_bitmap_bytesize); > > Should covert le32_to_cpu(cp_block->sit_ver_bitmap_bytesize). > Got it. > > + > > + kfree(sbi->ckpt); > > + sbi->ckpt = kzalloc(cp_blks * blk_size, GFP_KERNEL); > > Why does it have to reallocate this and not to handle -ENOMEM correctly? I think it's more simple than using another variable to point sit_ver_bitmap and it doesn't require alloc and free for the variable. > > > + > > + memcpy(sbi->ckpt, cp_block, blk_size); > > + > > + for (i = 1; i < cp_blks; i++) { > > + void *sit_bitmap_ptr; > > + unsigned char *ckpt = (unsigned char *)sbi->ckpt; > > + > > + cur_page = get_meta_page(sbi, cp_blk_no + i); > > + sit_bitmap_ptr = page_address(cur_page); > > + memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); > > + f2fs_put_page(cur_page, 1); > > + } > > + } > > + > > f2fs_put_page(cp1, 1); > > f2fs_put_page(cp2, 1); > > return 0; > > @@ -736,6 +762,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) > > __u32 crc32 = 0; > > void *kaddr; > > int i; > > + int sit_bitmap_blks = 0; > > > > /* > > * This avoids to conduct wrong roll-forward operations and uses > > @@ -786,16 +813,21 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) > > > > orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1) > > / F2FS_ORPHANS_PER_BLOCK; > > - ckpt->cp_pack_start_sum = cpu_to_le32(1 + orphan_blocks); > > + if (is_set_ckpt_flags(ckpt, CP_LARGE_VOL_FLAG)) > > + sit_bitmap_blks = F2FS_BLK_ALIGN(ckpt->sit_ver_bitmap_bytesize); > > + ckpt->cp_pack_start_sum = cpu_to_le32(1 + sit_bitmap_blks + > > + orphan_blocks); > > > > if (is_umount) { > > set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); > > ckpt->cp_pack_total_block_count = cpu_to_le32(2 + > > - data_sum_blocks + orphan_blocks + NR_CURSEG_NODE_TYPE); > > + sit_bitmap_blks + data_sum_blocks + > > + orphan_blocks + NR_CURSEG_NODE_TYPE); > > } else { > > clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); > > ckpt->cp_pack_total_block_count = cpu_to_le32(2 + > > - data_sum_blocks + orphan_blocks); > > + sit_bitmap_blks + data_sum_blocks + > > + orphan_blocks); > > } > > > > if (sbi->n_orphans) > > @@ -821,6 +853,15 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) > > set_page_dirty(cp_page); > > f2fs_put_page(cp_page, 1); > > > > + for (i = 1; i < 1 + sit_bitmap_blks; i++) { > > + cp_page = grab_meta_page(sbi, start_blk++); > > + kaddr = page_address(cp_page); > > + memcpy(kaddr, (char *)ckpt + i * F2FS_BLKSIZE, > > + (1 << sbi->log_blocksize)); > > + set_page_dirty(cp_page); > > + f2fs_put_page(cp_page, 1); > > + } > > + > > if (sbi->n_orphans) { > > write_orphan_inodes(sbi, start_blk); > > start_blk += orphan_blocks; > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > > index 676a2c6..9e147ae 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) > > static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) > > { > > struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); > > - int offset = (flag == NAT_BITMAP) ? > > + int offset; > > + > > + if (ckpt->ckpt_flags & CP_LARGE_VOL_FLAG) { > > Should call is_set_ckpt_flag(ckpt, CP_LARGE_VOL_FLAG) to avoid endian > conversion issue. > > Thanks, > My mistake. Thanks. > > + if (flag == NAT_BITMAP) > > + return &ckpt->sit_nat_version_bitmap; > > + else > > + return ((unsigned char *)ckpt + F2FS_BLKSIZE); > > + } else { > > + offset = (flag == NAT_BITMAP) ? > > le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0; > > - return &ckpt->sit_nat_version_bitmap + offset; > > + return &ckpt->sit_nat_version_bitmap + offset; > > + } > > } > > > > 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 8c03f71..0f0b788 100644 > > --- a/include/linux/f2fs_fs.h > > +++ b/include/linux/f2fs_fs.h > > @@ -19,6 +19,7 @@ > > #define F2FS_LOG_SECTORS_PER_BLOCK 3 /* 4KB: F2FS_BLKSIZE */ > > #define F2FS_BLKSIZE 4096 /* support only 4KB block */ > > #define F2FS_MAX_EXTENSION 64 /* # of extension entries */ > > +#define F2FS_BLK_ALIGN(x) (((x) + F2FS_BLKSIZE - 1) / F2FS_BLKSIZE) > > > > #define NULL_ADDR ((block_t)0) /* used as block_t addresses */ > > #define NEW_ADDR ((block_t)-1) /* used as block_t addresses */ > > @@ -80,6 +81,7 @@ struct f2fs_super_block { > > /* > > * For checkpoint > > */ > > +#define CP_LARGE_VOL_FLAG 0x00000010 > > #define CP_ERROR_FLAG 0x00000008 > > #define CP_COMPACT_SUM_FLAG 0x00000004 > > #define CP_ORPHAN_PRESENT_FLAG 0x00000002 > -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH V3] f2fs: large volume support 2014-05-21 6:46 ` Changman Lee @ 2014-05-22 8:31 ` Changman Lee 2014-05-26 23:49 ` [f2fs-dev] " Changman Lee 0 siblings, 1 reply; 5+ messages in thread From: Changman Lee @ 2014-05-22 8:31 UTC (permalink / raw) To: Jaegeuk Kim; +Cc: linux-fsdevel, linux-f2fs-devel Changes from V2 o fix conversion like le32_to_cpu o use is_set_ckpt_flags instead of bit operation o check return value after memory allocation Changes from V1 o fix orphan node blkaddr for large volume Jaegeuk, What is your opinion about reallocation of sbi->ckpt ? If you have any idea, let me know. Thanks. --> 8 -- >From 5a821fcec79fb9570a26104238b3c2391f6160ae Mon Sep 17 00:00:00 2001 From: Changman Lee <cm224.lee@samsung.com> Date: Mon, 12 May 2014 12:27:43 +0900 Subject: [PATCH] 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> --- fs/f2fs/checkpoint.c | 59 +++++++++++++++++++++++++++++++++++++++++++---- fs/f2fs/f2fs.h | 13 +++++++++-- include/linux/f2fs_fs.h | 2 ++ 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index fe968c7..cf2d1a7 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -366,12 +366,18 @@ static void recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) void recover_orphan_inodes(struct f2fs_sb_info *sbi) { block_t start_blk, orphan_blkaddr, i, j; + struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG)) return; sbi->por_doing = true; - start_blk = __start_cp_addr(sbi) + 1; + + if (is_set_ckpt_flags(ckpt, CP_LARGE_VOL_FLAG)) + start_blk = __start_cp_addr(sbi) + F2FS_BLK_ALIGN( + le32_to_cpu(ckpt->sit_ver_bitmap_bytesize)); + else + start_blk = __start_cp_addr(sbi) + 1; orphan_blkaddr = __start_sum_addr(sbi) - 1; ra_meta_pages(sbi, start_blk, orphan_blkaddr, META_CP); @@ -544,6 +550,35 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) cp_block = (struct f2fs_checkpoint *)page_address(cur_page); memcpy(sbi->ckpt, cp_block, blk_size); + if (is_set_ckpt_flags(sbi->ckpt, CP_LARGE_VOL_FLAG)) { + int i, cp_blks; + block_t cp_blk_no; + + cp_blk_no = le32_to_cpu(fsb->cp_blkaddr); + if (cur_page == cp2) + cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg); + + cp_blks = 1 + F2FS_BLK_ALIGN( + le32_to_cpu(cp_block->sit_ver_bitmap_bytesize)); + + kfree(sbi->ckpt); + sbi->ckpt = kzalloc(cp_blks * blk_size, GFP_KERNEL); + if (!sbi->ckpt) + return -ENOMEM; + + memcpy(sbi->ckpt, cp_block, blk_size); + + for (i = 1; i < cp_blks; i++) { + void *sit_bitmap_ptr; + unsigned char *ckpt = (unsigned char *)sbi->ckpt; + + cur_page = get_meta_page(sbi, cp_blk_no + i); + sit_bitmap_ptr = page_address(cur_page); + memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); + f2fs_put_page(cur_page, 1); + } + } + f2fs_put_page(cp1, 1); f2fs_put_page(cp2, 1); return 0; @@ -736,6 +771,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) __u32 crc32 = 0; void *kaddr; int i; + int sit_bitmap_blks = 0; /* * This avoids to conduct wrong roll-forward operations and uses @@ -786,16 +822,22 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1) / F2FS_ORPHANS_PER_BLOCK; - ckpt->cp_pack_start_sum = cpu_to_le32(1 + orphan_blocks); + if (is_set_ckpt_flags(ckpt, CP_LARGE_VOL_FLAG)) + sit_bitmap_blks = F2FS_BLK_ALIGN( + le32_to_cpu(ckpt->sit_ver_bitmap_bytesize)); + ckpt->cp_pack_start_sum = cpu_to_le32(1 + sit_bitmap_blks + + orphan_blocks); if (is_umount) { set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); ckpt->cp_pack_total_block_count = cpu_to_le32(2 + - data_sum_blocks + orphan_blocks + NR_CURSEG_NODE_TYPE); + sit_bitmap_blks + data_sum_blocks + + orphan_blocks + NR_CURSEG_NODE_TYPE); } else { clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); ckpt->cp_pack_total_block_count = cpu_to_le32(2 + - data_sum_blocks + orphan_blocks); + sit_bitmap_blks + data_sum_blocks + + orphan_blocks); } if (sbi->n_orphans) @@ -821,6 +863,15 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) set_page_dirty(cp_page); f2fs_put_page(cp_page, 1); + for (i = 1; i < 1 + sit_bitmap_blks; i++) { + cp_page = grab_meta_page(sbi, start_blk++); + kaddr = page_address(cp_page); + memcpy(kaddr, (char *)ckpt + i * F2FS_BLKSIZE, + (1 << sbi->log_blocksize)); + set_page_dirty(cp_page); + f2fs_put_page(cp_page, 1); + } + if (sbi->n_orphans) { write_orphan_inodes(sbi, start_blk); start_blk += orphan_blocks; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 676a2c6..3aec601 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) static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) { struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); - int offset = (flag == NAT_BITMAP) ? + int offset; + + if (is_set_ckpt_flags(ckpt, CP_LARGE_VOL_FLAG)) { + if (flag == NAT_BITMAP) + return &ckpt->sit_nat_version_bitmap; + else + return ((unsigned char *)ckpt + F2FS_BLKSIZE); + } else { + offset = (flag == NAT_BITMAP) ? le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0; - return &ckpt->sit_nat_version_bitmap + offset; + return &ckpt->sit_nat_version_bitmap + offset; + } } 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 8c03f71..0f0b788 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -19,6 +19,7 @@ #define F2FS_LOG_SECTORS_PER_BLOCK 3 /* 4KB: F2FS_BLKSIZE */ #define F2FS_BLKSIZE 4096 /* support only 4KB block */ #define F2FS_MAX_EXTENSION 64 /* # of extension entries */ +#define F2FS_BLK_ALIGN(x) (((x) + F2FS_BLKSIZE - 1) / F2FS_BLKSIZE) #define NULL_ADDR ((block_t)0) /* used as block_t addresses */ #define NEW_ADDR ((block_t)-1) /* used as block_t addresses */ @@ -80,6 +81,7 @@ struct f2fs_super_block { /* * For checkpoint */ +#define CP_LARGE_VOL_FLAG 0x00000010 #define CP_ERROR_FLAG 0x00000008 #define CP_COMPACT_SUM_FLAG 0x00000004 #define CP_ORPHAN_PRESENT_FLAG 0x00000002 -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [f2fs-dev] [PATCH V3] f2fs: large volume support 2014-05-22 8:31 ` [PATCH V3] " Changman Lee @ 2014-05-26 23:49 ` Changman Lee 0 siblings, 0 replies; 5+ messages in thread From: Changman Lee @ 2014-05-26 23:49 UTC (permalink / raw) To: Jaegeuk Kim; +Cc: linux-fsdevel, linux-f2fs-devel Changes from V3 o remove CP_LARGE_VOL_FLAG instead, use cp_payload in superblock because disk size is determined at format Changes from V2 o fix conversion like le32_to_cpu o use is_set_ckpt_flags instead of bit operation o check return value after memory allocation Changes from V1 o fix orphan node blkaddr for large volume -- >8 -- >From b1610f32c472cb11f025e0997b7633d5c45b87e9 Mon Sep 17 00:00:00 2001 From: Changman Lee <cm224.lee@samsung.com> Date: Mon, 12 May 2014 12:27:43 +0900 Subject: [PATCH] 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> --- fs/f2fs/checkpoint.c | 45 ++++++++++++++++++++++++++++++++++++++++----- fs/f2fs/f2fs.h | 13 +++++++++++-- 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 fe968c7..c559946 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -371,7 +371,9 @@ void recover_orphan_inodes(struct f2fs_sb_info *sbi) return; sbi->por_doing = true; - start_blk = __start_cp_addr(sbi) + 1; + + start_blk = __start_cp_addr(sbi) + 1 + + le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload); orphan_blkaddr = __start_sum_addr(sbi) - 1; ra_meta_pages(sbi, start_blk, orphan_blkaddr, META_CP); @@ -512,8 +514,9 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) unsigned long blk_size = sbi->blocksize; unsigned long long cp1_version = 0, cp2_version = 0; unsigned long long cp_start_blk_no; + unsigned int cp_blks = 1 + le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload); - sbi->ckpt = kzalloc(blk_size, GFP_KERNEL); + sbi->ckpt = kzalloc(cp_blks * blk_size, GFP_KERNEL); if (!sbi->ckpt) return -ENOMEM; /* @@ -544,6 +547,25 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) cp_block = (struct f2fs_checkpoint *)page_address(cur_page); memcpy(sbi->ckpt, cp_block, blk_size); + if (cp_blks > 1) { + int i; + block_t cp_blk_no; + + cp_blk_no = le32_to_cpu(fsb->cp_blkaddr); + if (cur_page == cp2) + cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg); + + for (i = 1; i < cp_blks; i++) { + void *sit_bitmap_ptr; + unsigned char *ckpt = (unsigned char *)sbi->ckpt; + + cur_page = get_meta_page(sbi, cp_blk_no + i); + sit_bitmap_ptr = page_address(cur_page); + memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); + f2fs_put_page(cur_page, 1); + } + } + f2fs_put_page(cp1, 1); f2fs_put_page(cp2, 1); return 0; @@ -736,6 +758,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) __u32 crc32 = 0; void *kaddr; int i; + int cp_payload_blks = le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload); /* * 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) orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1) / F2FS_ORPHANS_PER_BLOCK; - ckpt->cp_pack_start_sum = cpu_to_le32(1 + orphan_blocks); + ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks + + orphan_blocks); if (is_umount) { set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); ckpt->cp_pack_total_block_count = cpu_to_le32(2 + - data_sum_blocks + orphan_blocks + NR_CURSEG_NODE_TYPE); + cp_payload_blks + data_sum_blocks + + orphan_blocks + NR_CURSEG_NODE_TYPE); } else { clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); ckpt->cp_pack_total_block_count = cpu_to_le32(2 + - data_sum_blocks + orphan_blocks); + cp_payload_blks + data_sum_blocks + + orphan_blocks); } if (sbi->n_orphans) @@ -821,6 +847,15 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) set_page_dirty(cp_page); f2fs_put_page(cp_page, 1); + for (i = 1; i < 1 + cp_payload_blks; i++) { + cp_page = grab_meta_page(sbi, start_blk++); + kaddr = page_address(cp_page); + memcpy(kaddr, (char *)ckpt + i * F2FS_BLKSIZE, + (1 << sbi->log_blocksize)); + set_page_dirty(cp_page); + f2fs_put_page(cp_page, 1); + } + if (sbi->n_orphans) { write_orphan_inodes(sbi, start_blk); start_blk += orphan_blocks; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 676a2c6..9684b1f 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) static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) { struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); - int offset = (flag == NAT_BITMAP) ? + int offset; + + if (le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload) > 0) { + if (flag == NAT_BITMAP) + return &ckpt->sit_nat_version_bitmap; + else + return ((unsigned char *)ckpt + F2FS_BLKSIZE); + } else { + offset = (flag == NAT_BITMAP) ? le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0; - return &ckpt->sit_nat_version_bitmap + offset; + return &ckpt->sit_nat_version_bitmap + offset; + } } 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 8c03f71..23ba0b5 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -19,6 +19,7 @@ #define F2FS_LOG_SECTORS_PER_BLOCK 3 /* 4KB: F2FS_BLKSIZE */ #define F2FS_BLKSIZE 4096 /* support only 4KB block */ #define F2FS_MAX_EXTENSION 64 /* # of extension entries */ +#define F2FS_BLK_ALIGN(x) (((x) + F2FS_BLKSIZE - 1) / F2FS_BLKSIZE) #define NULL_ADDR ((block_t)0) /* used as block_t addresses */ #define NEW_ADDR ((block_t)-1) /* used as block_t addresses */ @@ -75,6 +76,7 @@ struct f2fs_super_block { __le16 volume_name[512]; /* volume name */ __le32 extension_count; /* # of extensions below */ __u8 extension_list[F2FS_MAX_EXTENSION][8]; /* extension array */ + __le32 cp_payload; } __packed; /* -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-05-26 23:49 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-05-12 6:59 [PATCH] f2fs: large volume support Changman Lee 2014-05-21 4:33 ` [f2fs-dev] " Jaegeuk Kim 2014-05-21 6:46 ` Changman Lee 2014-05-22 8:31 ` [PATCH V3] " Changman Lee 2014-05-26 23:49 ` [f2fs-dev] " Changman Lee
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).