Commit 119ee914 authored by Jaegeuk Kim's avatar Jaegeuk Kim

f2fs: split UMOUNT and FASTBOOT flags

This patch adds FASTBOOT flag into checkpoint as follows.

 - CP_UMOUNT_FLAG is set when system is umounted.
 - CP_FASTBOOT_FLAG is set when intermediate checkpoint having node summaries
   was done.

So, if you get CP_UMOUNT_FLAG from checkpoint, the system was umounted cleanly.
Instead, if there was sudden-power-off, you can get CP_FASTBOOT_FLAG or nothing.
Reviewed-by: default avatarChao Yu <chao2.yu@samsung.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 11504a8e
...@@ -956,17 +956,24 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -956,17 +956,24 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
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 (cpc->reason == CP_UMOUNT) { if (__remain_node_summaries(cpc->reason))
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 +
orphan_blocks + NR_CURSEG_NODE_TYPE); orphan_blocks + NR_CURSEG_NODE_TYPE);
} else { else
clear_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 +
orphan_blocks); orphan_blocks);
}
if (cpc->reason == CP_UMOUNT)
set_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
else
clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
if (cpc->reason == CP_FASTBOOT)
set_ckpt_flags(ckpt, CP_FASTBOOT_FLAG);
else
clear_ckpt_flags(ckpt, CP_FASTBOOT_FLAG);
if (orphan_num) if (orphan_num)
set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG);
...@@ -1010,7 +1017,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1010,7 +1017,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
write_data_summaries(sbi, start_blk); write_data_summaries(sbi, start_blk);
start_blk += data_sum_blocks; start_blk += data_sum_blocks;
if (cpc->reason == CP_UMOUNT) { if (__remain_node_summaries(cpc->reason)) {
write_node_summaries(sbi, start_blk); write_node_summaries(sbi, start_blk);
start_blk += NR_CURSEG_NODE_TYPE; start_blk += NR_CURSEG_NODE_TYPE;
} }
......
...@@ -100,6 +100,7 @@ enum { ...@@ -100,6 +100,7 @@ enum {
enum { enum {
CP_UMOUNT, CP_UMOUNT,
CP_FASTBOOT,
CP_SYNC, CP_SYNC,
CP_DISCARD, CP_DISCARD,
}; };
...@@ -764,6 +765,28 @@ static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi) ...@@ -764,6 +765,28 @@ static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi)
up_write(&sbi->cp_rwsem); up_write(&sbi->cp_rwsem);
} }
static inline int __get_cp_reason(struct f2fs_sb_info *sbi)
{
int reason = CP_SYNC;
if (test_opt(sbi, FASTBOOT))
reason = CP_FASTBOOT;
if (is_sbi_flag_set(sbi, SBI_IS_CLOSE))
reason = CP_UMOUNT;
return reason;
}
static inline bool __remain_node_summaries(int reason)
{
return (reason == CP_UMOUNT || reason == CP_FASTBOOT);
}
static inline bool __exist_node_summaries(struct f2fs_sb_info *sbi)
{
return (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG) ||
is_set_ckpt_flags(F2FS_CKPT(sbi), CP_FASTBOOT_FLAG));
}
/* /*
* Check whether the given nid is within node id range. * Check whether the given nid is within node id range.
*/ */
......
...@@ -698,8 +698,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi) ...@@ -698,8 +698,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi)
.iroot = RADIX_TREE_INIT(GFP_NOFS), .iroot = RADIX_TREE_INIT(GFP_NOFS),
}; };
cpc.reason = test_opt(sbi, FASTBOOT) ? CP_UMOUNT : CP_SYNC; cpc.reason = __get_cp_reason(sbi);
gc_more: gc_more:
if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE))) if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE)))
goto stop; goto stop;
......
...@@ -1401,7 +1401,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) ...@@ -1401,7 +1401,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
segno = le32_to_cpu(ckpt->cur_data_segno[type]); segno = le32_to_cpu(ckpt->cur_data_segno[type]);
blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type - blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type -
CURSEG_HOT_DATA]); CURSEG_HOT_DATA]);
if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) if (__exist_node_summaries(sbi))
blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type); blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type);
else else
blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type); blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type);
...@@ -1410,7 +1410,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) ...@@ -1410,7 +1410,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
CURSEG_HOT_NODE]); CURSEG_HOT_NODE]);
blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type - blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type -
CURSEG_HOT_NODE]); CURSEG_HOT_NODE]);
if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) if (__exist_node_summaries(sbi))
blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE, blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE,
type - CURSEG_HOT_NODE); type - CURSEG_HOT_NODE);
else else
...@@ -1421,7 +1421,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) ...@@ -1421,7 +1421,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
sum = (struct f2fs_summary_block *)page_address(new); sum = (struct f2fs_summary_block *)page_address(new);
if (IS_NODESEG(type)) { if (IS_NODESEG(type)) {
if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) { if (__exist_node_summaries(sbi)) {
struct f2fs_summary *ns = &sum->entries[0]; struct f2fs_summary *ns = &sum->entries[0];
int i; int i;
for (i = 0; i < sbi->blocks_per_seg; i++, ns++) { for (i = 0; i < sbi->blocks_per_seg; i++, ns++) {
...@@ -1470,7 +1470,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi) ...@@ -1470,7 +1470,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
type = CURSEG_HOT_NODE; type = CURSEG_HOT_NODE;
} }
if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG)) if (__exist_node_summaries(sbi))
ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type), ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type),
NR_CURSEG_TYPE - type, META_CP); NR_CURSEG_TYPE - type, META_CP);
...@@ -1567,8 +1567,7 @@ void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk) ...@@ -1567,8 +1567,7 @@ void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk) void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
{ {
if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG)) write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE);
write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE);
} }
int lookup_journal_in_cursum(struct f2fs_summary_block *sum, int type, int lookup_journal_in_cursum(struct f2fs_summary_block *sum, int type,
......
...@@ -500,9 +500,8 @@ int f2fs_sync_fs(struct super_block *sb, int sync) ...@@ -500,9 +500,8 @@ int f2fs_sync_fs(struct super_block *sb, int sync)
if (sync) { if (sync) {
struct cp_control cpc; struct cp_control cpc;
cpc.reason = (test_opt(sbi, FASTBOOT) || cpc.reason = __get_cp_reason(sbi);
is_sbi_flag_set(sbi, SBI_IS_CLOSE)) ?
CP_UMOUNT : CP_SYNC;
mutex_lock(&sbi->gc_mutex); mutex_lock(&sbi->gc_mutex);
write_checkpoint(sbi, &cpc); write_checkpoint(sbi, &cpc);
mutex_unlock(&sbi->gc_mutex); mutex_unlock(&sbi->gc_mutex);
......
...@@ -87,6 +87,7 @@ struct f2fs_super_block { ...@@ -87,6 +87,7 @@ struct f2fs_super_block {
/* /*
* For checkpoint * For checkpoint
*/ */
#define CP_FASTBOOT_FLAG 0x00000020
#define CP_FSCK_FLAG 0x00000010 #define CP_FSCK_FLAG 0x00000010
#define CP_ERROR_FLAG 0x00000008 #define CP_ERROR_FLAG 0x00000008
#define CP_COMPACT_SUM_FLAG 0x00000004 #define CP_COMPACT_SUM_FLAG 0x00000004
......
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
#define show_cpreason(type) \ #define show_cpreason(type) \
__print_symbolic(type, \ __print_symbolic(type, \
{ CP_UMOUNT, "Umount" }, \ { CP_UMOUNT, "Umount" }, \
{ CP_FASTBOOT, "Fastboot" }, \
{ CP_SYNC, "Sync" }, \ { CP_SYNC, "Sync" }, \
{ CP_DISCARD, "Discard" }) { CP_DISCARD, "Discard" })
......
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