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: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
95dd897301
commit
75ab4cb830
|
@ -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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
/*
|
/*
|
||||||
* 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)
|
||||||
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)
|
||||||
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 {
|
||||||
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 *);
|
||||||
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)
|
||||||
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 @@ gc_more:
|
||||||
|
|
||||||
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 @@ gc_more:
|
||||||
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 @@ out:
|
||||||
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)
|
||||||
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)
|
||||||
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 @@
|
||||||
{ 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,
|
||||||
|
|
||||||
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)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue