f2fs: introduce a periodic checkpoint flow
authorJaegeuk Kim <jaegeuk@kernel.org>
Mon, 5 Oct 2015 21:49:57 +0000 (14:49 -0700)
committerJaegeuk Kim <jaegeuk@kernel.org>
Fri, 9 Oct 2015 23:20:57 +0000 (16:20 -0700)
This patch introduces a periodic checkpoint feature.
Note that, this is not enforcing to conduct checkpoints very strictly in terms
of trigger timing, instead just hope to help user experiences.
The default value is 60 seconds.

Reviewed-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Documentation/ABI/testing/sysfs-fs-f2fs
fs/f2fs/checkpoint.c
fs/f2fs/f2fs.h
fs/f2fs/segment.c
fs/f2fs/super.c

index 2c4cc42006e8c92baad28fabfec3f3fd8ec3cff1..e066281dfd4e3cb88128ca222a330eb8a7d585e5 100644 (file)
@@ -80,3 +80,9 @@ Date:         February 2015
 Contact:       "Jaegeuk Kim" <jaegeuk@kernel.org>
 Description:
                 Controls the trimming rate in batch mode.
+
+What:          /sys/fs/f2fs/<disk>/cp_interval
+Date:          October 2015
+Contact:       "Jaegeuk Kim" <jaegeuk@kernel.org>
+Description:
+                Controls the checkpoint timing.
index ff53405aee39e47094882bac8e90e02dc0802768..0569097dbd7ab29d4f43b6311d799cf4553a3f73 100644 (file)
@@ -1114,6 +1114,9 @@ void write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
        if (cpc->reason == CP_RECOVERY)
                f2fs_msg(sbi->sb, KERN_NOTICE,
                        "checkpoint: version = %llx", ckpt_ver);
+
+       /* do checkpoint periodically */
+       sbi->cp_expires = round_jiffies_up(jiffies + HZ * sbi->cp_interval);
 out:
        mutex_unlock(&sbi->cp_mutex);
        trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint");
index 00bd47045c1ee4b5f18aa3110155b102d8f6cdcc..aad4720c516e4dfe748bace693ebb8f3b2ac7237 100644 (file)
@@ -124,6 +124,7 @@ enum {
                (SM_I(sbi)->trim_sections * (sbi)->segs_per_sec)
 #define BATCHED_TRIM_BLOCKS(sbi)       \
                (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg)
+#define DEF_CP_INTERVAL                        60      /* 60 secs */
 
 struct cp_control {
        int reason;
@@ -734,6 +735,7 @@ struct f2fs_sb_info {
        struct rw_semaphore node_write;         /* locking node writes */
        struct mutex writepages;                /* mutex for writepages() */
        wait_queue_head_t cp_wait;
+       long cp_expires, cp_interval;           /* next expected periodic cp */
 
        struct inode_management im[MAX_INO_ENTRY];      /* manage inode cache */
 
index 6b8edf21a15211fef49dd0fea0bad0152f1aa57c..1d86a35ae9fe19632fca542adc40a66970544eac 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/prefetch.h>
 #include <linux/kthread.h>
 #include <linux/swap.h>
+#include <linux/timer.h>
 
 #include "f2fs.h"
 #include "segment.h"
@@ -315,7 +316,8 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
        /* checkpoint is the only way to shrink partial cached entries */
        if (!available_free_memory(sbi, NAT_ENTRIES) ||
                        excess_prefree_segs(sbi) ||
-                       !available_free_memory(sbi, INO_ENTRIES))
+                       !available_free_memory(sbi, INO_ENTRIES) ||
+                       jiffies > sbi->cp_expires)
                f2fs_sync_fs(sbi->sb, true);
 }
 
index ba058d08cb33d751e05f391dafeb09c4ebf6724f..cb23d85a4ed3dfa69ac47b9441a0535f93878cf6 100644 (file)
@@ -215,6 +215,7 @@ F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);
 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, cp_interval);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -231,6 +232,7 @@ static struct attribute *f2fs_attrs[] = {
        ATTR_LIST(max_victim_search),
        ATTR_LIST(dir_level),
        ATTR_LIST(ram_thresh),
+       ATTR_LIST(cp_interval),
        NULL,
 };
 
@@ -1014,6 +1016,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
                atomic_set(&sbi->nr_pages[i], 0);
 
        sbi->dir_level = DEF_DIR_LEVEL;
+       sbi->cp_interval = DEF_CP_INTERVAL;
        clear_sbi_flag(sbi, SBI_NEED_FSCK);
 
        INIT_LIST_HEAD(&sbi->s_list);
@@ -1350,6 +1353,8 @@ try_onemore:
                f2fs_commit_super(sbi, true);
        }
 
+       sbi->cp_expires = round_jiffies_up(jiffies);
+
        return 0;
 
 free_kobj: