aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2017-02-24 18:46:00 +0800
committerMister Oyster <oysterized@gmail.com>2017-04-13 12:35:02 +0200
commitc01af61c498587d0da0afa4ca52793d83f8630d1 (patch)
tree5d1472d5fa2758e5936ac3f10e5c76b0ad28c9d7
parent11f5cfb6a2953e6999877f179848c47aee90ee70 (diff)
f2fs: select target segment with closer temperature in SSR mode
In SSR mode, we can allocate target segment which has different temperature type from the type of current block, in order to avoid mixing coldest and hottest data/node as much as possible, change SSR allocation policy to select closer temperature for current block prior. Signed-off-by: Yunlong Song <yunlong.song@huawei.com> Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/segment.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 7575fab95..be93c9674 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1680,7 +1680,8 @@ static int get_ssr_segment(struct f2fs_sb_info *sbi, int type)
{
struct curseg_info *curseg = CURSEG_I(sbi, type);
const struct victim_selection *v_ops = DIRTY_I(sbi)->v_ops;
- int i, n;
+ int i, cnt;
+ bool reversed = false;
/* need_SSR() already forces to do this */
if (v_ops->get_victim(sbi, &(curseg)->next_segno, BG_GC, type, SSR))
@@ -1688,14 +1689,24 @@ static int get_ssr_segment(struct f2fs_sb_info *sbi, int type)
/* For node segments, let's do SSR more intensively */
if (IS_NODESEG(type)) {
- i = CURSEG_HOT_NODE;
- n = CURSEG_COLD_NODE;
+ if (type >= CURSEG_WARM_NODE) {
+ reversed = true;
+ i = CURSEG_COLD_NODE;
+ } else {
+ i = CURSEG_HOT_NODE;
+ }
+ cnt = NR_CURSEG_NODE_TYPE;
} else {
- i = CURSEG_HOT_DATA;
- n = CURSEG_COLD_DATA;
+ if (type >= CURSEG_WARM_DATA) {
+ reversed = true;
+ i = CURSEG_COLD_DATA;
+ } else {
+ i = CURSEG_HOT_DATA;
+ }
+ cnt = NR_CURSEG_DATA_TYPE;
}
- for (; i <= n; i++) {
+ for (; cnt-- > 0; reversed ? i-- : i++) {
if (i == type)
continue;
if (v_ops->get_victim(sbi, &(curseg)->next_segno,