diff options
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/f2fs.h | 7 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 17 | ||||
-rw-r--r-- | fs/f2fs/super.c | 2 |
3 files changed, 21 insertions, 5 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index db1ff55de0bc..337204dfc5cd 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -105,6 +105,10 @@ enum { | |||
105 | CP_DISCARD, | 105 | CP_DISCARD, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | #define DEF_BATCHED_TRIM_SECTIONS 32 | ||
109 | #define BATCHED_TRIM_SEGMENTS(sbi) \ | ||
110 | (SM_I(sbi)->trim_sections * (sbi)->segs_per_sec) | ||
111 | |||
108 | struct cp_control { | 112 | struct cp_control { |
109 | int reason; | 113 | int reason; |
110 | __u64 trim_start; | 114 | __u64 trim_start; |
@@ -448,6 +452,9 @@ struct f2fs_sm_info { | |||
448 | int nr_discards; /* # of discards in the list */ | 452 | int nr_discards; /* # of discards in the list */ |
449 | int max_discards; /* max. discards to be issued */ | 453 | int max_discards; /* max. discards to be issued */ |
450 | 454 | ||
455 | /* for batched trimming */ | ||
456 | unsigned int trim_sections; /* # of sections to trim */ | ||
457 | |||
451 | struct list_head sit_entry_set; /* sit entry set list */ | 458 | struct list_head sit_entry_set; /* sit entry set list */ |
452 | 459 | ||
453 | unsigned int ipu_policy; /* in-place-update policy */ | 460 | unsigned int ipu_policy; /* in-place-update policy */ |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 5ea57ec153d1..9f278d156d88 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -1066,14 +1066,19 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) | |||
1066 | end_segno = (end >= MAX_BLKADDR(sbi)) ? MAIN_SEGS(sbi) - 1 : | 1066 | end_segno = (end >= MAX_BLKADDR(sbi)) ? MAIN_SEGS(sbi) - 1 : |
1067 | GET_SEGNO(sbi, end); | 1067 | GET_SEGNO(sbi, end); |
1068 | cpc.reason = CP_DISCARD; | 1068 | cpc.reason = CP_DISCARD; |
1069 | cpc.trim_start = start_segno; | ||
1070 | cpc.trim_end = end_segno; | ||
1071 | cpc.trim_minlen = range->minlen >> sbi->log_blocksize; | 1069 | cpc.trim_minlen = range->minlen >> sbi->log_blocksize; |
1072 | 1070 | ||
1073 | /* do checkpoint to issue discard commands safely */ | 1071 | /* do checkpoint to issue discard commands safely */ |
1074 | mutex_lock(&sbi->gc_mutex); | 1072 | for (; start_segno <= end_segno; start_segno = cpc.trim_end + 1) { |
1075 | write_checkpoint(sbi, &cpc); | 1073 | cpc.trim_start = start_segno; |
1076 | mutex_unlock(&sbi->gc_mutex); | 1074 | cpc.trim_end = min_t(unsigned int, rounddown(start_segno + |
1075 | BATCHED_TRIM_SEGMENTS(sbi), | ||
1076 | sbi->segs_per_sec) - 1, end_segno); | ||
1077 | |||
1078 | mutex_lock(&sbi->gc_mutex); | ||
1079 | write_checkpoint(sbi, &cpc); | ||
1080 | mutex_unlock(&sbi->gc_mutex); | ||
1081 | } | ||
1077 | out: | 1082 | out: |
1078 | range->len = cpc.trimmed << sbi->log_blocksize; | 1083 | range->len = cpc.trimmed << sbi->log_blocksize; |
1079 | return 0; | 1084 | return 0; |
@@ -2127,6 +2132,8 @@ int build_segment_manager(struct f2fs_sb_info *sbi) | |||
2127 | sm_info->nr_discards = 0; | 2132 | sm_info->nr_discards = 0; |
2128 | sm_info->max_discards = 0; | 2133 | sm_info->max_discards = 0; |
2129 | 2134 | ||
2135 | sm_info->trim_sections = DEF_BATCHED_TRIM_SECTIONS; | ||
2136 | |||
2130 | INIT_LIST_HEAD(&sm_info->sit_entry_set); | 2137 | INIT_LIST_HEAD(&sm_info->sit_entry_set); |
2131 | 2138 | ||
2132 | if (test_opt(sbi, FLUSH_MERGE) && !f2fs_readonly(sbi->sb)) { | 2139 | if (test_opt(sbi, FLUSH_MERGE) && !f2fs_readonly(sbi->sb)) { |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 1e92c2ea6bc1..f2fe666a6ea9 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -195,6 +195,7 @@ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time); | |||
195 | F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle); | 195 | F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle); |
196 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); | 196 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); |
197 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards); | 197 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards); |
198 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections); | ||
198 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); | 199 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); |
199 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); | 200 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); |
200 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); | 201 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); |
@@ -210,6 +211,7 @@ static struct attribute *f2fs_attrs[] = { | |||
210 | ATTR_LIST(gc_idle), | 211 | ATTR_LIST(gc_idle), |
211 | ATTR_LIST(reclaim_segments), | 212 | ATTR_LIST(reclaim_segments), |
212 | ATTR_LIST(max_small_discards), | 213 | ATTR_LIST(max_small_discards), |
214 | ATTR_LIST(batched_trim_sections), | ||
213 | ATTR_LIST(ipu_policy), | 215 | ATTR_LIST(ipu_policy), |
214 | ATTR_LIST(min_ipu_util), | 216 | ATTR_LIST(min_ipu_util), |
215 | ATTR_LIST(min_fsync_blocks), | 217 | ATTR_LIST(min_fsync_blocks), |