Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -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 +
			orphan_blocks);

	if (cpc->reason == CP_UMOUNT) {
		set_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
	if (__remain_node_summaries(cpc->reason))
		ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS+
				cp_payload_blks + data_sum_blocks +
				orphan_blocks + NR_CURSEG_NODE_TYPE);
	} else {
		clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
	else
		ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS +
				cp_payload_blks + data_sum_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)
		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)

	write_data_summaries(sbi, start_blk);
	start_blk += data_sum_blocks;
	if (cpc->reason == CP_UMOUNT) {
	if (__remain_node_summaries(cpc->reason)) {
		write_node_summaries(sbi, start_blk);
		start_blk += NR_CURSEG_NODE_TYPE;
	}
+23 −0
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ enum {

enum {
	CP_UMOUNT,
	CP_FASTBOOT,
	CP_SYNC,
	CP_DISCARD,
};
@@ -764,6 +765,28 @@ static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi)
	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.
 */
+1 −2
Original line number Diff line number Diff line
@@ -698,8 +698,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi)
		.iroot = RADIX_TREE_INIT(GFP_NOFS),
	};

	cpc.reason = test_opt(sbi, FASTBOOT) ? CP_UMOUNT : CP_SYNC;

	cpc.reason = __get_cp_reason(sbi);
gc_more:
	if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE)))
		goto stop;
+5 −6
Original line number Diff line number Diff line
@@ -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]);
		blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type -
							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);
		else
			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)
							CURSEG_HOT_NODE]);
		blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type -
							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,
							type - CURSEG_HOT_NODE);
		else
@@ -1421,7 +1421,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
	sum = (struct f2fs_summary_block *)page_address(new);

	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];
			int i;
			for (i = 0; i < sbi->blocks_per_seg; i++, ns++) {
@@ -1470,7 +1470,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
		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),
					NR_CURSEG_TYPE - type, META_CP);

@@ -1567,7 +1567,6 @@ 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)
{
	if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG))
	write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE);
}

+2 −3
Original line number Diff line number Diff line
@@ -500,9 +500,8 @@ int f2fs_sync_fs(struct super_block *sb, int sync)
	if (sync) {
		struct cp_control cpc;

		cpc.reason = (test_opt(sbi, FASTBOOT) ||
					is_sbi_flag_set(sbi, SBI_IS_CLOSE)) ?
						CP_UMOUNT : CP_SYNC;
		cpc.reason = __get_cp_reason(sbi);

		mutex_lock(&sbi->gc_mutex);
		write_checkpoint(sbi, &cpc);
		mutex_unlock(&sbi->gc_mutex);
Loading