mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-06 05:02:31 +00:00
f2fs: introduce f2fs_get_section_mtime
When segs_per_sec is larger than 1, section may contain invalid segments, mtime should be the average value of each valid blocks, so introduce f2fs_get_section_mtime to record the average mtime of all valid blocks in a section. Signed-off-by: liuderong <liuderong@oppo.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
eca631b8fe
commit
b19ee72722
@ -3783,6 +3783,8 @@ enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
|
||||
unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi);
|
||||
unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
|
||||
unsigned int segno);
|
||||
unsigned long long f2fs_get_section_mtime(struct f2fs_sb_info *sbi,
|
||||
unsigned int segno);
|
||||
|
||||
#define DEF_FRAGMENT_SIZE 4
|
||||
#define MIN_FRAGMENT_SIZE 1
|
||||
|
17
fs/f2fs/gc.c
17
fs/f2fs/gc.c
@ -361,20 +361,15 @@ static unsigned int check_bg_victims(struct f2fs_sb_info *sbi)
|
||||
static unsigned int get_cb_cost(struct f2fs_sb_info *sbi, unsigned int segno)
|
||||
{
|
||||
struct sit_info *sit_i = SIT_I(sbi);
|
||||
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
|
||||
unsigned int start = GET_SEG_FROM_SEC(sbi, secno);
|
||||
unsigned long long mtime = 0;
|
||||
unsigned int vblocks;
|
||||
unsigned char age = 0;
|
||||
unsigned char u;
|
||||
unsigned int i;
|
||||
unsigned int usable_segs_per_sec = f2fs_usable_segs_in_sec(sbi);
|
||||
|
||||
for (i = 0; i < usable_segs_per_sec; i++)
|
||||
mtime += get_seg_entry(sbi, start + i)->mtime;
|
||||
mtime = f2fs_get_section_mtime(sbi, segno);
|
||||
f2fs_bug_on(sbi, mtime == INVALID_MTIME);
|
||||
vblocks = get_valid_blocks(sbi, segno, true);
|
||||
|
||||
mtime = div_u64(mtime, usable_segs_per_sec);
|
||||
vblocks = div_u64(vblocks, usable_segs_per_sec);
|
||||
|
||||
u = BLKS_TO_SEGS(sbi, vblocks * 100);
|
||||
@ -519,10 +514,7 @@ static void add_victim_entry(struct f2fs_sb_info *sbi,
|
||||
struct victim_sel_policy *p, unsigned int segno)
|
||||
{
|
||||
struct sit_info *sit_i = SIT_I(sbi);
|
||||
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
|
||||
unsigned int start = GET_SEG_FROM_SEC(sbi, secno);
|
||||
unsigned long long mtime = 0;
|
||||
unsigned int i;
|
||||
|
||||
if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
|
||||
if (p->gc_mode == GC_AT &&
|
||||
@ -530,9 +522,8 @@ static void add_victim_entry(struct f2fs_sb_info *sbi,
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < SEGS_PER_SEC(sbi); i++)
|
||||
mtime += get_seg_entry(sbi, start + i)->mtime;
|
||||
mtime = div_u64(mtime, SEGS_PER_SEC(sbi));
|
||||
mtime = f2fs_get_section_mtime(sbi, segno);
|
||||
f2fs_bug_on(sbi, mtime == INVALID_MTIME);
|
||||
|
||||
/* Handle if the system time has changed by the user */
|
||||
if (mtime < sit_i->min_mtime)
|
||||
|
@ -5430,6 +5430,35 @@ unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi)
|
||||
return SEGS_PER_SEC(sbi);
|
||||
}
|
||||
|
||||
unsigned long long f2fs_get_section_mtime(struct f2fs_sb_info *sbi,
|
||||
unsigned int segno)
|
||||
{
|
||||
unsigned int usable_segs_per_sec = f2fs_usable_segs_in_sec(sbi);
|
||||
unsigned int secno = 0, start = 0;
|
||||
unsigned int total_valid_blocks = 0;
|
||||
unsigned long long mtime = 0;
|
||||
unsigned int i = 0;
|
||||
|
||||
secno = GET_SEC_FROM_SEG(sbi, segno);
|
||||
start = GET_SEG_FROM_SEC(sbi, secno);
|
||||
|
||||
if (!__is_large_section(sbi))
|
||||
return get_seg_entry(sbi, start + i)->mtime;
|
||||
|
||||
for (i = 0; i < usable_segs_per_sec; i++) {
|
||||
/* for large section, only check the mtime of valid segments */
|
||||
struct seg_entry *se = get_seg_entry(sbi, start+i);
|
||||
|
||||
mtime += se->mtime * se->valid_blocks;
|
||||
total_valid_blocks += se->valid_blocks;
|
||||
}
|
||||
|
||||
if (total_valid_blocks == 0)
|
||||
return INVALID_MTIME;
|
||||
|
||||
return div_u64(mtime, total_valid_blocks);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update min, max modified time for cost-benefit GC algorithm
|
||||
*/
|
||||
@ -5443,13 +5472,9 @@ static void init_min_max_mtime(struct f2fs_sb_info *sbi)
|
||||
sit_i->min_mtime = ULLONG_MAX;
|
||||
|
||||
for (segno = 0; segno < MAIN_SEGS(sbi); segno += SEGS_PER_SEC(sbi)) {
|
||||
unsigned int i;
|
||||
unsigned long long mtime = 0;
|
||||
|
||||
for (i = 0; i < SEGS_PER_SEC(sbi); i++)
|
||||
mtime += get_seg_entry(sbi, segno + i)->mtime;
|
||||
|
||||
mtime = div_u64(mtime, SEGS_PER_SEC(sbi));
|
||||
mtime = f2fs_get_section_mtime(sbi, segno);
|
||||
|
||||
if (sit_i->min_mtime > mtime)
|
||||
sit_i->min_mtime = mtime;
|
||||
|
@ -18,6 +18,8 @@
|
||||
#define F2FS_MIN_SEGMENTS 9 /* SB + 2 (CP + SIT + NAT) + SSA + MAIN */
|
||||
#define F2FS_MIN_META_SEGMENTS 8 /* SB + 2 (CP + SIT + NAT) + SSA */
|
||||
|
||||
#define INVALID_MTIME ULLONG_MAX /* no valid blocks in a segment/section */
|
||||
|
||||
/* L: Logical segment # in volume, R: Relative segment # in main area */
|
||||
#define GET_L2R_SEGNO(free_i, segno) ((segno) - (free_i)->start_segno)
|
||||
#define GET_R2L_SEGNO(free_i, segno) ((segno) + (free_i)->start_segno)
|
||||
|
Loading…
Reference in New Issue
Block a user