Loading fs/f2fs/checkpoint.c +5 −0 Original line number Diff line number Diff line Loading @@ -1249,6 +1249,11 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* this is the case of multiple fstrims without any changes */ if (cpc->reason == CP_DISCARD) { if (!exist_trim_candidates(sbi, cpc)) { unblock_operations(sbi); goto out; } if (NM_I(sbi)->dirty_nat_cnt == 0 && SIT_I(sbi)->dirty_sentries == 0 && prefree_segments(sbi) == 0) { Loading fs/f2fs/f2fs.h +1 −0 Original line number Diff line number Diff line Loading @@ -2119,6 +2119,7 @@ void release_discard_addrs(struct f2fs_sb_info *); int npages_for_summary_flush(struct f2fs_sb_info *, bool); void allocate_new_segments(struct f2fs_sb_info *); int f2fs_trim_fs(struct f2fs_sb_info *, struct fstrim_range *); bool exist_trim_candidates(struct f2fs_sb_info *, struct cp_control *); struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); void update_meta_page(struct f2fs_sb_info *, void *, block_t); void write_meta_page(struct f2fs_sb_info *, struct page *); Loading fs/f2fs/segment.c +28 −5 Original line number Diff line number Diff line Loading @@ -834,7 +834,8 @@ static void __add_discard_entry(struct f2fs_sb_info *sbi, SM_I(sbi)->nr_discards += end - start; } static void add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc) static bool add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc, bool check_only) { int entries = SIT_VBLOCK_MAP_SIZE / sizeof(unsigned long); int max_blocks = sbi->blocks_per_seg; Loading @@ -848,12 +849,12 @@ static void add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc) int i; if (se->valid_blocks == max_blocks || !f2fs_discard_en(sbi)) return; return false; if (!force) { if (!test_opt(sbi, DISCARD) || !se->valid_blocks || SM_I(sbi)->nr_discards >= SM_I(sbi)->max_discards) return; return false; } /* SIT_VBLOCK_MAP_SIZE should be multiple of sizeof(unsigned long) */ Loading @@ -871,8 +872,12 @@ static void add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc) && (end - start) < cpc->trim_minlen) continue; if (check_only) return true; __add_discard_entry(sbi, cpc, se, start, end); } return false; } void release_discard_addrs(struct f2fs_sb_info *sbi) Loading Loading @@ -1453,6 +1458,24 @@ static const struct segment_allocation default_salloc_ops = { .allocate_segment = allocate_segment_by_default, }; bool exist_trim_candidates(struct f2fs_sb_info *sbi, struct cp_control *cpc) { __u64 trim_start = cpc->trim_start; bool has_candidate = false; mutex_lock(&SIT_I(sbi)->sentry_lock); for (; cpc->trim_start <= cpc->trim_end; cpc->trim_start++) { if (add_discard_addrs(sbi, cpc, true)) { has_candidate = true; break; } } mutex_unlock(&SIT_I(sbi)->sentry_lock); cpc->trim_start = trim_start; return has_candidate; } int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) { __u64 start = F2FS_BYTES_TO_BLK(range->start); Loading Loading @@ -2249,7 +2272,7 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* add discard candidates */ if (cpc->reason != CP_DISCARD) { cpc->trim_start = segno; add_discard_addrs(sbi, cpc); add_discard_addrs(sbi, cpc, false); } if (to_journal) { Loading Loading @@ -2287,7 +2310,7 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) __u64 trim_start = cpc->trim_start; for (; cpc->trim_start <= cpc->trim_end; cpc->trim_start++) add_discard_addrs(sbi, cpc); add_discard_addrs(sbi, cpc, false); cpc->trim_start = trim_start; } Loading Loading
fs/f2fs/checkpoint.c +5 −0 Original line number Diff line number Diff line Loading @@ -1249,6 +1249,11 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* this is the case of multiple fstrims without any changes */ if (cpc->reason == CP_DISCARD) { if (!exist_trim_candidates(sbi, cpc)) { unblock_operations(sbi); goto out; } if (NM_I(sbi)->dirty_nat_cnt == 0 && SIT_I(sbi)->dirty_sentries == 0 && prefree_segments(sbi) == 0) { Loading
fs/f2fs/f2fs.h +1 −0 Original line number Diff line number Diff line Loading @@ -2119,6 +2119,7 @@ void release_discard_addrs(struct f2fs_sb_info *); int npages_for_summary_flush(struct f2fs_sb_info *, bool); void allocate_new_segments(struct f2fs_sb_info *); int f2fs_trim_fs(struct f2fs_sb_info *, struct fstrim_range *); bool exist_trim_candidates(struct f2fs_sb_info *, struct cp_control *); struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); void update_meta_page(struct f2fs_sb_info *, void *, block_t); void write_meta_page(struct f2fs_sb_info *, struct page *); Loading
fs/f2fs/segment.c +28 −5 Original line number Diff line number Diff line Loading @@ -834,7 +834,8 @@ static void __add_discard_entry(struct f2fs_sb_info *sbi, SM_I(sbi)->nr_discards += end - start; } static void add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc) static bool add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc, bool check_only) { int entries = SIT_VBLOCK_MAP_SIZE / sizeof(unsigned long); int max_blocks = sbi->blocks_per_seg; Loading @@ -848,12 +849,12 @@ static void add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc) int i; if (se->valid_blocks == max_blocks || !f2fs_discard_en(sbi)) return; return false; if (!force) { if (!test_opt(sbi, DISCARD) || !se->valid_blocks || SM_I(sbi)->nr_discards >= SM_I(sbi)->max_discards) return; return false; } /* SIT_VBLOCK_MAP_SIZE should be multiple of sizeof(unsigned long) */ Loading @@ -871,8 +872,12 @@ static void add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc) && (end - start) < cpc->trim_minlen) continue; if (check_only) return true; __add_discard_entry(sbi, cpc, se, start, end); } return false; } void release_discard_addrs(struct f2fs_sb_info *sbi) Loading Loading @@ -1453,6 +1458,24 @@ static const struct segment_allocation default_salloc_ops = { .allocate_segment = allocate_segment_by_default, }; bool exist_trim_candidates(struct f2fs_sb_info *sbi, struct cp_control *cpc) { __u64 trim_start = cpc->trim_start; bool has_candidate = false; mutex_lock(&SIT_I(sbi)->sentry_lock); for (; cpc->trim_start <= cpc->trim_end; cpc->trim_start++) { if (add_discard_addrs(sbi, cpc, true)) { has_candidate = true; break; } } mutex_unlock(&SIT_I(sbi)->sentry_lock); cpc->trim_start = trim_start; return has_candidate; } int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) { __u64 start = F2FS_BYTES_TO_BLK(range->start); Loading Loading @@ -2249,7 +2272,7 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* add discard candidates */ if (cpc->reason != CP_DISCARD) { cpc->trim_start = segno; add_discard_addrs(sbi, cpc); add_discard_addrs(sbi, cpc, false); } if (to_journal) { Loading Loading @@ -2287,7 +2310,7 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) __u64 trim_start = cpc->trim_start; for (; cpc->trim_start <= cpc->trim_end; cpc->trim_start++) add_discard_addrs(sbi, cpc); add_discard_addrs(sbi, cpc, false); cpc->trim_start = trim_start; } Loading