Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

f2fs: checkpoint disabling

Note that, it requires "f2fs: return correct errno in f2fs_gc".

This adds a lightweight non-persistent snapshotting scheme to f2fs.

To use, mount with the option checkpoint=disable, and to return to
normal operation, remount with checkpoint=enable. If the filesystem
is shut down before remounting with checkpoint=enable, it will revert
back to its apparent state when it was first mounted with
checkpoint=disable. This is useful for situations where you wish to be
able to roll back the state of the disk in case of some critical
failure.

Signed-off-by: Daniel Rosenberg <drosen@google.com>
[Jaegeuk Kim: use SB_RDONLY instead of MS_RDONLY]
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

authored by

Daniel Rosenberg and committed by
Jaegeuk Kim
4354994f fb7d70db

+324 -14
+5
Documentation/filesystems/f2fs.txt
··· 212 212 non-atomic files likewise "nobarrier" mount option. 213 213 test_dummy_encryption Enable dummy encryption, which provides a fake fscrypt 214 214 context. The fake fscrypt context is used by xfstests. 215 + checkpoint=%s Set to "disable" to turn off checkpointing. Set to "enable" 216 + to reenable checkpointing. Is enabled by default. While 217 + disabled, any unmounting or unexpected shutdowns will cause 218 + the filesystem contents to appear as they did when the 219 + filesystem was mounted with that option. 215 220 216 221 ================================================================================ 217 222 DEBUGFS ENTRIES
+12
fs/f2fs/checkpoint.c
··· 1210 1210 if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) 1211 1211 __set_ckpt_flags(ckpt, CP_FSCK_FLAG); 1212 1212 1213 + if (is_sbi_flag_set(sbi, SBI_CP_DISABLED)) 1214 + __set_ckpt_flags(ckpt, CP_DISABLED_FLAG); 1215 + else 1216 + __clear_ckpt_flags(ckpt, CP_DISABLED_FLAG); 1217 + 1213 1218 /* set this flag to activate crc|cp_ver for recovery */ 1214 1219 __set_ckpt_flags(ckpt, CP_CRC_RECOVERY_FLAG); 1215 1220 __clear_ckpt_flags(ckpt, CP_NOCRC_RECOVERY_FLAG); ··· 1422 1417 1423 1418 clear_sbi_flag(sbi, SBI_IS_DIRTY); 1424 1419 clear_sbi_flag(sbi, SBI_NEED_CP); 1420 + sbi->unusable_block_count = 0; 1425 1421 __set_cp_next_pack(sbi); 1426 1422 1427 1423 /* ··· 1447 1441 unsigned long long ckpt_ver; 1448 1442 int err = 0; 1449 1443 1444 + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { 1445 + if (cpc->reason != CP_PAUSE) 1446 + return 0; 1447 + f2fs_msg(sbi->sb, KERN_WARNING, 1448 + "Start checkpoint disabled!"); 1449 + } 1450 1450 mutex_lock(&sbi->cp_mutex); 1451 1451 1452 1452 if (!is_sbi_flag_set(sbi, SBI_IS_DIRTY) &&
+13 -1
fs/f2fs/data.c
··· 537 537 if (fio->in_list) 538 538 goto next; 539 539 out: 540 - if (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)) 540 + if (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) || 541 + f2fs_is_checkpoint_ready(sbi)) 541 542 __submit_merged_bio(io); 542 543 up_write(&io->io_rwsem); 543 544 } ··· 1704 1703 is_inode_flag_set(inode, FI_NEED_IPU)) 1705 1704 return true; 1706 1705 1706 + if (unlikely(fio && is_sbi_flag_set(sbi, SBI_CP_DISABLED) && 1707 + !f2fs_is_checkpointed_data(sbi, fio->old_blkaddr))) 1708 + return true; 1709 + 1707 1710 return false; 1708 1711 } 1709 1712 ··· 1737 1732 if (is_cold_data(fio->page)) 1738 1733 return true; 1739 1734 if (IS_ATOMIC_WRITTEN_PAGE(fio->page)) 1735 + return true; 1736 + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) && 1737 + f2fs_is_checkpointed_data(sbi, fio->old_blkaddr))) 1740 1738 return true; 1741 1739 } 1742 1740 return false; ··· 2360 2352 int err = 0; 2361 2353 2362 2354 trace_f2fs_write_begin(inode, pos, len, flags); 2355 + 2356 + err = f2fs_is_checkpoint_ready(sbi); 2357 + if (err) 2358 + goto fail; 2363 2359 2364 2360 if ((f2fs_is_atomic_file(inode) && 2365 2361 !f2fs_available_free_memory(sbi, INMEM_PAGES)) ||
+2 -1
fs/f2fs/debug.c
··· 272 272 seq_printf(s, "\n=====[ partition info(%pg). #%d, %s, CP: %s]=====\n", 273 273 si->sbi->sb->s_bdev, i++, 274 274 f2fs_readonly(si->sbi->sb) ? "RO": "RW", 275 - f2fs_cp_error(si->sbi) ? "Error": "Good"); 275 + is_set_ckpt_flags(si->sbi, CP_DISABLED_FLAG) ? 276 + "Disabled": (f2fs_cp_error(si->sbi) ? "Error": "Good")); 276 277 seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ", 277 278 si->sit_area_segs, si->nat_area_segs); 278 279 seq_printf(s, "[SSA: %d] [MAIN: %d",
+17 -1
fs/f2fs/f2fs.h
··· 99 99 #define F2FS_MOUNT_QUOTA 0x00400000 100 100 #define F2FS_MOUNT_INLINE_XATTR_SIZE 0x00800000 101 101 #define F2FS_MOUNT_RESERVE_ROOT 0x01000000 102 + #define F2FS_MOUNT_DISABLE_CHECKPOINT 0x02000000 102 103 103 104 #define F2FS_OPTION(sbi) ((sbi)->mount_opt) 104 105 #define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option) ··· 179 178 #define CP_RECOVERY 0x00000008 180 179 #define CP_DISCARD 0x00000010 181 180 #define CP_TRIMMED 0x00000020 181 + #define CP_PAUSE 0x00000040 182 182 183 183 #define MAX_DISCARD_BLOCKS(sbi) BLKS_PER_SEC(sbi) 184 184 #define DEF_MAX_DISCARD_REQUEST 8 /* issue 8 discards per round */ ··· 189 187 #define DEF_DISCARD_URGENT_UTIL 80 /* do more discard over 80% */ 190 188 #define DEF_CP_INTERVAL 60 /* 60 secs */ 191 189 #define DEF_IDLE_INTERVAL 5 /* 5 secs */ 190 + #define DEF_DISABLE_INTERVAL 5 /* 5 secs */ 192 191 193 192 struct cp_control { 194 193 int reason; ··· 1095 1092 SBI_NEED_CP, /* need to checkpoint */ 1096 1093 SBI_IS_SHUTDOWN, /* shutdown by ioctl */ 1097 1094 SBI_IS_RECOVERED, /* recovered orphan/data */ 1095 + SBI_CP_DISABLED, /* CP was disabled last mount */ 1098 1096 }; 1099 1097 1100 1098 enum { ··· 1103 1099 REQ_TIME, 1104 1100 DISCARD_TIME, 1105 1101 GC_TIME, 1102 + DISABLE_TIME, 1106 1103 MAX_TIME, 1107 1104 }; 1108 1105 ··· 1229 1224 block_t last_valid_block_count; /* for recovery */ 1230 1225 block_t reserved_blocks; /* configurable reserved blocks */ 1231 1226 block_t current_reserved_blocks; /* current reserved blocks */ 1227 + 1228 + /* Additional tracking for no checkpoint mode */ 1229 + block_t unusable_block_count; /* # of blocks saved by last cp */ 1232 1230 1233 1231 unsigned int nquota_files; /* # of quota sysfile */ 1234 1232 ··· 1743 1735 1744 1736 if (!__allow_reserved_blocks(sbi, inode, true)) 1745 1737 avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks; 1746 - 1738 + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 1739 + avail_user_block_count -= sbi->unusable_block_count; 1747 1740 if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) { 1748 1741 diff = sbi->total_valid_block_count - avail_user_block_count; 1749 1742 if (diff > *count) ··· 1951 1942 1952 1943 if (!__allow_reserved_blocks(sbi, inode, false)) 1953 1944 valid_block_count += F2FS_OPTION(sbi).root_reserved_blocks; 1945 + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 1946 + valid_block_count += sbi->unusable_block_count; 1954 1947 1955 1948 if (unlikely(valid_block_count > sbi->user_block_count)) { 1956 1949 spin_unlock(&sbi->stat_lock); ··· 2956 2945 bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi); 2957 2946 void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi, 2958 2947 struct cp_control *cpc); 2948 + void f2fs_dirty_to_prefree(struct f2fs_sb_info *sbi); 2949 + int f2fs_disable_cp_again(struct f2fs_sb_info *sbi); 2959 2950 void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi); 2960 2951 int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra); 2961 2952 void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi); ··· 3545 3532 if (test_opt(sbi, LFS) && (rw == WRITE) && 3546 3533 block_unaligned_IO(inode, iocb, iter)) 3547 3534 return true; 3535 + if (is_sbi_flag_set(F2FS_I_SB(inode), SBI_CP_DISABLED)) 3536 + return true; 3537 + 3548 3538 return false; 3549 3539 } 3550 3540
+11 -1
fs/f2fs/file.c
··· 210 210 }; 211 211 unsigned int seq_id = 0; 212 212 213 - if (unlikely(f2fs_readonly(inode->i_sb))) 213 + if (unlikely(f2fs_readonly(inode->i_sb) || 214 + is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 214 215 return 0; 215 216 216 217 trace_f2fs_sync_file_enter(inode); ··· 2158 2157 if (f2fs_readonly(sbi->sb)) 2159 2158 return -EROFS; 2160 2159 2160 + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { 2161 + f2fs_msg(sbi->sb, KERN_INFO, 2162 + "Skipping Checkpoint. Checkpoints currently disabled."); 2163 + return -EINVAL; 2164 + } 2165 + 2161 2166 ret = mnt_want_write_file(filp); 2162 2167 if (ret) 2163 2168 return ret; ··· 2534 2527 2535 2528 if (f2fs_readonly(sbi->sb)) 2536 2529 return -EROFS; 2530 + 2531 + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 2532 + return -EINVAL; 2537 2533 2538 2534 if (copy_from_user(&range, (struct f2fs_flush_device __user *)arg, 2539 2535 sizeof(range)))
+7 -2
fs/f2fs/gc.c
··· 370 370 371 371 if (sec_usage_check(sbi, secno)) 372 372 goto next; 373 + /* Don't touch checkpointed data */ 374 + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) && 375 + get_ckpt_valid_blocks(sbi, segno))) 376 + goto next; 373 377 if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap)) 374 378 goto next; 375 379 ··· 1193 1189 * threshold, we can make them free by checkpoint. Then, we 1194 1190 * secure free segments which doesn't need fggc any more. 1195 1191 */ 1196 - if (prefree_segments(sbi)) { 1192 + if (prefree_segments(sbi) && 1193 + !is_sbi_flag_set(sbi, SBI_CP_DISABLED)) { 1197 1194 ret = f2fs_write_checkpoint(sbi, &cpc); 1198 1195 if (ret) 1199 1196 goto stop; ··· 1246 1241 segno = NULL_SEGNO; 1247 1242 goto gc_more; 1248 1243 } 1249 - if (gc_type == FG_GC) 1244 + if (gc_type == FG_GC && !is_sbi_flag_set(sbi, SBI_CP_DISABLED)) 1250 1245 ret = f2fs_write_checkpoint(sbi, &cpc); 1251 1246 } 1252 1247 stop:
+5 -1
fs/f2fs/inode.c
··· 607 607 if (!is_inode_flag_set(inode, FI_DIRTY_INODE)) 608 608 return 0; 609 609 610 + if (f2fs_is_checkpoint_ready(sbi)) 611 + return -ENOSPC; 612 + 610 613 /* 611 614 * We need to balance fs here to prevent from producing dirty node pages 612 615 * during the urgent cleaning time when runing out of free sections. ··· 691 688 stat_dec_inline_dir(inode); 692 689 stat_dec_inline_inode(inode); 693 690 694 - if (likely(!is_set_ckpt_flags(sbi, CP_ERROR_FLAG))) 691 + if (likely(!is_set_ckpt_flags(sbi, CP_ERROR_FLAG) && 692 + !is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 695 693 f2fs_bug_on(sbi, is_inode_flag_set(inode, FI_DIRTY_INODE)); 696 694 else 697 695 f2fs_inode_synced(inode);
+19
fs/f2fs/namei.c
··· 16 16 17 17 #include "f2fs.h" 18 18 #include "node.h" 19 + #include "segment.h" 19 20 #include "xattr.h" 20 21 #include "acl.h" 21 22 #include <trace/events/f2fs.h> ··· 270 269 271 270 if (unlikely(f2fs_cp_error(sbi))) 272 271 return -EIO; 272 + err = f2fs_is_checkpoint_ready(sbi); 273 + if (err) 274 + return err; 273 275 274 276 err = dquot_initialize(dir); 275 277 if (err) ··· 319 315 320 316 if (unlikely(f2fs_cp_error(sbi))) 321 317 return -EIO; 318 + err = f2fs_is_checkpoint_ready(sbi); 319 + if (err) 320 + return err; 322 321 323 322 err = fscrypt_prepare_link(old_dentry, dir, dentry); 324 323 if (err) ··· 568 561 569 562 if (unlikely(f2fs_cp_error(sbi))) 570 563 return -EIO; 564 + err = f2fs_is_checkpoint_ready(sbi); 565 + if (err) 566 + return err; 571 567 572 568 err = fscrypt_prepare_symlink(dir, symname, len, dir->i_sb->s_blocksize, 573 569 &disk_link); ··· 700 690 701 691 if (unlikely(f2fs_cp_error(sbi))) 702 692 return -EIO; 693 + err = f2fs_is_checkpoint_ready(sbi); 694 + if (err) 695 + return err; 703 696 704 697 err = dquot_initialize(dir); 705 698 if (err) ··· 837 824 838 825 if (unlikely(f2fs_cp_error(sbi))) 839 826 return -EIO; 827 + err = f2fs_is_checkpoint_ready(sbi); 828 + if (err) 829 + return err; 840 830 841 831 if (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && 842 832 (!projid_eq(F2FS_I(new_dir)->i_projid, ··· 1030 1014 1031 1015 if (unlikely(f2fs_cp_error(sbi))) 1032 1016 return -EIO; 1017 + err = f2fs_is_checkpoint_ready(sbi); 1018 + if (err) 1019 + return err; 1033 1020 1034 1021 if ((is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && 1035 1022 !projid_eq(F2FS_I(new_dir)->i_projid,
+94 -4
fs/f2fs/segment.c
··· 176 176 return false; 177 177 if (sbi->gc_mode == GC_URGENT) 178 178 return true; 179 + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 180 + return true; 179 181 180 182 return free_sections(sbi) <= (node_secs + 2 * dent_secs + imeta_secs + 181 183 SM_I(sbi)->min_ssr_sections + reserved_sections(sbi)); ··· 481 479 /* balance_fs_bg is able to be pending */ 482 480 if (need && excess_cached_nats(sbi)) 483 481 f2fs_balance_fs_bg(sbi); 482 + 483 + if (f2fs_is_checkpoint_ready(sbi)) 484 + return; 484 485 485 486 /* 486 487 * We should do GC or end up with checkpoint, if there are so many dirty ··· 801 796 static void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno) 802 797 { 803 798 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); 804 - unsigned short valid_blocks; 799 + unsigned short valid_blocks, ckpt_valid_blocks; 805 800 806 801 if (segno == NULL_SEGNO || IS_CURSEG(sbi, segno)) 807 802 return; ··· 809 804 mutex_lock(&dirty_i->seglist_lock); 810 805 811 806 valid_blocks = get_valid_blocks(sbi, segno, false); 807 + ckpt_valid_blocks = get_ckpt_valid_blocks(sbi, segno); 812 808 813 - if (valid_blocks == 0) { 809 + if (valid_blocks == 0 && (!is_sbi_flag_set(sbi, SBI_CP_DISABLED) || 810 + ckpt_valid_blocks == sbi->blocks_per_seg)) { 814 811 __locate_dirty_segment(sbi, segno, PRE); 815 812 __remove_dirty_segment(sbi, segno, DIRTY); 816 813 } else if (valid_blocks < sbi->blocks_per_seg) { ··· 823 816 } 824 817 825 818 mutex_unlock(&dirty_i->seglist_lock); 819 + } 820 + 821 + /* This moves currently empty dirty blocks to prefree. Must hold seglist_lock */ 822 + void f2fs_dirty_to_prefree(struct f2fs_sb_info *sbi) 823 + { 824 + struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); 825 + unsigned int segno; 826 + 827 + mutex_lock(&dirty_i->seglist_lock); 828 + for_each_set_bit(segno, dirty_i->dirty_segmap[DIRTY], MAIN_SEGS(sbi)) { 829 + if (get_valid_blocks(sbi, segno, false)) 830 + continue; 831 + if (IS_CURSEG(sbi, segno)) 832 + continue; 833 + __locate_dirty_segment(sbi, segno, PRE); 834 + __remove_dirty_segment(sbi, segno, DIRTY); 835 + } 836 + mutex_unlock(&dirty_i->seglist_lock); 837 + } 838 + 839 + int f2fs_disable_cp_again(struct f2fs_sb_info *sbi) 840 + { 841 + struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); 842 + block_t ovp = overprovision_segments(sbi) << sbi->log_blocks_per_seg; 843 + block_t holes[2] = {0, 0}; /* DATA and NODE */ 844 + struct seg_entry *se; 845 + unsigned int segno; 846 + 847 + mutex_lock(&dirty_i->seglist_lock); 848 + for_each_set_bit(segno, dirty_i->dirty_segmap[DIRTY], MAIN_SEGS(sbi)) { 849 + se = get_seg_entry(sbi, segno); 850 + if (IS_NODESEG(se->type)) 851 + holes[NODE] += sbi->blocks_per_seg - se->valid_blocks; 852 + else 853 + holes[DATA] += sbi->blocks_per_seg - se->valid_blocks; 854 + } 855 + mutex_unlock(&dirty_i->seglist_lock); 856 + 857 + if (holes[DATA] > ovp || holes[NODE] > ovp) 858 + return -EAGAIN; 859 + return 0; 860 + } 861 + 862 + /* This is only used by SBI_CP_DISABLED */ 863 + static unsigned int get_free_segment(struct f2fs_sb_info *sbi) 864 + { 865 + struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); 866 + unsigned int segno = 0; 867 + 868 + mutex_lock(&dirty_i->seglist_lock); 869 + for_each_set_bit(segno, dirty_i->dirty_segmap[DIRTY], MAIN_SEGS(sbi)) { 870 + if (get_valid_blocks(sbi, segno, false)) 871 + continue; 872 + if (get_ckpt_valid_blocks(sbi, segno)) 873 + continue; 874 + mutex_unlock(&dirty_i->seglist_lock); 875 + return segno; 876 + } 877 + mutex_unlock(&dirty_i->seglist_lock); 878 + return NULL_SEGNO; 826 879 } 827 880 828 881 static struct discard_cmd *__create_discard_cmd(struct f2fs_sb_info *sbi, ··· 2095 2028 sbi->discard_blks--; 2096 2029 2097 2030 /* don't overwrite by SSR to keep node chain */ 2098 - if (IS_NODESEG(se->type)) { 2031 + if (IS_NODESEG(se->type) && 2032 + !is_sbi_flag_set(sbi, SBI_CP_DISABLED)) { 2099 2033 if (!f2fs_test_and_set_bit(offset, se->ckpt_valid_map)) 2100 2034 se->ckpt_valid_blocks++; 2101 2035 } ··· 2118 2050 f2fs_bug_on(sbi, 1); 2119 2051 se->valid_blocks++; 2120 2052 del = 0; 2053 + } else if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { 2054 + /* 2055 + * If checkpoints are off, we must not reuse data that 2056 + * was used in the previous checkpoint. If it was used 2057 + * before, we must track that to know how much space we 2058 + * really have. 2059 + */ 2060 + if (f2fs_test_bit(offset, se->ckpt_valid_map)) 2061 + sbi->unusable_block_count++; 2121 2062 } 2122 2063 2123 2064 if (f2fs_test_and_clear_bit(offset, se->discard_map)) ··· 2409 2332 if (sbi->segs_per_sec != 1) 2410 2333 return CURSEG_I(sbi, type)->segno; 2411 2334 2335 + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 2336 + return 0; 2337 + 2412 2338 if (test_opt(sbi, NOHEAP) && 2413 2339 (type == CURSEG_HOT_DATA || IS_NODESEG(type))) 2414 2340 return 0; ··· 2556 2476 return 1; 2557 2477 } 2558 2478 } 2479 + 2480 + /* find valid_blocks=0 in dirty list */ 2481 + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { 2482 + segno = get_free_segment(sbi); 2483 + if (segno != NULL_SEGNO) { 2484 + curseg->next_segno = segno; 2485 + return 1; 2486 + } 2487 + } 2559 2488 return 0; 2560 2489 } 2561 2490 ··· 2582 2493 else if (!is_set_ckpt_flags(sbi, CP_CRC_RECOVERY_FLAG) && 2583 2494 type == CURSEG_WARM_NODE) 2584 2495 new_curseg(sbi, type, false); 2585 - else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type)) 2496 + else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type) && 2497 + likely(!is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 2586 2498 new_curseg(sbi, type, false); 2587 2499 else if (f2fs_need_SSR(sbi) && get_ssr_segment(sbi, type)) 2588 2500 change_curseg(sbi, type);
+15
fs/f2fs/segment.h
··· 339 339 return get_seg_entry(sbi, segno)->valid_blocks; 340 340 } 341 341 342 + static inline unsigned int get_ckpt_valid_blocks(struct f2fs_sb_info *sbi, 343 + unsigned int segno) 344 + { 345 + return get_seg_entry(sbi, segno)->ckpt_valid_blocks; 346 + } 347 + 342 348 static inline void seg_info_from_raw_sit(struct seg_entry *se, 343 349 struct f2fs_sit_entry *rs) 344 350 { ··· 580 574 return (free_sections(sbi) + freed) <= 581 575 (node_secs + 2 * dent_secs + imeta_secs + 582 576 reserved_sections(sbi) + needed); 577 + } 578 + 579 + static inline int f2fs_is_checkpoint_ready(struct f2fs_sb_info *sbi) 580 + { 581 + if (likely(!is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 582 + return 0; 583 + if (likely(!has_not_enough_free_secs(sbi, 0, 0))) 584 + return 0; 585 + return -ENOSPC; 583 586 } 584 587 585 588 static inline bool excess_prefree_segs(struct f2fs_sb_info *sbi)
+123 -3
fs/f2fs/super.c
··· 136 136 Opt_alloc, 137 137 Opt_fsync, 138 138 Opt_test_dummy_encryption, 139 + Opt_checkpoint, 139 140 Opt_err, 140 141 }; 141 142 ··· 195 194 {Opt_alloc, "alloc_mode=%s"}, 196 195 {Opt_fsync, "fsync_mode=%s"}, 197 196 {Opt_test_dummy_encryption, "test_dummy_encryption"}, 197 + {Opt_checkpoint, "checkpoint=%s"}, 198 198 {Opt_err, NULL}, 199 199 }; 200 200 ··· 771 769 "Test dummy encryption mount option ignored"); 772 770 #endif 773 771 break; 772 + case Opt_checkpoint: 773 + name = match_strdup(&args[0]); 774 + if (!name) 775 + return -ENOMEM; 776 + 777 + if (strlen(name) == 6 && 778 + !strncmp(name, "enable", 6)) { 779 + clear_opt(sbi, DISABLE_CHECKPOINT); 780 + } else if (strlen(name) == 7 && 781 + !strncmp(name, "disable", 7)) { 782 + set_opt(sbi, DISABLE_CHECKPOINT); 783 + } else { 784 + kfree(name); 785 + return -EINVAL; 786 + } 787 + kfree(name); 788 + break; 774 789 default: 775 790 f2fs_msg(sb, KERN_ERR, 776 791 "Unrecognized mount option \"%s\" or missing value", ··· 844 825 "inline xattr size is out of range"); 845 826 return -EINVAL; 846 827 } 828 + } 829 + 830 + if (test_opt(sbi, DISABLE_CHECKPOINT) && test_opt(sbi, LFS)) { 831 + f2fs_msg(sb, KERN_ERR, 832 + "LFS not compatible with checkpoint=disable\n"); 833 + return -EINVAL; 847 834 } 848 835 849 836 /* Not pass down write hints if the number of active logs is lesser ··· 1039 1014 * But, the previous checkpoint was not done by umount, it needs to do 1040 1015 * clean checkpoint again. 1041 1016 */ 1042 - if (is_sbi_flag_set(sbi, SBI_IS_DIRTY) || 1043 - !is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { 1017 + if ((is_sbi_flag_set(sbi, SBI_IS_DIRTY) || 1018 + !is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG))) { 1044 1019 struct cp_control cpc = { 1045 1020 .reason = CP_UMOUNT, 1046 1021 }; ··· 1111 1086 int err = 0; 1112 1087 1113 1088 if (unlikely(f2fs_cp_error(sbi))) 1089 + return 0; 1090 + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 1114 1091 return 0; 1115 1092 1116 1093 trace_f2fs_sync_fs(sb, sync); ··· 1213 1186 buf->f_blocks = total_count - start_count; 1214 1187 buf->f_bfree = user_block_count - valid_user_blocks(sbi) - 1215 1188 sbi->current_reserved_blocks; 1189 + if (unlikely(buf->f_bfree <= sbi->unusable_block_count)) 1190 + buf->f_bfree = 0; 1191 + else 1192 + buf->f_bfree -= sbi->unusable_block_count; 1193 + 1216 1194 if (buf->f_bfree > F2FS_OPTION(sbi).root_reserved_blocks) 1217 1195 buf->f_bavail = buf->f_bfree - 1218 1196 F2FS_OPTION(sbi).root_reserved_blocks; ··· 1397 1365 else if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_REUSE) 1398 1366 seq_printf(seq, ",alloc_mode=%s", "reuse"); 1399 1367 1368 + if (test_opt(sbi, DISABLE_CHECKPOINT)) 1369 + seq_puts(seq, ",checkpoint=disable"); 1370 + 1400 1371 if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_POSIX) 1401 1372 seq_printf(seq, ",fsync_mode=%s", "posix"); 1402 1373 else if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) ··· 1427 1392 set_opt(sbi, INLINE_DENTRY); 1428 1393 set_opt(sbi, EXTENT_CACHE); 1429 1394 set_opt(sbi, NOHEAP); 1395 + clear_opt(sbi, DISABLE_CHECKPOINT); 1430 1396 sbi->sb->s_flags |= SB_LAZYTIME; 1431 1397 set_opt(sbi, FLUSH_MERGE); 1432 1398 set_opt(sbi, DISCARD); ··· 1449 1413 #ifdef CONFIG_QUOTA 1450 1414 static int f2fs_enable_quotas(struct super_block *sb); 1451 1415 #endif 1416 + 1417 + static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) 1418 + { 1419 + struct cp_control cpc; 1420 + int err; 1421 + 1422 + sbi->sb->s_flags |= SB_ACTIVE; 1423 + 1424 + mutex_lock(&sbi->gc_mutex); 1425 + f2fs_update_time(sbi, DISABLE_TIME); 1426 + 1427 + while (!f2fs_time_over(sbi, DISABLE_TIME)) { 1428 + err = f2fs_gc(sbi, true, false, NULL_SEGNO); 1429 + if (err == -ENODATA) 1430 + break; 1431 + if (err && err != -EAGAIN) { 1432 + mutex_unlock(&sbi->gc_mutex); 1433 + return err; 1434 + } 1435 + } 1436 + mutex_unlock(&sbi->gc_mutex); 1437 + 1438 + err = sync_filesystem(sbi->sb); 1439 + if (err) 1440 + return err; 1441 + 1442 + if (f2fs_disable_cp_again(sbi)) 1443 + return -EAGAIN; 1444 + 1445 + mutex_lock(&sbi->gc_mutex); 1446 + cpc.reason = CP_PAUSE; 1447 + set_sbi_flag(sbi, SBI_CP_DISABLED); 1448 + f2fs_write_checkpoint(sbi, &cpc); 1449 + 1450 + sbi->unusable_block_count = 0; 1451 + mutex_unlock(&sbi->gc_mutex); 1452 + return 0; 1453 + } 1454 + 1455 + static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) 1456 + { 1457 + mutex_lock(&sbi->gc_mutex); 1458 + f2fs_dirty_to_prefree(sbi); 1459 + 1460 + clear_sbi_flag(sbi, SBI_CP_DISABLED); 1461 + set_sbi_flag(sbi, SBI_IS_DIRTY); 1462 + mutex_unlock(&sbi->gc_mutex); 1463 + 1464 + f2fs_sync_fs(sbi->sb, 1); 1465 + } 1466 + 1452 1467 static int f2fs_remount(struct super_block *sb, int *flags, char *data) 1453 1468 { 1454 1469 struct f2fs_sb_info *sbi = F2FS_SB(sb); ··· 1509 1422 bool need_restart_gc = false; 1510 1423 bool need_stop_gc = false; 1511 1424 bool no_extent_cache = !test_opt(sbi, EXTENT_CACHE); 1425 + bool disable_checkpoint = test_opt(sbi, DISABLE_CHECKPOINT); 1426 + bool checkpoint_changed; 1512 1427 #ifdef CONFIG_QUOTA 1513 1428 int i, j; 1514 1429 #endif ··· 1555 1466 err = parse_options(sb, data); 1556 1467 if (err) 1557 1468 goto restore_opts; 1469 + checkpoint_changed = 1470 + disable_checkpoint != test_opt(sbi, DISABLE_CHECKPOINT); 1558 1471 1559 1472 /* 1560 1473 * Previous and new state of filesystem is RO, ··· 1570 1479 err = dquot_suspend(sb, -1); 1571 1480 if (err < 0) 1572 1481 goto restore_opts; 1573 - } else if (f2fs_readonly(sb) && !(*flags & MS_RDONLY)) { 1482 + } else if (f2fs_readonly(sb) && !(*flags & SB_RDONLY)) { 1574 1483 /* dquot_resume needs RW */ 1575 1484 sb->s_flags &= ~SB_RDONLY; 1576 1485 if (sb_any_quota_suspended(sb)) { ··· 1587 1496 err = -EINVAL; 1588 1497 f2fs_msg(sbi->sb, KERN_WARNING, 1589 1498 "switch extent_cache option is not allowed"); 1499 + goto restore_opts; 1500 + } 1501 + 1502 + if ((*flags & SB_RDONLY) && test_opt(sbi, DISABLE_CHECKPOINT)) { 1503 + err = -EINVAL; 1504 + f2fs_msg(sbi->sb, KERN_WARNING, 1505 + "disabling checkpoint not compatible with read-only"); 1590 1506 goto restore_opts; 1591 1507 } 1592 1508 ··· 1623 1525 set_sbi_flag(sbi, SBI_IS_CLOSE); 1624 1526 f2fs_sync_fs(sb, 1); 1625 1527 clear_sbi_flag(sbi, SBI_IS_CLOSE); 1528 + } 1529 + 1530 + if (checkpoint_changed) { 1531 + if (test_opt(sbi, DISABLE_CHECKPOINT)) { 1532 + err = f2fs_disable_checkpoint(sbi); 1533 + if (err) 1534 + goto restore_gc; 1535 + } else { 1536 + f2fs_enable_checkpoint(sbi); 1537 + } 1626 1538 } 1627 1539 1628 1540 /* ··· 2593 2485 sbi->interval_time[REQ_TIME] = DEF_IDLE_INTERVAL; 2594 2486 sbi->interval_time[DISCARD_TIME] = DEF_IDLE_INTERVAL; 2595 2487 sbi->interval_time[GC_TIME] = DEF_IDLE_INTERVAL; 2488 + sbi->interval_time[DISABLE_TIME] = DEF_DISABLE_INTERVAL; 2596 2489 clear_sbi_flag(sbi, SBI_NEED_FSCK); 2597 2490 2598 2491 for (i = 0; i < NR_COUNT_TYPE; i++) ··· 3202 3093 if (err) 3203 3094 goto free_meta; 3204 3095 3096 + if (unlikely(is_set_ckpt_flags(sbi, CP_DISABLED_FLAG))) 3097 + goto skip_recovery; 3098 + 3205 3099 /* recover fsynced data */ 3206 3100 if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) { 3207 3101 /* ··· 3243 3131 skip_recovery: 3244 3132 /* f2fs_recover_fsync_data() cleared this already */ 3245 3133 clear_sbi_flag(sbi, SBI_POR_DOING); 3134 + 3135 + if (test_opt(sbi, DISABLE_CHECKPOINT)) { 3136 + err = f2fs_disable_checkpoint(sbi); 3137 + if (err) 3138 + goto free_meta; 3139 + } else if (is_set_ckpt_flags(sbi, CP_DISABLED_FLAG)) { 3140 + f2fs_enable_checkpoint(sbi); 3141 + } 3246 3142 3247 3143 /* 3248 3144 * If filesystem is not mounted as read-only then
+1
include/linux/f2fs_fs.h
··· 116 116 /* 117 117 * For checkpoint 118 118 */ 119 + #define CP_DISABLED_FLAG 0x00001000 119 120 #define CP_LARGE_NAT_BITMAP_FLAG 0x00000400 120 121 #define CP_NOCRC_RECOVERY_FLAG 0x00000200 121 122 #define CP_TRIMMED_FLAG 0x00000100