f2fs: allocate node and hot data in the beginning of partition
authorJaegeuk Kim <jaegeuk@kernel.org>
Sat, 25 Mar 2017 00:41:45 +0000 (20:41 -0400)
committerJaegeuk Kim <jaegeuk@kernel.org>
Thu, 30 Mar 2017 00:34:37 +0000 (17:34 -0700)
In order to give more spatial locality, this patch changes the block allocation
policy which assigns beginning of partition for small and hot data/node blocks.
In order to do this, we set noheap allocation by default and introduce another
mount option, heap, to reset it back.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/gc.c
fs/f2fs/segment.c
fs/f2fs/super.c

index 704bea678d37f1406e7a30418459959da4ec6052..63fefef04184e24b81d3eec2f76c89574d86d2bf 100644 (file)
@@ -172,7 +172,11 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type,
        if (gc_type != FG_GC && p->max_search > sbi->max_victim_search)
                p->max_search = sbi->max_victim_search;
 
-       p->offset = sbi->last_victim[p->gc_mode];
+       /* let's select beginning hot/small space first */
+       if (type == CURSEG_HOT_DATA || IS_NODESEG(type))
+               p->offset = 0;
+       else
+               p->offset = sbi->last_victim[p->gc_mode];
 }
 
 static unsigned int get_max_cost(struct f2fs_sb_info *sbi,
index c5a5258f71c5d25649db1912c44cb5322967a726..c5f0075764bf8c765238012f655972beabe92cdb 100644 (file)
@@ -1519,6 +1519,14 @@ static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified)
        __set_sit_entry_type(sbi, type, curseg->segno, modified);
 }
 
+static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type)
+{
+       if (type == CURSEG_HOT_DATA || IS_NODESEG(type))
+               return 0;
+
+       return CURSEG_I(sbi, type)->segno;
+}
+
 /*
  * Allocate a current working segment.
  * This function always allocates a free segment in LFS manner.
@@ -1537,6 +1545,7 @@ static void new_curseg(struct f2fs_sb_info *sbi, int type, bool new_sec)
        if (test_opt(sbi, NOHEAP))
                dir = ALLOC_RIGHT;
 
+       segno = __get_next_segno(sbi, type);
        get_new_segment(sbi, &segno, new_sec, dir);
        curseg->next_segno = segno;
        reset_curseg(sbi, type, 1);
index 49434f951acecb800727997c312d35188d48314d..f315b54cd840ccf37afc438485a19dd94a4f2cdd 100644 (file)
@@ -83,6 +83,7 @@ enum {
        Opt_discard,
        Opt_nodiscard,
        Opt_noheap,
+       Opt_heap,
        Opt_user_xattr,
        Opt_nouser_xattr,
        Opt_acl,
@@ -117,6 +118,7 @@ static match_table_t f2fs_tokens = {
        {Opt_discard, "discard"},
        {Opt_nodiscard, "nodiscard"},
        {Opt_noheap, "no_heap"},
+       {Opt_heap, "heap"},
        {Opt_user_xattr, "user_xattr"},
        {Opt_nouser_xattr, "nouser_xattr"},
        {Opt_acl, "acl"},
@@ -437,6 +439,9 @@ static int parse_options(struct super_block *sb, char *options)
                case Opt_noheap:
                        set_opt(sbi, NOHEAP);
                        break;
+               case Opt_heap:
+                       clear_opt(sbi, NOHEAP);
+                       break;
 #ifdef CONFIG_F2FS_FS_XATTR
                case Opt_user_xattr:
                        set_opt(sbi, XATTR_USER);
@@ -914,7 +919,9 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
        if (test_opt(sbi, DISCARD))
                seq_puts(seq, ",discard");
        if (test_opt(sbi, NOHEAP))
-               seq_puts(seq, ",no_heap_alloc");
+               seq_puts(seq, ",no_heap");
+       else
+               seq_puts(seq, ",heap");
 #ifdef CONFIG_F2FS_FS_XATTR
        if (test_opt(sbi, XATTR_USER))
                seq_puts(seq, ",user_xattr");
@@ -1047,6 +1054,7 @@ static void default_options(struct f2fs_sb_info *sbi)
        set_opt(sbi, INLINE_DATA);
        set_opt(sbi, INLINE_DENTRY);
        set_opt(sbi, EXTENT_CACHE);
+       set_opt(sbi, NOHEAP);
        sbi->sb->s_flags |= MS_LAZYTIME;
        set_opt(sbi, FLUSH_MERGE);
        if (f2fs_sb_mounted_blkzoned(sbi->sb)) {