Commit 60b99b48 authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: introduce a periodic checkpoint flow



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: default avatarChao Yu <chao2.yu@samsung.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 5c267434
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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.
+3 −0
Original line number Diff line number Diff line
@@ -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");
+2 −0
Original line number Diff line number Diff line
@@ -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 */

+3 −1
Original line number Diff line number Diff line
@@ -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);
}

+5 −0
Original line number Diff line number Diff line
@@ -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: