diff options
Diffstat (limited to 'fs/f2fs/checkpoint.c')
-rw-r--r-- | fs/f2fs/checkpoint.c | 70 |
1 files changed, 49 insertions, 21 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index f73ee9534d83..0339daf4ca02 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
@@ -249,7 +249,8 @@ static int f2fs_write_meta_page(struct page *page, | |||
249 | dec_page_count(sbi, F2FS_DIRTY_META); | 249 | dec_page_count(sbi, F2FS_DIRTY_META); |
250 | 250 | ||
251 | if (wbc->for_reclaim) | 251 | if (wbc->for_reclaim) |
252 | f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, META, WRITE); | 252 | f2fs_submit_merged_bio_cond(sbi, page->mapping->host, |
253 | 0, page->index, META, WRITE); | ||
253 | 254 | ||
254 | unlock_page(page); | 255 | unlock_page(page); |
255 | 256 | ||
@@ -493,6 +494,7 @@ int acquire_orphan_inode(struct f2fs_sb_info *sbi) | |||
493 | #ifdef CONFIG_F2FS_FAULT_INJECTION | 494 | #ifdef CONFIG_F2FS_FAULT_INJECTION |
494 | if (time_to_inject(sbi, FAULT_ORPHAN)) { | 495 | if (time_to_inject(sbi, FAULT_ORPHAN)) { |
495 | spin_unlock(&im->ino_lock); | 496 | spin_unlock(&im->ino_lock); |
497 | f2fs_show_injection_info(FAULT_ORPHAN); | ||
496 | return -ENOSPC; | 498 | return -ENOSPC; |
497 | } | 499 | } |
498 | #endif | 500 | #endif |
@@ -681,8 +683,7 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr, | |||
681 | return -EINVAL; | 683 | return -EINVAL; |
682 | } | 684 | } |
683 | 685 | ||
684 | crc = le32_to_cpu(*((__le32 *)((unsigned char *)*cp_block | 686 | crc = cur_cp_crc(*cp_block); |
685 | + crc_offset))); | ||
686 | if (!f2fs_crc_valid(sbi, crc, *cp_block, crc_offset)) { | 687 | if (!f2fs_crc_valid(sbi, crc, *cp_block, crc_offset)) { |
687 | f2fs_msg(sbi->sb, KERN_WARNING, "invalid crc value"); | 688 | f2fs_msg(sbi->sb, KERN_WARNING, "invalid crc value"); |
688 | return -EINVAL; | 689 | return -EINVAL; |
@@ -891,7 +892,7 @@ retry: | |||
891 | F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA)); | 892 | F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA)); |
892 | return 0; | 893 | return 0; |
893 | } | 894 | } |
894 | fi = list_entry(head->next, struct f2fs_inode_info, dirty_list); | 895 | fi = list_first_entry(head, struct f2fs_inode_info, dirty_list); |
895 | inode = igrab(&fi->vfs_inode); | 896 | inode = igrab(&fi->vfs_inode); |
896 | spin_unlock(&sbi->inode_lock[type]); | 897 | spin_unlock(&sbi->inode_lock[type]); |
897 | if (inode) { | 898 | if (inode) { |
@@ -924,7 +925,7 @@ int f2fs_sync_inode_meta(struct f2fs_sb_info *sbi) | |||
924 | spin_unlock(&sbi->inode_lock[DIRTY_META]); | 925 | spin_unlock(&sbi->inode_lock[DIRTY_META]); |
925 | return 0; | 926 | return 0; |
926 | } | 927 | } |
927 | fi = list_entry(head->next, struct f2fs_inode_info, | 928 | fi = list_first_entry(head, struct f2fs_inode_info, |
928 | gdirty_list); | 929 | gdirty_list); |
929 | inode = igrab(&fi->vfs_inode); | 930 | inode = igrab(&fi->vfs_inode); |
930 | spin_unlock(&sbi->inode_lock[DIRTY_META]); | 931 | spin_unlock(&sbi->inode_lock[DIRTY_META]); |
@@ -998,8 +999,6 @@ out: | |||
998 | static void unblock_operations(struct f2fs_sb_info *sbi) | 999 | static void unblock_operations(struct f2fs_sb_info *sbi) |
999 | { | 1000 | { |
1000 | up_write(&sbi->node_write); | 1001 | up_write(&sbi->node_write); |
1001 | |||
1002 | build_free_nids(sbi, false); | ||
1003 | f2fs_unlock_all(sbi); | 1002 | f2fs_unlock_all(sbi); |
1004 | } | 1003 | } |
1005 | 1004 | ||
@@ -1025,6 +1024,10 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1025 | 1024 | ||
1026 | spin_lock(&sbi->cp_lock); | 1025 | spin_lock(&sbi->cp_lock); |
1027 | 1026 | ||
1027 | if (cpc->reason == CP_UMOUNT && ckpt->cp_pack_total_block_count > | ||
1028 | sbi->blocks_per_seg - NM_I(sbi)->nat_bits_blocks) | ||
1029 | disable_nat_bits(sbi, false); | ||
1030 | |||
1028 | if (cpc->reason == CP_UMOUNT) | 1031 | if (cpc->reason == CP_UMOUNT) |
1029 | __set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); | 1032 | __set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); |
1030 | else | 1033 | else |
@@ -1137,6 +1140,28 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1137 | 1140 | ||
1138 | start_blk = __start_cp_next_addr(sbi); | 1141 | start_blk = __start_cp_next_addr(sbi); |
1139 | 1142 | ||
1143 | /* write nat bits */ | ||
1144 | if (enabled_nat_bits(sbi, cpc)) { | ||
1145 | __u64 cp_ver = cur_cp_version(ckpt); | ||
1146 | unsigned int i; | ||
1147 | block_t blk; | ||
1148 | |||
1149 | cp_ver |= ((__u64)crc32 << 32); | ||
1150 | *(__le64 *)nm_i->nat_bits = cpu_to_le64(cp_ver); | ||
1151 | |||
1152 | blk = start_blk + sbi->blocks_per_seg - nm_i->nat_bits_blocks; | ||
1153 | for (i = 0; i < nm_i->nat_bits_blocks; i++) | ||
1154 | update_meta_page(sbi, nm_i->nat_bits + | ||
1155 | (i << F2FS_BLKSIZE_BITS), blk + i); | ||
1156 | |||
1157 | /* Flush all the NAT BITS pages */ | ||
1158 | while (get_pages(sbi, F2FS_DIRTY_META)) { | ||
1159 | sync_meta_pages(sbi, META, LONG_MAX); | ||
1160 | if (unlikely(f2fs_cp_error(sbi))) | ||
1161 | return -EIO; | ||
1162 | } | ||
1163 | } | ||
1164 | |||
1140 | /* need to wait for end_io results */ | 1165 | /* need to wait for end_io results */ |
1141 | wait_on_all_pages_writeback(sbi); | 1166 | wait_on_all_pages_writeback(sbi); |
1142 | if (unlikely(f2fs_cp_error(sbi))) | 1167 | if (unlikely(f2fs_cp_error(sbi))) |
@@ -1248,15 +1273,20 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1248 | f2fs_flush_merged_bios(sbi); | 1273 | f2fs_flush_merged_bios(sbi); |
1249 | 1274 | ||
1250 | /* this is the case of multiple fstrims without any changes */ | 1275 | /* this is the case of multiple fstrims without any changes */ |
1251 | if (cpc->reason == CP_DISCARD && !is_sbi_flag_set(sbi, SBI_IS_DIRTY)) { | 1276 | if (cpc->reason == CP_DISCARD) { |
1252 | f2fs_bug_on(sbi, NM_I(sbi)->dirty_nat_cnt); | 1277 | if (!exist_trim_candidates(sbi, cpc)) { |
1253 | f2fs_bug_on(sbi, SIT_I(sbi)->dirty_sentries); | 1278 | unblock_operations(sbi); |
1254 | f2fs_bug_on(sbi, prefree_segments(sbi)); | 1279 | goto out; |
1255 | flush_sit_entries(sbi, cpc); | 1280 | } |
1256 | clear_prefree_segments(sbi, cpc); | 1281 | |
1257 | f2fs_wait_all_discard_bio(sbi); | 1282 | if (NM_I(sbi)->dirty_nat_cnt == 0 && |
1258 | unblock_operations(sbi); | 1283 | SIT_I(sbi)->dirty_sentries == 0 && |
1259 | goto out; | 1284 | prefree_segments(sbi) == 0) { |
1285 | flush_sit_entries(sbi, cpc); | ||
1286 | clear_prefree_segments(sbi, cpc); | ||
1287 | unblock_operations(sbi); | ||
1288 | goto out; | ||
1289 | } | ||
1260 | } | 1290 | } |
1261 | 1291 | ||
1262 | /* | 1292 | /* |
@@ -1268,17 +1298,15 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1268 | ckpt->checkpoint_ver = cpu_to_le64(++ckpt_ver); | 1298 | ckpt->checkpoint_ver = cpu_to_le64(++ckpt_ver); |
1269 | 1299 | ||
1270 | /* write cached NAT/SIT entries to NAT/SIT area */ | 1300 | /* write cached NAT/SIT entries to NAT/SIT area */ |
1271 | flush_nat_entries(sbi); | 1301 | flush_nat_entries(sbi, cpc); |
1272 | flush_sit_entries(sbi, cpc); | 1302 | flush_sit_entries(sbi, cpc); |
1273 | 1303 | ||
1274 | /* unlock all the fs_lock[] in do_checkpoint() */ | 1304 | /* unlock all the fs_lock[] in do_checkpoint() */ |
1275 | err = do_checkpoint(sbi, cpc); | 1305 | err = do_checkpoint(sbi, cpc); |
1276 | if (err) { | 1306 | if (err) |
1277 | release_discard_addrs(sbi); | 1307 | release_discard_addrs(sbi); |
1278 | } else { | 1308 | else |
1279 | clear_prefree_segments(sbi, cpc); | 1309 | clear_prefree_segments(sbi, cpc); |
1280 | f2fs_wait_all_discard_bio(sbi); | ||
1281 | } | ||
1282 | 1310 | ||
1283 | unblock_operations(sbi); | 1311 | unblock_operations(sbi); |
1284 | stat_inc_cp_count(sbi->stat_info); | 1312 | stat_inc_cp_count(sbi->stat_info); |