After we flush sit && nat, maybe we can unlock filesystem. 1. Release prefree segments after cp pack write back. 2. Not allowed SSR on dirty sit until cp pack write back.
Signed-off-by: h00285313 <heyun...@huawei.com> --- fs/f2fs/checkpoint.c | 38 +++++++++++++++++++++++++++++++++++++- fs/f2fs/gc.c | 5 ++++- fs/f2fs/segment.c | 17 +---------------- fs/f2fs/segment.h | 3 ++- 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index ea9c317b..d11d83f 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1263,6 +1263,40 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) return 0; } +void clear_in_cp_flag(struct f2fs_sb_info *sbi) +{ + struct sit_info *sit_i = SIT_I(sbi); + struct seg_entry *se; + unsigned int segno = 0; + unsigned int end_segno = MAIN_SEGS(sbi); + + mutex_lock(&sit_i->sentry_lock); + while (segno < end_segno) { + se = get_seg_entry(sbi, segno); + segno++; + + if (!se->in_cp) + continue; + + se->in_cp = 0; + } + mutex_unlock(&sit_i->sentry_lock); +} + +/* + * Should call clear_prefree_segments after checkpoint is done. + */ +static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi) +{ + struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); + unsigned int segno; + + mutex_lock(&dirty_i->seglist_lock); + for_each_set_bit(segno, dirty_i->dirty_segmap[PRE], MAIN_SEGS(sbi)) + __set_test_and_free(sbi, segno); + mutex_unlock(&dirty_i->seglist_lock); +} + /* * We guarantee that this checkpoint procedure will not fail. */ @@ -1325,6 +1359,7 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* write cached NAT/SIT entries to NAT/SIT area */ flush_nat_entries(sbi, cpc); flush_sit_entries(sbi, cpc); + unblock_operations(sbi); /* unlock all the fs_lock[] in do_checkpoint() */ err = do_checkpoint(sbi, cpc); @@ -1333,7 +1368,8 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) else clear_prefree_segments(sbi, cpc); - unblock_operations(sbi); + set_prefree_as_free_segments(sbi); + clear_in_cp_flag(sbi); stat_inc_cp_count(sbi->stat_info); if (cpc->reason & CP_RECOVERY) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 0265221..e5cde89 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -261,8 +261,11 @@ static unsigned int get_greedy_cost(struct f2fs_sb_info *sbi, static inline unsigned int get_gc_cost(struct f2fs_sb_info *sbi, unsigned int segno, struct victim_sel_policy *p) { + struct seg_entry *se; + + se = get_seg_entry(sbi, segno); if (p->alloc_mode == SSR) - return get_seg_entry(sbi, segno)->ckpt_valid_blocks; + return se->in_cp ? sbi->blocks_per_seg + 1: se->ckpt_valid_blocks; /* alloc_mode == LFS */ if (p->gc_mode == GC_GREEDY) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index de31030..0877a2e 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1244,20 +1244,6 @@ void release_discard_addrs(struct f2fs_sb_info *sbi) } } -/* - * Should call clear_prefree_segments after checkpoint is done. - */ -static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi) -{ - struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); - unsigned int segno; - - mutex_lock(&dirty_i->seglist_lock); - for_each_set_bit(segno, dirty_i->dirty_segmap[PRE], MAIN_SEGS(sbi)) - __set_test_and_free(sbi, segno); - mutex_unlock(&dirty_i->seglist_lock); -} - void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc) { struct list_head *head = &(SM_I(sbi)->dcc_info->entry_list); @@ -2815,8 +2801,6 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) cpc->trim_start = trim_start; } mutex_unlock(&sit_i->sentry_lock); - - set_prefree_as_free_segments(sbi); } static int build_sit_info(struct f2fs_sb_info *sbi) @@ -2995,6 +2979,7 @@ static void build_sit_entries(struct f2fs_sb_info *sbi) struct page *page; se = &sit_i->sentries[start]; + se->in_cp = 0; page = get_current_sit_page(sbi, start); sit_blk = (struct f2fs_sit_block *)page_address(page); sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)]; diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 10bf05d..f69cd5b 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -171,7 +171,7 @@ struct seg_entry { unsigned int type:6; /* segment type like CURSEG_XXX_TYPE */ unsigned int valid_blocks:10; /* # of valid blocks */ unsigned int ckpt_valid_blocks:10; /* # of valid blocks last cp */ - unsigned int padding:6; /* padding */ + unsigned int in_cp:6; /* indicate cp or not */ unsigned char *cur_valid_map; /* validity bitmap of blocks */ #ifdef CONFIG_F2FS_CHECK_FS unsigned char *cur_valid_map_mir; /* mirror of current valid bitmap */ @@ -352,6 +352,7 @@ static inline void seg_info_to_raw_sit(struct seg_entry *se, rs->vblocks = cpu_to_le16(raw_vblocks); memcpy(rs->valid_map, se->cur_valid_map, SIT_VBLOCK_MAP_SIZE); memcpy(se->ckpt_valid_map, rs->valid_map, SIT_VBLOCK_MAP_SIZE); + se->in_cp = 1; se->ckpt_valid_blocks = se->valid_blocks; rs->mtime = cpu_to_le64(se->mtime); } -- 1.9.1 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel