Commit 75ab4cb8 authored by Jaegeuk Kim's avatar Jaegeuk Kim

f2fs: introduce cp_control structure

This patch add a new data structure to control checkpoint parameters.
Currently, it presents the reason of checkpoint such as is_umount and normal
sync.
Reviewed-by: default avatarChao Yu <chao2.yu@samsung.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 95dd8973
...@@ -826,7 +826,7 @@ static void wait_on_all_pages_writeback(struct f2fs_sb_info *sbi) ...@@ -826,7 +826,7 @@ static void wait_on_all_pages_writeback(struct f2fs_sb_info *sbi)
finish_wait(&sbi->cp_wait, &wait); finish_wait(&sbi->cp_wait, &wait);
} }
static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
{ {
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
...@@ -894,7 +894,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) ...@@ -894,7 +894,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks + ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks +
orphan_blocks); orphan_blocks);
if (is_umount) { if (cpc->reason == CP_UMOUNT) {
set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); set_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS+ ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS+
cp_payload_blks + data_sum_blocks + cp_payload_blks + data_sum_blocks +
...@@ -948,7 +948,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) ...@@ -948,7 +948,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
write_data_summaries(sbi, start_blk); write_data_summaries(sbi, start_blk);
start_blk += data_sum_blocks; start_blk += data_sum_blocks;
if (is_umount) { if (cpc->reason == CP_UMOUNT) {
write_node_summaries(sbi, start_blk); write_node_summaries(sbi, start_blk);
start_blk += NR_CURSEG_NODE_TYPE; start_blk += NR_CURSEG_NODE_TYPE;
} }
...@@ -988,12 +988,12 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) ...@@ -988,12 +988,12 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
/* /*
* We guarantee that this checkpoint procedure will not fail. * We guarantee that this checkpoint procedure will not fail.
*/ */
void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) void write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
{ {
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
unsigned long long ckpt_ver; unsigned long long ckpt_ver;
trace_f2fs_write_checkpoint(sbi->sb, is_umount, "start block_ops"); trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "start block_ops");
mutex_lock(&sbi->cp_mutex); mutex_lock(&sbi->cp_mutex);
...@@ -1004,7 +1004,7 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) ...@@ -1004,7 +1004,7 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
if (block_operations(sbi)) if (block_operations(sbi))
goto out; goto out;
trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish block_ops"); trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish block_ops");
f2fs_submit_merged_bio(sbi, DATA, WRITE); f2fs_submit_merged_bio(sbi, DATA, WRITE);
f2fs_submit_merged_bio(sbi, NODE, WRITE); f2fs_submit_merged_bio(sbi, NODE, WRITE);
...@@ -1023,13 +1023,13 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) ...@@ -1023,13 +1023,13 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
flush_sit_entries(sbi); flush_sit_entries(sbi);
/* unlock all the fs_lock[] in do_checkpoint() */ /* unlock all the fs_lock[] in do_checkpoint() */
do_checkpoint(sbi, is_umount); do_checkpoint(sbi, cpc);
unblock_operations(sbi); unblock_operations(sbi);
stat_inc_cp_count(sbi->stat_info); stat_inc_cp_count(sbi->stat_info);
out: out:
mutex_unlock(&sbi->cp_mutex); mutex_unlock(&sbi->cp_mutex);
trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish checkpoint"); trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint");
} }
void init_ino_entry_info(struct f2fs_sb_info *sbi) void init_ino_entry_info(struct f2fs_sb_info *sbi)
......
...@@ -96,6 +96,15 @@ enum { ...@@ -96,6 +96,15 @@ enum {
SIT_BITMAP SIT_BITMAP
}; };
enum {
CP_UMOUNT,
CP_SYNC,
};
struct cp_control {
int reason;
};
/* /*
* For CP/NAT/SIT/SSA readahead * For CP/NAT/SIT/SSA readahead
*/ */
...@@ -1314,7 +1323,7 @@ void update_dirty_page(struct inode *, struct page *); ...@@ -1314,7 +1323,7 @@ void update_dirty_page(struct inode *, struct page *);
void add_dirty_dir_inode(struct inode *); void add_dirty_dir_inode(struct inode *);
void remove_dirty_dir_inode(struct inode *); void remove_dirty_dir_inode(struct inode *);
void sync_dirty_dir_inodes(struct f2fs_sb_info *); void sync_dirty_dir_inodes(struct f2fs_sb_info *);
void write_checkpoint(struct f2fs_sb_info *, bool); void write_checkpoint(struct f2fs_sb_info *, struct cp_control *);
void init_ino_entry_info(struct f2fs_sb_info *); void init_ino_entry_info(struct f2fs_sb_info *);
int __init create_checkpoint_caches(void); int __init create_checkpoint_caches(void);
void destroy_checkpoint_caches(void); void destroy_checkpoint_caches(void);
......
...@@ -694,6 +694,9 @@ int f2fs_gc(struct f2fs_sb_info *sbi) ...@@ -694,6 +694,9 @@ int f2fs_gc(struct f2fs_sb_info *sbi)
int gc_type = BG_GC; int gc_type = BG_GC;
int nfree = 0; int nfree = 0;
int ret = -1; int ret = -1;
struct cp_control cpc = {
.reason = CP_SYNC,
};
INIT_LIST_HEAD(&ilist); INIT_LIST_HEAD(&ilist);
gc_more: gc_more:
...@@ -704,7 +707,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi) ...@@ -704,7 +707,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi)
if (gc_type == BG_GC && has_not_enough_free_secs(sbi, nfree)) { if (gc_type == BG_GC && has_not_enough_free_secs(sbi, nfree)) {
gc_type = FG_GC; gc_type = FG_GC;
write_checkpoint(sbi, false); write_checkpoint(sbi, &cpc);
} }
if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE))
...@@ -729,7 +732,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi) ...@@ -729,7 +732,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi)
goto gc_more; goto gc_more;
if (gc_type == FG_GC) if (gc_type == FG_GC)
write_checkpoint(sbi, false); write_checkpoint(sbi, &cpc);
stop: stop:
mutex_unlock(&sbi->gc_mutex); mutex_unlock(&sbi->gc_mutex);
......
...@@ -542,8 +542,11 @@ int recover_fsync_data(struct f2fs_sb_info *sbi) ...@@ -542,8 +542,11 @@ int recover_fsync_data(struct f2fs_sb_info *sbi)
set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG); set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG);
mutex_unlock(&sbi->cp_mutex); mutex_unlock(&sbi->cp_mutex);
} else if (need_writecp) { } else if (need_writecp) {
struct cp_control cpc = {
.reason = CP_SYNC,
};
mutex_unlock(&sbi->cp_mutex); mutex_unlock(&sbi->cp_mutex);
write_checkpoint(sbi, false); write_checkpoint(sbi, &cpc);
} else { } else {
mutex_unlock(&sbi->cp_mutex); mutex_unlock(&sbi->cp_mutex);
} }
......
...@@ -434,8 +434,12 @@ static void f2fs_put_super(struct super_block *sb) ...@@ -434,8 +434,12 @@ static void f2fs_put_super(struct super_block *sb)
stop_gc_thread(sbi); stop_gc_thread(sbi);
/* We don't need to do checkpoint when it's clean */ /* We don't need to do checkpoint when it's clean */
if (sbi->s_dirty) if (sbi->s_dirty) {
write_checkpoint(sbi, true); struct cp_control cpc = {
.reason = CP_UMOUNT,
};
write_checkpoint(sbi, &cpc);
}
/* /*
* normally superblock is clean, so we need to release this. * normally superblock is clean, so we need to release this.
...@@ -466,8 +470,11 @@ int f2fs_sync_fs(struct super_block *sb, int sync) ...@@ -466,8 +470,11 @@ int f2fs_sync_fs(struct super_block *sb, int sync)
trace_f2fs_sync_fs(sb, sync); trace_f2fs_sync_fs(sb, sync);
if (sync) { if (sync) {
struct cp_control cpc = {
.reason = CP_SYNC,
};
mutex_lock(&sbi->gc_mutex); mutex_lock(&sbi->gc_mutex);
write_checkpoint(sbi, false); write_checkpoint(sbi, &cpc);
mutex_unlock(&sbi->gc_mutex); mutex_unlock(&sbi->gc_mutex);
} else { } else {
f2fs_balance_fs(sbi); f2fs_balance_fs(sbi);
......
...@@ -69,6 +69,11 @@ ...@@ -69,6 +69,11 @@
{ GC_GREEDY, "Greedy" }, \ { GC_GREEDY, "Greedy" }, \
{ GC_CB, "Cost-Benefit" }) { GC_CB, "Cost-Benefit" })
#define show_cpreason(type) \
__print_symbolic(type, \
{ CP_UMOUNT, "Umount" }, \
{ CP_SYNC, "Sync" })
struct victim_sel_policy; struct victim_sel_policy;
DECLARE_EVENT_CLASS(f2fs__inode, DECLARE_EVENT_CLASS(f2fs__inode,
...@@ -944,25 +949,25 @@ TRACE_EVENT(f2fs_submit_page_mbio, ...@@ -944,25 +949,25 @@ TRACE_EVENT(f2fs_submit_page_mbio,
TRACE_EVENT(f2fs_write_checkpoint, TRACE_EVENT(f2fs_write_checkpoint,
TP_PROTO(struct super_block *sb, bool is_umount, char *msg), TP_PROTO(struct super_block *sb, int reason, char *msg),
TP_ARGS(sb, is_umount, msg), TP_ARGS(sb, reason, msg),
TP_STRUCT__entry( TP_STRUCT__entry(
__field(dev_t, dev) __field(dev_t, dev)
__field(bool, is_umount) __field(int, reason)
__field(char *, msg) __field(char *, msg)
), ),
TP_fast_assign( TP_fast_assign(
__entry->dev = sb->s_dev; __entry->dev = sb->s_dev;
__entry->is_umount = is_umount; __entry->reason = reason;
__entry->msg = msg; __entry->msg = msg;
), ),
TP_printk("dev = (%d,%d), checkpoint for %s, state = %s", TP_printk("dev = (%d,%d), checkpoint for %s, state = %s",
show_dev(__entry), show_dev(__entry),
__entry->is_umount ? "clean umount" : "consistency", show_cpreason(__entry->reason),
__entry->msg) __entry->msg)
); );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment