Skip to content

Commit b19ee72

Browse files
liuderongJaegeuk Kim
authored andcommitted
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 <[email protected]> Reviewed-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent eca631b commit b19ee72

File tree

4 files changed

+38
-18
lines changed

4 files changed

+38
-18
lines changed

fs/f2fs/f2fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3783,6 +3783,8 @@ enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
37833783
unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi);
37843784
unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
37853785
unsigned int segno);
3786+
unsigned long long f2fs_get_section_mtime(struct f2fs_sb_info *sbi,
3787+
unsigned int segno);
37863788

37873789
#define DEF_FRAGMENT_SIZE 4
37883790
#define MIN_FRAGMENT_SIZE 1

fs/f2fs/gc.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -361,20 +361,15 @@ static unsigned int check_bg_victims(struct f2fs_sb_info *sbi)
361361
static unsigned int get_cb_cost(struct f2fs_sb_info *sbi, unsigned int segno)
362362
{
363363
struct sit_info *sit_i = SIT_I(sbi);
364-
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
365-
unsigned int start = GET_SEG_FROM_SEC(sbi, secno);
366364
unsigned long long mtime = 0;
367365
unsigned int vblocks;
368366
unsigned char age = 0;
369367
unsigned char u;
370-
unsigned int i;
371368
unsigned int usable_segs_per_sec = f2fs_usable_segs_in_sec(sbi);
372369

373-
for (i = 0; i < usable_segs_per_sec; i++)
374-
mtime += get_seg_entry(sbi, start + i)->mtime;
370+
mtime = f2fs_get_section_mtime(sbi, segno);
371+
f2fs_bug_on(sbi, mtime == INVALID_MTIME);
375372
vblocks = get_valid_blocks(sbi, segno, true);
376-
377-
mtime = div_u64(mtime, usable_segs_per_sec);
378373
vblocks = div_u64(vblocks, usable_segs_per_sec);
379374

380375
u = BLKS_TO_SEGS(sbi, vblocks * 100);
@@ -519,20 +514,16 @@ static void add_victim_entry(struct f2fs_sb_info *sbi,
519514
struct victim_sel_policy *p, unsigned int segno)
520515
{
521516
struct sit_info *sit_i = SIT_I(sbi);
522-
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
523-
unsigned int start = GET_SEG_FROM_SEC(sbi, secno);
524517
unsigned long long mtime = 0;
525-
unsigned int i;
526518

527519
if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
528520
if (p->gc_mode == GC_AT &&
529521
get_valid_blocks(sbi, segno, true) == 0)
530522
return;
531523
}
532524

533-
for (i = 0; i < SEGS_PER_SEC(sbi); i++)
534-
mtime += get_seg_entry(sbi, start + i)->mtime;
535-
mtime = div_u64(mtime, SEGS_PER_SEC(sbi));
525+
mtime = f2fs_get_section_mtime(sbi, segno);
526+
f2fs_bug_on(sbi, mtime == INVALID_MTIME);
536527

537528
/* Handle if the system time has changed by the user */
538529
if (mtime < sit_i->min_mtime)

fs/f2fs/segment.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5430,6 +5430,35 @@ unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi)
54305430
return SEGS_PER_SEC(sbi);
54315431
}
54325432

5433+
unsigned long long f2fs_get_section_mtime(struct f2fs_sb_info *sbi,
5434+
unsigned int segno)
5435+
{
5436+
unsigned int usable_segs_per_sec = f2fs_usable_segs_in_sec(sbi);
5437+
unsigned int secno = 0, start = 0;
5438+
unsigned int total_valid_blocks = 0;
5439+
unsigned long long mtime = 0;
5440+
unsigned int i = 0;
5441+
5442+
secno = GET_SEC_FROM_SEG(sbi, segno);
5443+
start = GET_SEG_FROM_SEC(sbi, secno);
5444+
5445+
if (!__is_large_section(sbi))
5446+
return get_seg_entry(sbi, start + i)->mtime;
5447+
5448+
for (i = 0; i < usable_segs_per_sec; i++) {
5449+
/* for large section, only check the mtime of valid segments */
5450+
struct seg_entry *se = get_seg_entry(sbi, start+i);
5451+
5452+
mtime += se->mtime * se->valid_blocks;
5453+
total_valid_blocks += se->valid_blocks;
5454+
}
5455+
5456+
if (total_valid_blocks == 0)
5457+
return INVALID_MTIME;
5458+
5459+
return div_u64(mtime, total_valid_blocks);
5460+
}
5461+
54335462
/*
54345463
* Update min, max modified time for cost-benefit GC algorithm
54355464
*/
@@ -5443,13 +5472,9 @@ static void init_min_max_mtime(struct f2fs_sb_info *sbi)
54435472
sit_i->min_mtime = ULLONG_MAX;
54445473

54455474
for (segno = 0; segno < MAIN_SEGS(sbi); segno += SEGS_PER_SEC(sbi)) {
5446-
unsigned int i;
54475475
unsigned long long mtime = 0;
54485476

5449-
for (i = 0; i < SEGS_PER_SEC(sbi); i++)
5450-
mtime += get_seg_entry(sbi, segno + i)->mtime;
5451-
5452-
mtime = div_u64(mtime, SEGS_PER_SEC(sbi));
5477+
mtime = f2fs_get_section_mtime(sbi, segno);
54535478

54545479
if (sit_i->min_mtime > mtime)
54555480
sit_i->min_mtime = mtime;

fs/f2fs/segment.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#define F2FS_MIN_SEGMENTS 9 /* SB + 2 (CP + SIT + NAT) + SSA + MAIN */
1919
#define F2FS_MIN_META_SEGMENTS 8 /* SB + 2 (CP + SIT + NAT) + SSA */
2020

21+
#define INVALID_MTIME ULLONG_MAX /* no valid blocks in a segment/section */
22+
2123
/* L: Logical segment # in volume, R: Relative segment # in main area */
2224
#define GET_L2R_SEGNO(free_i, segno) ((segno) - (free_i)->start_segno)
2325
#define GET_R2L_SEGNO(free_i, segno) ((segno) + (free_i)->start_segno)

0 commit comments

Comments
 (0)