diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-01-29 14:45:33 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-02-11 20:04:41 -0500 |
commit | 119ee9144534141822462e3e8a5ccc8dc537f712 (patch) | |
tree | d1db8598f68e80459d40343d70883a62606de7d5 /fs/f2fs | |
parent | 11504a8e7e20e2ff2e68176850e9b83b8bae760e (diff) |
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: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/checkpoint.c | 19 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 23 | ||||
-rw-r--r-- | fs/f2fs/gc.c | 3 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 11 | ||||
-rw-r--r-- | fs/f2fs/super.c | 5 |
5 files changed, 44 insertions, 17 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 22165fb1d0d1..f7cdcad31943 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
@@ -956,17 +956,24 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
956 | ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks + | 956 | ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks + |
957 | orphan_blocks); | 957 | orphan_blocks); |
958 | 958 | ||
959 | if (cpc->reason == CP_UMOUNT) { | 959 | if (__remain_node_summaries(cpc->reason)) |
960 | set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); | ||
961 | ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS+ | 960 | ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS+ |
962 | cp_payload_blks + data_sum_blocks + | 961 | cp_payload_blks + data_sum_blocks + |
963 | orphan_blocks + NR_CURSEG_NODE_TYPE); | 962 | orphan_blocks + NR_CURSEG_NODE_TYPE); |
964 | } else { | 963 | else |
965 | clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); | ||
966 | ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS + | 964 | ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS + |
967 | cp_payload_blks + data_sum_blocks + | 965 | cp_payload_blks + data_sum_blocks + |
968 | orphan_blocks); | 966 | orphan_blocks); |
969 | } | 967 | |
968 | if (cpc->reason == CP_UMOUNT) | ||
969 | set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); | ||
970 | else | ||
971 | clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); | ||
972 | |||
973 | if (cpc->reason == CP_FASTBOOT) | ||
974 | set_ckpt_flags(ckpt, CP_FASTBOOT_FLAG); | ||
975 | else | ||
976 | clear_ckpt_flags(ckpt, CP_FASTBOOT_FLAG); | ||
970 | 977 | ||
971 | if (orphan_num) | 978 | if (orphan_num) |
972 | set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); | 979 | 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 | 1017 | ||
1011 | write_data_summaries(sbi, start_blk); | 1018 | write_data_summaries(sbi, start_blk); |
1012 | start_blk += data_sum_blocks; | 1019 | start_blk += data_sum_blocks; |
1013 | if (cpc->reason == CP_UMOUNT) { | 1020 | if (__remain_node_summaries(cpc->reason)) { |
1014 | write_node_summaries(sbi, start_blk); | 1021 | write_node_summaries(sbi, start_blk); |
1015 | start_blk += NR_CURSEG_NODE_TYPE; | 1022 | start_blk += NR_CURSEG_NODE_TYPE; |
1016 | } | 1023 | } |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 5abe0836c179..8231a599a305 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -100,6 +100,7 @@ enum { | |||
100 | 100 | ||
101 | enum { | 101 | enum { |
102 | CP_UMOUNT, | 102 | CP_UMOUNT, |
103 | CP_FASTBOOT, | ||
103 | CP_SYNC, | 104 | CP_SYNC, |
104 | CP_DISCARD, | 105 | CP_DISCARD, |
105 | }; | 106 | }; |
@@ -764,6 +765,28 @@ static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi) | |||
764 | up_write(&sbi->cp_rwsem); | 765 | up_write(&sbi->cp_rwsem); |
765 | } | 766 | } |
766 | 767 | ||
768 | static inline int __get_cp_reason(struct f2fs_sb_info *sbi) | ||
769 | { | ||
770 | int reason = CP_SYNC; | ||
771 | |||
772 | if (test_opt(sbi, FASTBOOT)) | ||
773 | reason = CP_FASTBOOT; | ||
774 | if (is_sbi_flag_set(sbi, SBI_IS_CLOSE)) | ||
775 | reason = CP_UMOUNT; | ||
776 | return reason; | ||
777 | } | ||
778 | |||
779 | static inline bool __remain_node_summaries(int reason) | ||
780 | { | ||
781 | return (reason == CP_UMOUNT || reason == CP_FASTBOOT); | ||
782 | } | ||
783 | |||
784 | static inline bool __exist_node_summaries(struct f2fs_sb_info *sbi) | ||
785 | { | ||
786 | return (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG) || | ||
787 | is_set_ckpt_flags(F2FS_CKPT(sbi), CP_FASTBOOT_FLAG)); | ||
788 | } | ||
789 | |||
767 | /* | 790 | /* |
768 | * Check whether the given nid is within node id range. | 791 | * Check whether the given nid is within node id range. |
769 | */ | 792 | */ |
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index ba89e27f394f..76adbc3641f1 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c | |||
@@ -698,8 +698,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi) | |||
698 | .iroot = RADIX_TREE_INIT(GFP_NOFS), | 698 | .iroot = RADIX_TREE_INIT(GFP_NOFS), |
699 | }; | 699 | }; |
700 | 700 | ||
701 | cpc.reason = test_opt(sbi, FASTBOOT) ? CP_UMOUNT : CP_SYNC; | 701 | cpc.reason = __get_cp_reason(sbi); |
702 | |||
703 | gc_more: | 702 | gc_more: |
704 | if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE))) | 703 | if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE))) |
705 | goto stop; | 704 | goto stop; |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 31c4e5702c7d..5ea57ec153d1 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -1401,7 +1401,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) | |||
1401 | segno = le32_to_cpu(ckpt->cur_data_segno[type]); | 1401 | segno = le32_to_cpu(ckpt->cur_data_segno[type]); |
1402 | blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type - | 1402 | blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type - |
1403 | CURSEG_HOT_DATA]); | 1403 | CURSEG_HOT_DATA]); |
1404 | if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) | 1404 | if (__exist_node_summaries(sbi)) |
1405 | blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type); | 1405 | blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type); |
1406 | else | 1406 | else |
1407 | blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type); | 1407 | 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 | CURSEG_HOT_NODE]); | 1410 | CURSEG_HOT_NODE]); |
1411 | blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type - | 1411 | blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type - |
1412 | CURSEG_HOT_NODE]); | 1412 | CURSEG_HOT_NODE]); |
1413 | if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) | 1413 | if (__exist_node_summaries(sbi)) |
1414 | blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE, | 1414 | blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE, |
1415 | type - CURSEG_HOT_NODE); | 1415 | type - CURSEG_HOT_NODE); |
1416 | else | 1416 | else |
@@ -1421,7 +1421,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) | |||
1421 | sum = (struct f2fs_summary_block *)page_address(new); | 1421 | sum = (struct f2fs_summary_block *)page_address(new); |
1422 | 1422 | ||
1423 | if (IS_NODESEG(type)) { | 1423 | if (IS_NODESEG(type)) { |
1424 | if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) { | 1424 | if (__exist_node_summaries(sbi)) { |
1425 | struct f2fs_summary *ns = &sum->entries[0]; | 1425 | struct f2fs_summary *ns = &sum->entries[0]; |
1426 | int i; | 1426 | int i; |
1427 | for (i = 0; i < sbi->blocks_per_seg; i++, ns++) { | 1427 | 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 | type = CURSEG_HOT_NODE; | 1470 | type = CURSEG_HOT_NODE; |
1471 | } | 1471 | } |
1472 | 1472 | ||
1473 | if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG)) | 1473 | if (__exist_node_summaries(sbi)) |
1474 | ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type), | 1474 | ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type), |
1475 | NR_CURSEG_TYPE - type, META_CP); | 1475 | NR_CURSEG_TYPE - type, META_CP); |
1476 | 1476 | ||
@@ -1567,8 +1567,7 @@ void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk) | |||
1567 | 1567 | ||
1568 | void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk) | 1568 | void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk) |
1569 | { | 1569 | { |
1570 | if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG)) | 1570 | write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE); |
1571 | write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE); | ||
1572 | } | 1571 | } |
1573 | 1572 | ||
1574 | int lookup_journal_in_cursum(struct f2fs_summary_block *sum, int type, | 1573 | int lookup_journal_in_cursum(struct f2fs_summary_block *sum, int type, |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 06d903b5d6c8..bfeab3c81a48 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -500,9 +500,8 @@ int f2fs_sync_fs(struct super_block *sb, int sync) | |||
500 | if (sync) { | 500 | if (sync) { |
501 | struct cp_control cpc; | 501 | struct cp_control cpc; |
502 | 502 | ||
503 | cpc.reason = (test_opt(sbi, FASTBOOT) || | 503 | cpc.reason = __get_cp_reason(sbi); |
504 | is_sbi_flag_set(sbi, SBI_IS_CLOSE)) ? | 504 | |
505 | CP_UMOUNT : CP_SYNC; | ||
506 | mutex_lock(&sbi->gc_mutex); | 505 | mutex_lock(&sbi->gc_mutex); |
507 | write_checkpoint(sbi, &cpc); | 506 | write_checkpoint(sbi, &cpc); |
508 | mutex_unlock(&sbi->gc_mutex); | 507 | mutex_unlock(&sbi->gc_mutex); |