Message ID | 9047C53C18267742AB12E43B65C7F9F70BCC6DD6@dggemi505-mbs.china.huawei.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 2018/1/10 12:01, Gaoxiang (OS) wrote: > Use binary decision approach to calculate SIT/NAT/SSA segments > it has some benefits when the partition size >= 512G. > > (bsearch) > psize main_segments main_seaments > ... > 512G 261509 261510 > 1 T 523141 523143 > 2 T 1046405 1046409 > 4 T 2092783 2092791 > ... > > It also clarify that SIT/NAT/SSA are used for main segment area only. > > Signed-off-by: Gao Xiang <gaoxiang25@huawei.com> > --- > Change log from v1: > - use align_down instead of align_up in get_best_main_zones > > mkfs/f2fs_format.c | 112 ++++++++++++++++++++++++++++++++++++++--------------- > 1 file changed, 80 insertions(+), 32 deletions(-) > > diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c > index a130001..9ca2257 100644 > --- a/mkfs/f2fs_format.c > +++ b/mkfs/f2fs_format.c > @@ -145,20 +145,80 @@ static void verify_cur_segs(void) > c.cur_seg[i] = next_zone(i - 1); > } > > +static u_int32_t get_best_main_zones(void) > +{ > + u_int32_t total_zones = get_sb(segment_count) / (c.segs_per_zone); > + u_int32_t left = 1, right = total_zones - 1; > + u_int32_t candicate = 0; > + > + while (left <= right) { > + u_int32_t blocks_for_nat; > + u_int32_t sit_segments, nat_segments, ssa_segments; > + u_int32_t meta_segments, meta_zones; > + u_int32_t max_sit_bitmap_size, max_nat_bitmap_size; > + > + u_int32_t main_zones = (left + right) / 2; If we start to search zone size from total_zones/2, it can be a little bit slow, how about starting from the size that calculated by original method, and then expanding main zone until founding the target? Thanks, > + u_int32_t main_segments = c.segs_per_zone * main_zones; > + > + sit_segments = SEG_ALIGN(SIZE_ALIGN(main_segments, > + SIT_ENTRY_PER_BLOCK) /* blocks_for_sit */); > + > + blocks_for_nat = SIZE_ALIGN(main_segments * c.blks_per_seg, > + NAT_ENTRY_PER_BLOCK); > + > + max_sit_bitmap_size = min((u_int32_t)MAX_SIT_BITMAP_SIZE, > + sit_segments * c.blks_per_seg / 8); > + > + /* > + * it's weird because for 1TB storage, payload is still not > + * used and max_nat_bitmap_blks is only 21472, which means > + * the total number of nodes is 21472 * 409 = 8782048 > + */ > + if (max_sit_bitmap_size > MAX_SIT_BITMAP_SIZE_IN_CKPT) > + max_nat_bitmap_size = CHECKSUM_OFFSET - > + sizeof(struct f2fs_checkpoint) + 1; > + else > + max_nat_bitmap_size = > + CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1 > + - max_sit_bitmap_size; > + > + nat_segments = min(SEG_ALIGN(blocks_for_nat), > + (max_nat_bitmap_size * 8) / c.blks_per_seg); > + > + /* each main segment has a ssa block */ > + ssa_segments = SEG_ALIGN(main_segments); > + > + meta_segments = (get_sb(segment_count_ckpt) + > + sit_segments * 2 + nat_segments * 2 + > + ssa_segments); > + > + meta_zones = ZONE_ALIGN(meta_segments * c.blks_per_seg); > + > + if (meta_zones + main_zones == total_zones) > + return main_zones; > + > + if (meta_zones + main_zones < total_zones) { > + left = main_zones + 1; > + candicate = main_zones; > + } else > + right = main_zones - 1; > + } > + > + return candicate; > +} > + > static int f2fs_prepare_super_block(void) > { > u_int32_t blk_size_bytes; > u_int32_t log_sectorsize, log_sectors_per_block; > u_int32_t log_blocksize, log_blks_per_seg; > u_int32_t segment_size_bytes, zone_size_bytes; > - u_int32_t sit_segments; > - u_int32_t blocks_for_sit, blocks_for_nat, blocks_for_ssa; > - u_int32_t total_valid_blks_available; > + u_int32_t blocks_for_sit, blocks_for_nat; > u_int64_t zone_align_start_offset, diff; > u_int64_t total_meta_zones, total_meta_segments; > u_int32_t sit_bitmap_size, max_sit_bitmap_size; > u_int32_t max_nat_bitmap_size, max_nat_segments; > - u_int32_t total_zones; > + u_int32_t main_zones, main_segments; > u_int32_t next_ino; > enum quota_type qtype; > int i; > @@ -256,22 +316,18 @@ static int f2fs_prepare_super_block(void) > set_sb(sit_blkaddr, get_sb(segment0_blkaddr) + > get_sb(segment_count_ckpt) * c.blks_per_seg); > > - blocks_for_sit = SIZE_ALIGN(get_sb(segment_count), SIT_ENTRY_PER_BLOCK); > + /* try to do binary decision to get main_zones */ > + main_zones = get_best_main_zones(); > + main_segments = c.segs_per_zone * main_zones; > > - sit_segments = SEG_ALIGN(blocks_for_sit); > - > - set_sb(segment_count_sit, sit_segments * 2); > + blocks_for_sit = SIZE_ALIGN(main_segments, SIT_ENTRY_PER_BLOCK); > + set_sb(segment_count_sit, SEG_ALIGN(blocks_for_sit) * 2); > > set_sb(nat_blkaddr, get_sb(sit_blkaddr) + get_sb(segment_count_sit) * > c.blks_per_seg); > > - total_valid_blks_available = (get_sb(segment_count) - > - (get_sb(segment_count_ckpt) + > - get_sb(segment_count_sit))) * c.blks_per_seg; > - > - blocks_for_nat = SIZE_ALIGN(total_valid_blks_available, > + blocks_for_nat = SIZE_ALIGN(main_segments * c.blks_per_seg, > NAT_ENTRY_PER_BLOCK); > - > set_sb(segment_count_nat, SEG_ALIGN(blocks_for_nat)); > /* > * The number of node segments should not be exceeded a "Threshold". > @@ -312,16 +368,8 @@ static int f2fs_prepare_super_block(void) > set_sb(ssa_blkaddr, get_sb(nat_blkaddr) + get_sb(segment_count_nat) * > c.blks_per_seg); > > - total_valid_blks_available = (get_sb(segment_count) - > - (get_sb(segment_count_ckpt) + > - get_sb(segment_count_sit) + > - get_sb(segment_count_nat))) * > - c.blks_per_seg; > > - blocks_for_ssa = total_valid_blks_available / > - c.blks_per_seg + 1; > - > - set_sb(segment_count_ssa, SEG_ALIGN(blocks_for_ssa)); > + set_sb(segment_count_ssa, SEG_ALIGN(main_segments)); > > total_meta_segments = get_sb(segment_count_ckpt) + > get_sb(segment_count_sit) + > @@ -354,10 +402,7 @@ static int f2fs_prepare_super_block(void) > } > } > > - total_zones = get_sb(segment_count) / (c.segs_per_zone) - > - total_meta_zones; > - > - set_sb(section_count, total_zones * c.secs_per_zone); > + set_sb(section_count, main_zones * c.secs_per_zone); > > set_sb(segment_count_main, get_sb(section_count) * c.segs_per_sec); > > @@ -373,6 +418,9 @@ static int f2fs_prepare_super_block(void) > return -1; > } > > + ASSERT((total_meta_zones + main_zones) * c.segs_per_zone > + == get_sb(segment_count)); > + > c.reserved_segments = > (2 * (100 / c.overprovision + 1) + 6) > * c.segs_per_sec; > @@ -404,15 +452,15 @@ static int f2fs_prepare_super_block(void) > qtype, next_ino - 1); > } > > - if (total_zones <= 6) { > + if (main_zones <= 6) { > MSG(1, "\tError: %d zones: Need more zones " > - "by shrinking zone size\n", total_zones); > + "by shrinking zone size\n", main_zones); > return -1; > } > > if (c.heap) { > c.cur_seg[CURSEG_HOT_NODE] = > - last_section(last_zone(total_zones)); > + last_section(last_zone(main_zones)); > c.cur_seg[CURSEG_WARM_NODE] = prev_zone(CURSEG_HOT_NODE); > c.cur_seg[CURSEG_COLD_NODE] = prev_zone(CURSEG_WARM_NODE); > c.cur_seg[CURSEG_HOT_DATA] = prev_zone(CURSEG_COLD_NODE); > @@ -424,10 +472,10 @@ static int f2fs_prepare_super_block(void) > c.cur_seg[CURSEG_COLD_NODE] = next_zone(CURSEG_WARM_NODE); > c.cur_seg[CURSEG_HOT_DATA] = next_zone(CURSEG_COLD_NODE); > c.cur_seg[CURSEG_COLD_DATA] = > - max(last_zone((total_zones >> 2)), > + max(last_zone((main_zones >> 2)), > next_zone(CURSEG_COLD_NODE)); > c.cur_seg[CURSEG_WARM_DATA] = > - max(last_zone((total_zones >> 1)), > + max(last_zone((main_zones >> 1)), > next_zone(CURSEG_COLD_DATA)); > } > >
Hi Chao, On 2018/1/10 23:08, Chao Yu wrote: > On 2018/1/10 12:01, Gaoxiang (OS) wrote: >> Use binary decision approach to calculate SIT/NAT/SSA segments >> it has some benefits when the partition size >= 512G. >> >> (bsearch) >> psize main_segments main_seaments >> ... >> 512G 261509 261510 >> 1 T 523141 523143 >> 2 T 1046405 1046409 >> 4 T 2092783 2092791 >> ... >> >> It also clarify that SIT/NAT/SSA are used for main segment area only. >> >> Signed-off-by: Gao Xiang <gaoxiang25@huawei.com> >> --- >> Change log from v1: >> - use align_down instead of align_up in get_best_main_zones >> >> mkfs/f2fs_format.c | 112 ++++++++++++++++++++++++++++++++++++++--------------- >> 1 file changed, 80 insertions(+), 32 deletions(-) >> >> diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c >> index a130001..9ca2257 100644 >> --- a/mkfs/f2fs_format.c >> +++ b/mkfs/f2fs_format.c >> @@ -145,20 +145,80 @@ static void verify_cur_segs(void) >> c.cur_seg[i] = next_zone(i - 1); >> } >> >> +static u_int32_t get_best_main_zones(void) >> +{ >> + u_int32_t total_zones = get_sb(segment_count) / (c.segs_per_zone); >> + u_int32_t left = 1, right = total_zones - 1; >> + u_int32_t candicate = 0; >> + >> + while (left <= right) { >> + u_int32_t blocks_for_nat; >> + u_int32_t sit_segments, nat_segments, ssa_segments; >> + u_int32_t meta_segments, meta_zones; >> + u_int32_t max_sit_bitmap_size, max_nat_bitmap_size; >> + >> + u_int32_t main_zones = (left + right) / 2; > If we start to search zone size from total_zones/2, it can be a little bit > slow, how about starting from the size that calculated by original method, > and then expanding main zone until founding the target? > > Thanks, OK, I will tighten the boundary as much as possible tomorrow. Thanks, > >> + u_int32_t main_segments = c.segs_per_zone * main_zones; >> + >> + sit_segments = SEG_ALIGN(SIZE_ALIGN(main_segments, >> + SIT_ENTRY_PER_BLOCK) /* blocks_for_sit */); >> + >> + blocks_for_nat = SIZE_ALIGN(main_segments * c.blks_per_seg, >> + NAT_ENTRY_PER_BLOCK); >> + >> + max_sit_bitmap_size = min((u_int32_t)MAX_SIT_BITMAP_SIZE, >> + sit_segments * c.blks_per_seg / 8); >> + >> + /* >> + * it's weird because for 1TB storage, payload is still not >> + * used and max_nat_bitmap_blks is only 21472, which means >> + * the total number of nodes is 21472 * 409 = 8782048 >> + */ >> + if (max_sit_bitmap_size > MAX_SIT_BITMAP_SIZE_IN_CKPT) >> + max_nat_bitmap_size = CHECKSUM_OFFSET - >> + sizeof(struct f2fs_checkpoint) + 1; >> + else >> + max_nat_bitmap_size = >> + CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1 >> + - max_sit_bitmap_size; >> + >> + nat_segments = min(SEG_ALIGN(blocks_for_nat), >> + (max_nat_bitmap_size * 8) / c.blks_per_seg); >> + >> + /* each main segment has a ssa block */ >> + ssa_segments = SEG_ALIGN(main_segments); >> + >> + meta_segments = (get_sb(segment_count_ckpt) + >> + sit_segments * 2 + nat_segments * 2 + >> + ssa_segments); >> + >> + meta_zones = ZONE_ALIGN(meta_segments * c.blks_per_seg); >> + >> + if (meta_zones + main_zones == total_zones) >> + return main_zones; >> + >> + if (meta_zones + main_zones < total_zones) { >> + left = main_zones + 1; >> + candicate = main_zones; >> + } else >> + right = main_zones - 1; >> + } >> + >> + return candicate; >> +} >> + >> static int f2fs_prepare_super_block(void) >> { >> u_int32_t blk_size_bytes; >> u_int32_t log_sectorsize, log_sectors_per_block; >> u_int32_t log_blocksize, log_blks_per_seg; >> u_int32_t segment_size_bytes, zone_size_bytes; >> - u_int32_t sit_segments; >> - u_int32_t blocks_for_sit, blocks_for_nat, blocks_for_ssa; >> - u_int32_t total_valid_blks_available; >> + u_int32_t blocks_for_sit, blocks_for_nat; >> u_int64_t zone_align_start_offset, diff; >> u_int64_t total_meta_zones, total_meta_segments; >> u_int32_t sit_bitmap_size, max_sit_bitmap_size; >> u_int32_t max_nat_bitmap_size, max_nat_segments; >> - u_int32_t total_zones; >> + u_int32_t main_zones, main_segments; >> u_int32_t next_ino; >> enum quota_type qtype; >> int i; >> @@ -256,22 +316,18 @@ static int f2fs_prepare_super_block(void) >> set_sb(sit_blkaddr, get_sb(segment0_blkaddr) + >> get_sb(segment_count_ckpt) * c.blks_per_seg); >> >> - blocks_for_sit = SIZE_ALIGN(get_sb(segment_count), SIT_ENTRY_PER_BLOCK); >> + /* try to do binary decision to get main_zones */ >> + main_zones = get_best_main_zones(); >> + main_segments = c.segs_per_zone * main_zones; >> >> - sit_segments = SEG_ALIGN(blocks_for_sit); >> - >> - set_sb(segment_count_sit, sit_segments * 2); >> + blocks_for_sit = SIZE_ALIGN(main_segments, SIT_ENTRY_PER_BLOCK); >> + set_sb(segment_count_sit, SEG_ALIGN(blocks_for_sit) * 2); >> >> set_sb(nat_blkaddr, get_sb(sit_blkaddr) + get_sb(segment_count_sit) * >> c.blks_per_seg); >> >> - total_valid_blks_available = (get_sb(segment_count) - >> - (get_sb(segment_count_ckpt) + >> - get_sb(segment_count_sit))) * c.blks_per_seg; >> - >> - blocks_for_nat = SIZE_ALIGN(total_valid_blks_available, >> + blocks_for_nat = SIZE_ALIGN(main_segments * c.blks_per_seg, >> NAT_ENTRY_PER_BLOCK); >> - >> set_sb(segment_count_nat, SEG_ALIGN(blocks_for_nat)); >> /* >> * The number of node segments should not be exceeded a "Threshold". >> @@ -312,16 +368,8 @@ static int f2fs_prepare_super_block(void) >> set_sb(ssa_blkaddr, get_sb(nat_blkaddr) + get_sb(segment_count_nat) * >> c.blks_per_seg); >> >> - total_valid_blks_available = (get_sb(segment_count) - >> - (get_sb(segment_count_ckpt) + >> - get_sb(segment_count_sit) + >> - get_sb(segment_count_nat))) * >> - c.blks_per_seg; >> >> - blocks_for_ssa = total_valid_blks_available / >> - c.blks_per_seg + 1; >> - >> - set_sb(segment_count_ssa, SEG_ALIGN(blocks_for_ssa)); >> + set_sb(segment_count_ssa, SEG_ALIGN(main_segments)); >> >> total_meta_segments = get_sb(segment_count_ckpt) + >> get_sb(segment_count_sit) + >> @@ -354,10 +402,7 @@ static int f2fs_prepare_super_block(void) >> } >> } >> >> - total_zones = get_sb(segment_count) / (c.segs_per_zone) - >> - total_meta_zones; >> - >> - set_sb(section_count, total_zones * c.secs_per_zone); >> + set_sb(section_count, main_zones * c.secs_per_zone); >> >> set_sb(segment_count_main, get_sb(section_count) * c.segs_per_sec); >> >> @@ -373,6 +418,9 @@ static int f2fs_prepare_super_block(void) >> return -1; >> } >> >> + ASSERT((total_meta_zones + main_zones) * c.segs_per_zone >> + == get_sb(segment_count)); >> + >> c.reserved_segments = >> (2 * (100 / c.overprovision + 1) + 6) >> * c.segs_per_sec; >> @@ -404,15 +452,15 @@ static int f2fs_prepare_super_block(void) >> qtype, next_ino - 1); >> } >> >> - if (total_zones <= 6) { >> + if (main_zones <= 6) { >> MSG(1, "\tError: %d zones: Need more zones " >> - "by shrinking zone size\n", total_zones); >> + "by shrinking zone size\n", main_zones); >> return -1; >> } >> >> if (c.heap) { >> c.cur_seg[CURSEG_HOT_NODE] = >> - last_section(last_zone(total_zones)); >> + last_section(last_zone(main_zones)); >> c.cur_seg[CURSEG_WARM_NODE] = prev_zone(CURSEG_HOT_NODE); >> c.cur_seg[CURSEG_COLD_NODE] = prev_zone(CURSEG_WARM_NODE); >> c.cur_seg[CURSEG_HOT_DATA] = prev_zone(CURSEG_COLD_NODE); >> @@ -424,10 +472,10 @@ static int f2fs_prepare_super_block(void) >> c.cur_seg[CURSEG_COLD_NODE] = next_zone(CURSEG_WARM_NODE); >> c.cur_seg[CURSEG_HOT_DATA] = next_zone(CURSEG_COLD_NODE); >> c.cur_seg[CURSEG_COLD_DATA] = >> - max(last_zone((total_zones >> 2)), >> + max(last_zone((main_zones >> 2)), >> next_zone(CURSEG_COLD_NODE)); >> c.cur_seg[CURSEG_WARM_DATA] = >> - max(last_zone((total_zones >> 1)), >> + max(last_zone((main_zones >> 1)), >> next_zone(CURSEG_COLD_DATA)); >> } >> >>
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c index a130001..9ca2257 100644 --- a/mkfs/f2fs_format.c +++ b/mkfs/f2fs_format.c @@ -145,20 +145,80 @@ static void verify_cur_segs(void) c.cur_seg[i] = next_zone(i - 1); } +static u_int32_t get_best_main_zones(void) +{ + u_int32_t total_zones = get_sb(segment_count) / (c.segs_per_zone); + u_int32_t left = 1, right = total_zones - 1; + u_int32_t candicate = 0; + + while (left <= right) { + u_int32_t blocks_for_nat; + u_int32_t sit_segments, nat_segments, ssa_segments; + u_int32_t meta_segments, meta_zones; + u_int32_t max_sit_bitmap_size, max_nat_bitmap_size; + + u_int32_t main_zones = (left + right) / 2; + u_int32_t main_segments = c.segs_per_zone * main_zones; + + sit_segments = SEG_ALIGN(SIZE_ALIGN(main_segments, + SIT_ENTRY_PER_BLOCK) /* blocks_for_sit */); + + blocks_for_nat = SIZE_ALIGN(main_segments * c.blks_per_seg, + NAT_ENTRY_PER_BLOCK); + + max_sit_bitmap_size = min((u_int32_t)MAX_SIT_BITMAP_SIZE, + sit_segments * c.blks_per_seg / 8); + + /* + * it's weird because for 1TB storage, payload is still not + * used and max_nat_bitmap_blks is only 21472, which means + * the total number of nodes is 21472 * 409 = 8782048 + */ + if (max_sit_bitmap_size > MAX_SIT_BITMAP_SIZE_IN_CKPT) + max_nat_bitmap_size = CHECKSUM_OFFSET - + sizeof(struct f2fs_checkpoint) + 1; + else + max_nat_bitmap_size = + CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1 + - max_sit_bitmap_size; + + nat_segments = min(SEG_ALIGN(blocks_for_nat), + (max_nat_bitmap_size * 8) / c.blks_per_seg); + + /* each main segment has a ssa block */ + ssa_segments = SEG_ALIGN(main_segments); + + meta_segments = (get_sb(segment_count_ckpt) + + sit_segments * 2 + nat_segments * 2 + + ssa_segments); + + meta_zones = ZONE_ALIGN(meta_segments * c.blks_per_seg); + + if (meta_zones + main_zones == total_zones) + return main_zones; + + if (meta_zones + main_zones < total_zones) { + left = main_zones + 1; + candicate = main_zones; + } else + right = main_zones - 1; + } + + return candicate; +} + static int f2fs_prepare_super_block(void) { u_int32_t blk_size_bytes; u_int32_t log_sectorsize, log_sectors_per_block; u_int32_t log_blocksize, log_blks_per_seg; u_int32_t segment_size_bytes, zone_size_bytes; - u_int32_t sit_segments; - u_int32_t blocks_for_sit, blocks_for_nat, blocks_for_ssa; - u_int32_t total_valid_blks_available; + u_int32_t blocks_for_sit, blocks_for_nat; u_int64_t zone_align_start_offset, diff; u_int64_t total_meta_zones, total_meta_segments; u_int32_t sit_bitmap_size, max_sit_bitmap_size; u_int32_t max_nat_bitmap_size, max_nat_segments; - u_int32_t total_zones; + u_int32_t main_zones, main_segments; u_int32_t next_ino; enum quota_type qtype; int i; @@ -256,22 +316,18 @@ static int f2fs_prepare_super_block(void) set_sb(sit_blkaddr, get_sb(segment0_blkaddr) + get_sb(segment_count_ckpt) * c.blks_per_seg); - blocks_for_sit = SIZE_ALIGN(get_sb(segment_count), SIT_ENTRY_PER_BLOCK); + /* try to do binary decision to get main_zones */ + main_zones = get_best_main_zones(); + main_segments = c.segs_per_zone * main_zones; - sit_segments = SEG_ALIGN(blocks_for_sit); - - set_sb(segment_count_sit, sit_segments * 2); + blocks_for_sit = SIZE_ALIGN(main_segments, SIT_ENTRY_PER_BLOCK); + set_sb(segment_count_sit, SEG_ALIGN(blocks_for_sit) * 2); set_sb(nat_blkaddr, get_sb(sit_blkaddr) + get_sb(segment_count_sit) * c.blks_per_seg); - total_valid_blks_available = (get_sb(segment_count) - - (get_sb(segment_count_ckpt) + - get_sb(segment_count_sit))) * c.blks_per_seg; - - blocks_for_nat = SIZE_ALIGN(total_valid_blks_available, + blocks_for_nat = SIZE_ALIGN(main_segments * c.blks_per_seg, NAT_ENTRY_PER_BLOCK); - set_sb(segment_count_nat, SEG_ALIGN(blocks_for_nat)); /* * The number of node segments should not be exceeded a "Threshold". @@ -312,16 +368,8 @@ static int f2fs_prepare_super_block(void) set_sb(ssa_blkaddr, get_sb(nat_blkaddr) + get_sb(segment_count_nat) * c.blks_per_seg); - total_valid_blks_available = (get_sb(segment_count) - - (get_sb(segment_count_ckpt) + - get_sb(segment_count_sit) + - get_sb(segment_count_nat))) * - c.blks_per_seg; - blocks_for_ssa = total_valid_blks_available / - c.blks_per_seg + 1; - - set_sb(segment_count_ssa, SEG_ALIGN(blocks_for_ssa)); + set_sb(segment_count_ssa, SEG_ALIGN(main_segments)); total_meta_segments = get_sb(segment_count_ckpt) + get_sb(segment_count_sit) + @@ -354,10 +402,7 @@ static int f2fs_prepare_super_block(void) } } - total_zones = get_sb(segment_count) / (c.segs_per_zone) - - total_meta_zones; - - set_sb(section_count, total_zones * c.secs_per_zone); + set_sb(section_count, main_zones * c.secs_per_zone); set_sb(segment_count_main, get_sb(section_count) * c.segs_per_sec); @@ -373,6 +418,9 @@ static int f2fs_prepare_super_block(void) return -1; } + ASSERT((total_meta_zones + main_zones) * c.segs_per_zone + == get_sb(segment_count)); + c.reserved_segments = (2 * (100 / c.overprovision + 1) + 6) * c.segs_per_sec; @@ -404,15 +452,15 @@ static int f2fs_prepare_super_block(void) qtype, next_ino - 1); } - if (total_zones <= 6) { + if (main_zones <= 6) { MSG(1, "\tError: %d zones: Need more zones " - "by shrinking zone size\n", total_zones); + "by shrinking zone size\n", main_zones); return -1; } if (c.heap) { c.cur_seg[CURSEG_HOT_NODE] = - last_section(last_zone(total_zones)); + last_section(last_zone(main_zones)); c.cur_seg[CURSEG_WARM_NODE] = prev_zone(CURSEG_HOT_NODE); c.cur_seg[CURSEG_COLD_NODE] = prev_zone(CURSEG_WARM_NODE); c.cur_seg[CURSEG_HOT_DATA] = prev_zone(CURSEG_COLD_NODE); @@ -424,10 +472,10 @@ static int f2fs_prepare_super_block(void) c.cur_seg[CURSEG_COLD_NODE] = next_zone(CURSEG_WARM_NODE); c.cur_seg[CURSEG_HOT_DATA] = next_zone(CURSEG_COLD_NODE); c.cur_seg[CURSEG_COLD_DATA] = - max(last_zone((total_zones >> 2)), + max(last_zone((main_zones >> 2)), next_zone(CURSEG_COLD_NODE)); c.cur_seg[CURSEG_WARM_DATA] = - max(last_zone((total_zones >> 1)), + max(last_zone((main_zones >> 1)), next_zone(CURSEG_COLD_DATA)); }
Use binary decision approach to calculate SIT/NAT/SSA segments it has some benefits when the partition size >= 512G. (bsearch) psize main_segments main_seaments ... 512G 261509 261510 1 T 523141 523143 2 T 1046405 1046409 4 T 2092783 2092791 ... It also clarify that SIT/NAT/SSA are used for main segment area only. Signed-off-by: Gao Xiang <gaoxiang25@huawei.com> --- Change log from v1: - use align_down instead of align_up in get_best_main_zones mkfs/f2fs_format.c | 112 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 32 deletions(-)