| .. | .. |
|---|
| 24 | 24 | #include <linux/sysfs.h> |
|---|
| 25 | 25 | #include <linux/quota.h> |
|---|
| 26 | 26 | #include <linux/unicode.h> |
|---|
| 27 | +#include <linux/part_stat.h> |
|---|
| 28 | +#include <linux/zstd.h> |
|---|
| 29 | +#include <linux/lz4.h> |
|---|
| 27 | 30 | |
|---|
| 28 | 31 | #include "f2fs.h" |
|---|
| 29 | 32 | #include "node.h" |
|---|
| 30 | 33 | #include "segment.h" |
|---|
| 31 | 34 | #include "xattr.h" |
|---|
| 32 | 35 | #include "gc.h" |
|---|
| 33 | | -#include "trace.h" |
|---|
| 34 | 36 | |
|---|
| 35 | 37 | #define CREATE_TRACE_POINTS |
|---|
| 36 | 38 | #include <trace/events/f2fs.h> |
|---|
| .. | .. |
|---|
| 44 | 46 | [FAULT_KVMALLOC] = "kvmalloc", |
|---|
| 45 | 47 | [FAULT_PAGE_ALLOC] = "page alloc", |
|---|
| 46 | 48 | [FAULT_PAGE_GET] = "page get", |
|---|
| 47 | | - [FAULT_ALLOC_BIO] = "alloc bio", |
|---|
| 48 | 49 | [FAULT_ALLOC_NID] = "alloc nid", |
|---|
| 49 | 50 | [FAULT_ORPHAN] = "orphan", |
|---|
| 50 | 51 | [FAULT_BLOCK] = "no more block", |
|---|
| .. | .. |
|---|
| 142 | 143 | Opt_checkpoint_disable_cap, |
|---|
| 143 | 144 | Opt_checkpoint_disable_cap_perc, |
|---|
| 144 | 145 | Opt_checkpoint_enable, |
|---|
| 146 | + Opt_checkpoint_merge, |
|---|
| 147 | + Opt_nocheckpoint_merge, |
|---|
| 145 | 148 | Opt_compress_algorithm, |
|---|
| 146 | 149 | Opt_compress_log_size, |
|---|
| 147 | 150 | Opt_compress_extension, |
|---|
| 151 | + Opt_compress_chksum, |
|---|
| 152 | + Opt_compress_mode, |
|---|
| 153 | + Opt_compress_cache, |
|---|
| 154 | + Opt_atgc, |
|---|
| 155 | + Opt_gc_merge, |
|---|
| 156 | + Opt_nogc_merge, |
|---|
| 157 | + Opt_memory_mode, |
|---|
| 158 | + Opt_age_extent_cache, |
|---|
| 148 | 159 | Opt_err, |
|---|
| 149 | 160 | }; |
|---|
| 150 | 161 | |
|---|
| .. | .. |
|---|
| 209 | 220 | {Opt_checkpoint_disable_cap, "checkpoint=disable:%u"}, |
|---|
| 210 | 221 | {Opt_checkpoint_disable_cap_perc, "checkpoint=disable:%u%%"}, |
|---|
| 211 | 222 | {Opt_checkpoint_enable, "checkpoint=enable"}, |
|---|
| 223 | + {Opt_checkpoint_merge, "checkpoint_merge"}, |
|---|
| 224 | + {Opt_nocheckpoint_merge, "nocheckpoint_merge"}, |
|---|
| 212 | 225 | {Opt_compress_algorithm, "compress_algorithm=%s"}, |
|---|
| 213 | 226 | {Opt_compress_log_size, "compress_log_size=%u"}, |
|---|
| 214 | 227 | {Opt_compress_extension, "compress_extension=%s"}, |
|---|
| 228 | + {Opt_compress_chksum, "compress_chksum"}, |
|---|
| 229 | + {Opt_compress_mode, "compress_mode=%s"}, |
|---|
| 230 | + {Opt_compress_cache, "compress_cache"}, |
|---|
| 231 | + {Opt_atgc, "atgc"}, |
|---|
| 232 | + {Opt_gc_merge, "gc_merge"}, |
|---|
| 233 | + {Opt_nogc_merge, "nogc_merge"}, |
|---|
| 234 | + {Opt_memory_mode, "memory=%s"}, |
|---|
| 235 | + {Opt_age_extent_cache, "age_extent_cache"}, |
|---|
| 215 | 236 | {Opt_err, NULL}, |
|---|
| 216 | 237 | }; |
|---|
| 217 | 238 | |
|---|
| .. | .. |
|---|
| 260 | 281 | |
|---|
| 261 | 282 | return 0; |
|---|
| 262 | 283 | } |
|---|
| 284 | + |
|---|
| 285 | +struct kmem_cache *f2fs_cf_name_slab; |
|---|
| 286 | +static int __init f2fs_create_casefold_cache(void) |
|---|
| 287 | +{ |
|---|
| 288 | + f2fs_cf_name_slab = f2fs_kmem_cache_create("f2fs_casefolded_name", |
|---|
| 289 | + F2FS_NAME_LEN); |
|---|
| 290 | + if (!f2fs_cf_name_slab) |
|---|
| 291 | + return -ENOMEM; |
|---|
| 292 | + return 0; |
|---|
| 293 | +} |
|---|
| 294 | + |
|---|
| 295 | +static void f2fs_destroy_casefold_cache(void) |
|---|
| 296 | +{ |
|---|
| 297 | + kmem_cache_destroy(f2fs_cf_name_slab); |
|---|
| 298 | +} |
|---|
| 299 | +#else |
|---|
| 300 | +static int __init f2fs_create_casefold_cache(void) { return 0; } |
|---|
| 301 | +static void f2fs_destroy_casefold_cache(void) { } |
|---|
| 263 | 302 | #endif |
|---|
| 264 | 303 | |
|---|
| 265 | 304 | static inline void limit_reserve_root(struct f2fs_sb_info *sbi) |
|---|
| 266 | 305 | { |
|---|
| 267 | | - block_t limit = min((sbi->user_block_count << 1) / 1000, |
|---|
| 306 | + block_t limit = min((sbi->user_block_count >> 3), |
|---|
| 268 | 307 | sbi->user_block_count - sbi->reserved_blocks); |
|---|
| 269 | 308 | |
|---|
| 270 | | - /* limit is 0.2%, and cannot be too small */ |
|---|
| 271 | | - limit = max(limit, MIN_ROOT_RESERVED_BLOCKS); |
|---|
| 309 | + /* limit is 12.5% */ |
|---|
| 272 | 310 | if (test_opt(sbi, RESERVE_ROOT) && |
|---|
| 273 | | - F2FS_OPTION(sbi).root_reserved_blocks > limit) { |
|---|
| 311 | + F2FS_OPTION(sbi).root_reserved_blocks > limit && |
|---|
| 312 | + F2FS_OPTION(sbi).root_reserved_blocks > MIN_ROOT_RESERVED_BLOCKS) { |
|---|
| 274 | 313 | F2FS_OPTION(sbi).root_reserved_blocks = limit; |
|---|
| 275 | 314 | f2fs_info(sbi, "Reduce reserved blocks for root = %u", |
|---|
| 276 | 315 | F2FS_OPTION(sbi).root_reserved_blocks); |
|---|
| .. | .. |
|---|
| 285 | 324 | F2FS_OPTION(sbi).s_resuid), |
|---|
| 286 | 325 | from_kgid_munged(&init_user_ns, |
|---|
| 287 | 326 | F2FS_OPTION(sbi).s_resgid)); |
|---|
| 327 | +} |
|---|
| 328 | + |
|---|
| 329 | +static inline int adjust_reserved_segment(struct f2fs_sb_info *sbi) |
|---|
| 330 | +{ |
|---|
| 331 | + unsigned int sec_blks = sbi->blocks_per_seg * sbi->segs_per_sec; |
|---|
| 332 | + unsigned int avg_vblocks; |
|---|
| 333 | + unsigned int wanted_reserved_segments; |
|---|
| 334 | + block_t avail_user_block_count; |
|---|
| 335 | + |
|---|
| 336 | + if (!F2FS_IO_ALIGNED(sbi)) |
|---|
| 337 | + return 0; |
|---|
| 338 | + |
|---|
| 339 | + /* average valid block count in section in worst case */ |
|---|
| 340 | + avg_vblocks = sec_blks / F2FS_IO_SIZE(sbi); |
|---|
| 341 | + |
|---|
| 342 | + /* |
|---|
| 343 | + * we need enough free space when migrating one section in worst case |
|---|
| 344 | + */ |
|---|
| 345 | + wanted_reserved_segments = (F2FS_IO_SIZE(sbi) / avg_vblocks) * |
|---|
| 346 | + reserved_segments(sbi); |
|---|
| 347 | + wanted_reserved_segments -= reserved_segments(sbi); |
|---|
| 348 | + |
|---|
| 349 | + avail_user_block_count = sbi->user_block_count - |
|---|
| 350 | + sbi->current_reserved_blocks - |
|---|
| 351 | + F2FS_OPTION(sbi).root_reserved_blocks; |
|---|
| 352 | + |
|---|
| 353 | + if (wanted_reserved_segments * sbi->blocks_per_seg > |
|---|
| 354 | + avail_user_block_count) { |
|---|
| 355 | + f2fs_err(sbi, "IO align feature can't grab additional reserved segment: %u, available segments: %u", |
|---|
| 356 | + wanted_reserved_segments, |
|---|
| 357 | + avail_user_block_count >> sbi->log_blocks_per_seg); |
|---|
| 358 | + return -ENOSPC; |
|---|
| 359 | + } |
|---|
| 360 | + |
|---|
| 361 | + SM_I(sbi)->additional_reserved_segments = wanted_reserved_segments; |
|---|
| 362 | + |
|---|
| 363 | + f2fs_info(sbi, "IO align feature needs additional reserved segment: %u", |
|---|
| 364 | + wanted_reserved_segments); |
|---|
| 365 | + |
|---|
| 366 | + return 0; |
|---|
| 288 | 367 | } |
|---|
| 289 | 368 | |
|---|
| 290 | 369 | static inline void adjust_unusable_cap_perc(struct f2fs_sb_info *sbi) |
|---|
| .. | .. |
|---|
| 350 | 429 | set_opt(sbi, QUOTA); |
|---|
| 351 | 430 | return 0; |
|---|
| 352 | 431 | errout: |
|---|
| 353 | | - kvfree(qname); |
|---|
| 432 | + kfree(qname); |
|---|
| 354 | 433 | return ret; |
|---|
| 355 | 434 | } |
|---|
| 356 | 435 | |
|---|
| .. | .. |
|---|
| 362 | 441 | f2fs_err(sbi, "Cannot change journaled quota options when quota turned on"); |
|---|
| 363 | 442 | return -EINVAL; |
|---|
| 364 | 443 | } |
|---|
| 365 | | - kvfree(F2FS_OPTION(sbi).s_qf_names[qtype]); |
|---|
| 444 | + kfree(F2FS_OPTION(sbi).s_qf_names[qtype]); |
|---|
| 366 | 445 | F2FS_OPTION(sbi).s_qf_names[qtype] = NULL; |
|---|
| 367 | 446 | return 0; |
|---|
| 368 | 447 | } |
|---|
| .. | .. |
|---|
| 433 | 512 | * needed to allow it to be set or changed during remount. We do allow |
|---|
| 434 | 513 | * it to be specified during remount, but only if there is no change. |
|---|
| 435 | 514 | */ |
|---|
| 436 | | - if (is_remount && !F2FS_OPTION(sbi).dummy_enc_ctx.ctx) { |
|---|
| 515 | + if (is_remount && !F2FS_OPTION(sbi).dummy_enc_policy.policy) { |
|---|
| 437 | 516 | f2fs_warn(sbi, "Can't set test_dummy_encryption on remount"); |
|---|
| 438 | 517 | return -EINVAL; |
|---|
| 439 | 518 | } |
|---|
| 440 | 519 | err = fscrypt_set_test_dummy_encryption( |
|---|
| 441 | | - sb, arg, &F2FS_OPTION(sbi).dummy_enc_ctx); |
|---|
| 520 | + sb, arg->from, &F2FS_OPTION(sbi).dummy_enc_policy); |
|---|
| 442 | 521 | if (err) { |
|---|
| 443 | 522 | if (err == -EEXIST) |
|---|
| 444 | 523 | f2fs_warn(sbi, |
|---|
| .. | .. |
|---|
| 458 | 537 | return 0; |
|---|
| 459 | 538 | } |
|---|
| 460 | 539 | |
|---|
| 540 | +#ifdef CONFIG_F2FS_FS_COMPRESSION |
|---|
| 541 | +#ifdef CONFIG_F2FS_FS_LZ4 |
|---|
| 542 | +static int f2fs_set_lz4hc_level(struct f2fs_sb_info *sbi, const char *str) |
|---|
| 543 | +{ |
|---|
| 544 | +#ifdef CONFIG_F2FS_FS_LZ4HC |
|---|
| 545 | + unsigned int level; |
|---|
| 546 | +#endif |
|---|
| 547 | + |
|---|
| 548 | + if (strlen(str) == 3) { |
|---|
| 549 | + F2FS_OPTION(sbi).compress_level = 0; |
|---|
| 550 | + return 0; |
|---|
| 551 | + } |
|---|
| 552 | + |
|---|
| 553 | +#ifdef CONFIG_F2FS_FS_LZ4HC |
|---|
| 554 | + str += 3; |
|---|
| 555 | + |
|---|
| 556 | + if (str[0] != ':') { |
|---|
| 557 | + f2fs_info(sbi, "wrong format, e.g. <alg_name>:<compr_level>"); |
|---|
| 558 | + return -EINVAL; |
|---|
| 559 | + } |
|---|
| 560 | + if (kstrtouint(str + 1, 10, &level)) |
|---|
| 561 | + return -EINVAL; |
|---|
| 562 | + |
|---|
| 563 | + if (level < LZ4HC_MIN_CLEVEL || level > LZ4HC_MAX_CLEVEL) { |
|---|
| 564 | + f2fs_info(sbi, "invalid lz4hc compress level: %d", level); |
|---|
| 565 | + return -EINVAL; |
|---|
| 566 | + } |
|---|
| 567 | + |
|---|
| 568 | + F2FS_OPTION(sbi).compress_level = level; |
|---|
| 569 | + return 0; |
|---|
| 570 | +#else |
|---|
| 571 | + f2fs_info(sbi, "kernel doesn't support lz4hc compression"); |
|---|
| 572 | + return -EINVAL; |
|---|
| 573 | +#endif |
|---|
| 574 | +} |
|---|
| 575 | +#endif |
|---|
| 576 | + |
|---|
| 577 | +#ifdef CONFIG_F2FS_FS_ZSTD |
|---|
| 578 | +static int f2fs_set_zstd_level(struct f2fs_sb_info *sbi, const char *str) |
|---|
| 579 | +{ |
|---|
| 580 | + unsigned int level; |
|---|
| 581 | + int len = 4; |
|---|
| 582 | + |
|---|
| 583 | + if (strlen(str) == len) { |
|---|
| 584 | + F2FS_OPTION(sbi).compress_level = 0; |
|---|
| 585 | + return 0; |
|---|
| 586 | + } |
|---|
| 587 | + |
|---|
| 588 | + str += len; |
|---|
| 589 | + |
|---|
| 590 | + if (str[0] != ':') { |
|---|
| 591 | + f2fs_info(sbi, "wrong format, e.g. <alg_name>:<compr_level>"); |
|---|
| 592 | + return -EINVAL; |
|---|
| 593 | + } |
|---|
| 594 | + if (kstrtouint(str + 1, 10, &level)) |
|---|
| 595 | + return -EINVAL; |
|---|
| 596 | + |
|---|
| 597 | + if (!level || level > ZSTD_maxCLevel()) { |
|---|
| 598 | + f2fs_info(sbi, "invalid zstd compress level: %d", level); |
|---|
| 599 | + return -EINVAL; |
|---|
| 600 | + } |
|---|
| 601 | + |
|---|
| 602 | + F2FS_OPTION(sbi).compress_level = level; |
|---|
| 603 | + return 0; |
|---|
| 604 | +} |
|---|
| 605 | +#endif |
|---|
| 606 | +#endif |
|---|
| 607 | + |
|---|
| 461 | 608 | static int parse_options(struct super_block *sb, char *options, bool is_remount) |
|---|
| 462 | 609 | { |
|---|
| 463 | 610 | struct f2fs_sb_info *sbi = F2FS_SB(sb); |
|---|
| 464 | 611 | substring_t args[MAX_OPT_ARGS]; |
|---|
| 612 | +#ifdef CONFIG_F2FS_FS_COMPRESSION |
|---|
| 465 | 613 | unsigned char (*ext)[F2FS_EXTENSION_LEN]; |
|---|
| 614 | + int ext_cnt; |
|---|
| 615 | +#endif |
|---|
| 466 | 616 | char *p, *name; |
|---|
| 467 | | - int arg = 0, ext_cnt; |
|---|
| 617 | + int arg = 0; |
|---|
| 468 | 618 | kuid_t uid; |
|---|
| 469 | 619 | kgid_t gid; |
|---|
| 470 | 620 | int ret; |
|---|
| 471 | 621 | |
|---|
| 472 | 622 | if (!options) |
|---|
| 473 | | - return 0; |
|---|
| 623 | + goto default_check; |
|---|
| 474 | 624 | |
|---|
| 475 | 625 | while ((p = strsep(&options, ",")) != NULL) { |
|---|
| 476 | 626 | int token; |
|---|
| 627 | + |
|---|
| 477 | 628 | if (!*p) |
|---|
| 478 | 629 | continue; |
|---|
| 479 | 630 | /* |
|---|
| .. | .. |
|---|
| 496 | 647 | } else if (!strcmp(name, "sync")) { |
|---|
| 497 | 648 | F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_SYNC; |
|---|
| 498 | 649 | } else { |
|---|
| 499 | | - kvfree(name); |
|---|
| 650 | + kfree(name); |
|---|
| 500 | 651 | return -EINVAL; |
|---|
| 501 | 652 | } |
|---|
| 502 | | - kvfree(name); |
|---|
| 653 | + kfree(name); |
|---|
| 503 | 654 | break; |
|---|
| 504 | 655 | case Opt_disable_roll_forward: |
|---|
| 505 | 656 | set_opt(sbi, DISABLE_ROLL_FORWARD); |
|---|
| .. | .. |
|---|
| 577 | 728 | case Opt_active_logs: |
|---|
| 578 | 729 | if (args->from && match_int(args, &arg)) |
|---|
| 579 | 730 | return -EINVAL; |
|---|
| 580 | | - if (arg != 2 && arg != 4 && arg != NR_CURSEG_TYPE) |
|---|
| 731 | + if (arg != 2 && arg != 4 && |
|---|
| 732 | + arg != NR_CURSEG_PERSIST_TYPE) |
|---|
| 581 | 733 | return -EINVAL; |
|---|
| 582 | 734 | F2FS_OPTION(sbi).active_logs = arg; |
|---|
| 583 | 735 | break; |
|---|
| .. | .. |
|---|
| 606 | 758 | set_opt(sbi, FASTBOOT); |
|---|
| 607 | 759 | break; |
|---|
| 608 | 760 | case Opt_extent_cache: |
|---|
| 609 | | - set_opt(sbi, EXTENT_CACHE); |
|---|
| 761 | + set_opt(sbi, READ_EXTENT_CACHE); |
|---|
| 610 | 762 | break; |
|---|
| 611 | 763 | case Opt_noextent_cache: |
|---|
| 612 | | - clear_opt(sbi, EXTENT_CACHE); |
|---|
| 764 | + clear_opt(sbi, READ_EXTENT_CACHE); |
|---|
| 613 | 765 | break; |
|---|
| 614 | 766 | case Opt_noinline_data: |
|---|
| 615 | 767 | clear_opt(sbi, INLINE_DATA); |
|---|
| .. | .. |
|---|
| 656 | 808 | if (!strcmp(name, "adaptive")) { |
|---|
| 657 | 809 | if (f2fs_sb_has_blkzoned(sbi)) { |
|---|
| 658 | 810 | f2fs_warn(sbi, "adaptive mode is not allowed with zoned block device feature"); |
|---|
| 659 | | - kvfree(name); |
|---|
| 811 | + kfree(name); |
|---|
| 660 | 812 | return -EINVAL; |
|---|
| 661 | 813 | } |
|---|
| 662 | 814 | F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE; |
|---|
| 663 | 815 | } else if (!strcmp(name, "lfs")) { |
|---|
| 664 | 816 | F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS; |
|---|
| 665 | 817 | } else { |
|---|
| 666 | | - kvfree(name); |
|---|
| 818 | + kfree(name); |
|---|
| 667 | 819 | return -EINVAL; |
|---|
| 668 | 820 | } |
|---|
| 669 | | - kvfree(name); |
|---|
| 821 | + kfree(name); |
|---|
| 670 | 822 | break; |
|---|
| 671 | 823 | case Opt_io_size_bits: |
|---|
| 672 | 824 | if (args->from && match_int(args, &arg)) |
|---|
| .. | .. |
|---|
| 792 | 944 | } else if (!strcmp(name, "fs-based")) { |
|---|
| 793 | 945 | F2FS_OPTION(sbi).whint_mode = WHINT_MODE_FS; |
|---|
| 794 | 946 | } else { |
|---|
| 795 | | - kvfree(name); |
|---|
| 947 | + kfree(name); |
|---|
| 796 | 948 | return -EINVAL; |
|---|
| 797 | 949 | } |
|---|
| 798 | | - kvfree(name); |
|---|
| 950 | + kfree(name); |
|---|
| 799 | 951 | break; |
|---|
| 800 | 952 | case Opt_alloc: |
|---|
| 801 | 953 | name = match_strdup(&args[0]); |
|---|
| .. | .. |
|---|
| 807 | 959 | } else if (!strcmp(name, "reuse")) { |
|---|
| 808 | 960 | F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_REUSE; |
|---|
| 809 | 961 | } else { |
|---|
| 810 | | - kvfree(name); |
|---|
| 962 | + kfree(name); |
|---|
| 811 | 963 | return -EINVAL; |
|---|
| 812 | 964 | } |
|---|
| 813 | | - kvfree(name); |
|---|
| 965 | + kfree(name); |
|---|
| 814 | 966 | break; |
|---|
| 815 | 967 | case Opt_fsync: |
|---|
| 816 | 968 | name = match_strdup(&args[0]); |
|---|
| .. | .. |
|---|
| 824 | 976 | F2FS_OPTION(sbi).fsync_mode = |
|---|
| 825 | 977 | FSYNC_MODE_NOBARRIER; |
|---|
| 826 | 978 | } else { |
|---|
| 827 | | - kvfree(name); |
|---|
| 979 | + kfree(name); |
|---|
| 828 | 980 | return -EINVAL; |
|---|
| 829 | 981 | } |
|---|
| 830 | | - kvfree(name); |
|---|
| 982 | + kfree(name); |
|---|
| 831 | 983 | break; |
|---|
| 832 | 984 | case Opt_test_dummy_encryption: |
|---|
| 833 | 985 | ret = f2fs_set_test_dummy_encryption(sb, p, &args[0], |
|---|
| .. | .. |
|---|
| 837 | 989 | break; |
|---|
| 838 | 990 | case Opt_inlinecrypt: |
|---|
| 839 | 991 | #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT |
|---|
| 840 | | - F2FS_OPTION(sbi).inlinecrypt = true; |
|---|
| 992 | + sb->s_flags |= SB_INLINECRYPT; |
|---|
| 841 | 993 | #else |
|---|
| 842 | 994 | f2fs_info(sbi, "inline encryption not supported"); |
|---|
| 843 | 995 | #endif |
|---|
| .. | .. |
|---|
| 862 | 1014 | case Opt_checkpoint_enable: |
|---|
| 863 | 1015 | clear_opt(sbi, DISABLE_CHECKPOINT); |
|---|
| 864 | 1016 | break; |
|---|
| 1017 | + case Opt_checkpoint_merge: |
|---|
| 1018 | + set_opt(sbi, MERGE_CHECKPOINT); |
|---|
| 1019 | + break; |
|---|
| 1020 | + case Opt_nocheckpoint_merge: |
|---|
| 1021 | + clear_opt(sbi, MERGE_CHECKPOINT); |
|---|
| 1022 | + break; |
|---|
| 1023 | +#ifdef CONFIG_F2FS_FS_COMPRESSION |
|---|
| 865 | 1024 | case Opt_compress_algorithm: |
|---|
| 866 | 1025 | if (!f2fs_sb_has_compression(sbi)) { |
|---|
| 867 | | - f2fs_err(sbi, "Compression feature if off"); |
|---|
| 868 | | - return -EINVAL; |
|---|
| 1026 | + f2fs_info(sbi, "Image doesn't support compression"); |
|---|
| 1027 | + break; |
|---|
| 869 | 1028 | } |
|---|
| 870 | 1029 | name = match_strdup(&args[0]); |
|---|
| 871 | 1030 | if (!name) |
|---|
| 872 | 1031 | return -ENOMEM; |
|---|
| 873 | 1032 | if (!strcmp(name, "lzo")) { |
|---|
| 1033 | +#ifdef CONFIG_F2FS_FS_LZO |
|---|
| 1034 | + F2FS_OPTION(sbi).compress_level = 0; |
|---|
| 874 | 1035 | F2FS_OPTION(sbi).compress_algorithm = |
|---|
| 875 | 1036 | COMPRESS_LZO; |
|---|
| 876 | | - } else if (!strcmp(name, "lz4")) { |
|---|
| 1037 | +#else |
|---|
| 1038 | + f2fs_info(sbi, "kernel doesn't support lzo compression"); |
|---|
| 1039 | +#endif |
|---|
| 1040 | + } else if (!strncmp(name, "lz4", 3)) { |
|---|
| 1041 | +#ifdef CONFIG_F2FS_FS_LZ4 |
|---|
| 1042 | + ret = f2fs_set_lz4hc_level(sbi, name); |
|---|
| 1043 | + if (ret) { |
|---|
| 1044 | + kfree(name); |
|---|
| 1045 | + return -EINVAL; |
|---|
| 1046 | + } |
|---|
| 877 | 1047 | F2FS_OPTION(sbi).compress_algorithm = |
|---|
| 878 | 1048 | COMPRESS_LZ4; |
|---|
| 879 | | - } else if (!strcmp(name, "zstd")) { |
|---|
| 1049 | +#else |
|---|
| 1050 | + f2fs_info(sbi, "kernel doesn't support lz4 compression"); |
|---|
| 1051 | +#endif |
|---|
| 1052 | + } else if (!strncmp(name, "zstd", 4)) { |
|---|
| 1053 | +#ifdef CONFIG_F2FS_FS_ZSTD |
|---|
| 1054 | + ret = f2fs_set_zstd_level(sbi, name); |
|---|
| 1055 | + if (ret) { |
|---|
| 1056 | + kfree(name); |
|---|
| 1057 | + return -EINVAL; |
|---|
| 1058 | + } |
|---|
| 880 | 1059 | F2FS_OPTION(sbi).compress_algorithm = |
|---|
| 881 | 1060 | COMPRESS_ZSTD; |
|---|
| 1061 | +#else |
|---|
| 1062 | + f2fs_info(sbi, "kernel doesn't support zstd compression"); |
|---|
| 1063 | +#endif |
|---|
| 1064 | + } else if (!strcmp(name, "lzo-rle")) { |
|---|
| 1065 | +#ifdef CONFIG_F2FS_FS_LZORLE |
|---|
| 1066 | + F2FS_OPTION(sbi).compress_level = 0; |
|---|
| 1067 | + F2FS_OPTION(sbi).compress_algorithm = |
|---|
| 1068 | + COMPRESS_LZORLE; |
|---|
| 1069 | +#else |
|---|
| 1070 | + f2fs_info(sbi, "kernel doesn't support lzorle compression"); |
|---|
| 1071 | +#endif |
|---|
| 882 | 1072 | } else { |
|---|
| 883 | 1073 | kfree(name); |
|---|
| 884 | 1074 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 887 | 1077 | break; |
|---|
| 888 | 1078 | case Opt_compress_log_size: |
|---|
| 889 | 1079 | if (!f2fs_sb_has_compression(sbi)) { |
|---|
| 890 | | - f2fs_err(sbi, "Compression feature is off"); |
|---|
| 891 | | - return -EINVAL; |
|---|
| 1080 | + f2fs_info(sbi, "Image doesn't support compression"); |
|---|
| 1081 | + break; |
|---|
| 892 | 1082 | } |
|---|
| 893 | 1083 | if (args->from && match_int(args, &arg)) |
|---|
| 894 | 1084 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 902 | 1092 | break; |
|---|
| 903 | 1093 | case Opt_compress_extension: |
|---|
| 904 | 1094 | if (!f2fs_sb_has_compression(sbi)) { |
|---|
| 905 | | - f2fs_err(sbi, "Compression feature is off"); |
|---|
| 906 | | - return -EINVAL; |
|---|
| 1095 | + f2fs_info(sbi, "Image doesn't support compression"); |
|---|
| 1096 | + break; |
|---|
| 907 | 1097 | } |
|---|
| 908 | 1098 | name = match_strdup(&args[0]); |
|---|
| 909 | 1099 | if (!name) |
|---|
| .. | .. |
|---|
| 924 | 1114 | F2FS_OPTION(sbi).compress_ext_cnt++; |
|---|
| 925 | 1115 | kfree(name); |
|---|
| 926 | 1116 | break; |
|---|
| 1117 | + case Opt_compress_chksum: |
|---|
| 1118 | + F2FS_OPTION(sbi).compress_chksum = true; |
|---|
| 1119 | + break; |
|---|
| 1120 | + case Opt_compress_mode: |
|---|
| 1121 | + name = match_strdup(&args[0]); |
|---|
| 1122 | + if (!name) |
|---|
| 1123 | + return -ENOMEM; |
|---|
| 1124 | + if (!strcmp(name, "fs")) { |
|---|
| 1125 | + F2FS_OPTION(sbi).compress_mode = COMPR_MODE_FS; |
|---|
| 1126 | + } else if (!strcmp(name, "user")) { |
|---|
| 1127 | + F2FS_OPTION(sbi).compress_mode = COMPR_MODE_USER; |
|---|
| 1128 | + } else { |
|---|
| 1129 | + kfree(name); |
|---|
| 1130 | + return -EINVAL; |
|---|
| 1131 | + } |
|---|
| 1132 | + kfree(name); |
|---|
| 1133 | + break; |
|---|
| 1134 | + case Opt_compress_cache: |
|---|
| 1135 | + set_opt(sbi, COMPRESS_CACHE); |
|---|
| 1136 | + break; |
|---|
| 1137 | +#else |
|---|
| 1138 | + case Opt_compress_algorithm: |
|---|
| 1139 | + case Opt_compress_log_size: |
|---|
| 1140 | + case Opt_compress_extension: |
|---|
| 1141 | + case Opt_compress_chksum: |
|---|
| 1142 | + case Opt_compress_mode: |
|---|
| 1143 | + case Opt_compress_cache: |
|---|
| 1144 | + f2fs_info(sbi, "compression options not supported"); |
|---|
| 1145 | + break; |
|---|
| 1146 | +#endif |
|---|
| 1147 | + case Opt_atgc: |
|---|
| 1148 | + set_opt(sbi, ATGC); |
|---|
| 1149 | + break; |
|---|
| 1150 | + case Opt_gc_merge: |
|---|
| 1151 | + set_opt(sbi, GC_MERGE); |
|---|
| 1152 | + break; |
|---|
| 1153 | + case Opt_nogc_merge: |
|---|
| 1154 | + clear_opt(sbi, GC_MERGE); |
|---|
| 1155 | + break; |
|---|
| 1156 | + case Opt_age_extent_cache: |
|---|
| 1157 | + set_opt(sbi, AGE_EXTENT_CACHE); |
|---|
| 1158 | + break; |
|---|
| 1159 | + case Opt_memory_mode: |
|---|
| 1160 | + name = match_strdup(&args[0]); |
|---|
| 1161 | + if (!name) |
|---|
| 1162 | + return -ENOMEM; |
|---|
| 1163 | + if (!strcmp(name, "normal")) { |
|---|
| 1164 | + F2FS_OPTION(sbi).memory_mode = |
|---|
| 1165 | + MEMORY_MODE_NORMAL; |
|---|
| 1166 | + } else if (!strcmp(name, "low")) { |
|---|
| 1167 | + F2FS_OPTION(sbi).memory_mode = |
|---|
| 1168 | + MEMORY_MODE_LOW; |
|---|
| 1169 | + } else { |
|---|
| 1170 | + kfree(name); |
|---|
| 1171 | + return -EINVAL; |
|---|
| 1172 | + } |
|---|
| 1173 | + kfree(name); |
|---|
| 1174 | + break; |
|---|
| 927 | 1175 | default: |
|---|
| 928 | 1176 | f2fs_err(sbi, "Unrecognized mount option \"%s\" or missing value", |
|---|
| 929 | 1177 | p); |
|---|
| 930 | 1178 | return -EINVAL; |
|---|
| 931 | 1179 | } |
|---|
| 932 | 1180 | } |
|---|
| 1181 | +default_check: |
|---|
| 933 | 1182 | #ifdef CONFIG_QUOTA |
|---|
| 934 | 1183 | if (f2fs_check_quota_options(sbi)) |
|---|
| 935 | 1184 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 947 | 1196 | if (f2fs_sb_has_casefold(sbi)) { |
|---|
| 948 | 1197 | f2fs_err(sbi, |
|---|
| 949 | 1198 | "Filesystem with casefold feature cannot be mounted without CONFIG_UNICODE"); |
|---|
| 1199 | + return -EINVAL; |
|---|
| 1200 | + } |
|---|
| 1201 | +#endif |
|---|
| 1202 | + /* |
|---|
| 1203 | + * The BLKZONED feature indicates that the drive was formatted with |
|---|
| 1204 | + * zone alignment optimization. This is optional for host-aware |
|---|
| 1205 | + * devices, but mandatory for host-managed zoned block devices. |
|---|
| 1206 | + */ |
|---|
| 1207 | +#ifndef CONFIG_BLK_DEV_ZONED |
|---|
| 1208 | + if (f2fs_sb_has_blkzoned(sbi)) { |
|---|
| 1209 | + f2fs_err(sbi, "Zoned block device support is not enabled"); |
|---|
| 950 | 1210 | return -EINVAL; |
|---|
| 951 | 1211 | } |
|---|
| 952 | 1212 | #endif |
|---|
| .. | .. |
|---|
| 982 | 1242 | } |
|---|
| 983 | 1243 | |
|---|
| 984 | 1244 | if (test_opt(sbi, DISABLE_CHECKPOINT) && f2fs_lfs_mode(sbi)) { |
|---|
| 985 | | - f2fs_err(sbi, "LFS not compatible with checkpoint=disable\n"); |
|---|
| 1245 | + f2fs_err(sbi, "LFS not compatible with checkpoint=disable"); |
|---|
| 986 | 1246 | return -EINVAL; |
|---|
| 987 | 1247 | } |
|---|
| 988 | 1248 | |
|---|
| 989 | 1249 | /* Not pass down write hints if the number of active logs is lesser |
|---|
| 990 | | - * than NR_CURSEG_TYPE. |
|---|
| 1250 | + * than NR_CURSEG_PERSIST_TYPE. |
|---|
| 991 | 1251 | */ |
|---|
| 992 | | - if (F2FS_OPTION(sbi).active_logs != NR_CURSEG_TYPE) |
|---|
| 1252 | + if (F2FS_OPTION(sbi).active_logs != NR_CURSEG_PERSIST_TYPE) |
|---|
| 993 | 1253 | F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF; |
|---|
| 1254 | + |
|---|
| 1255 | + if (f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) { |
|---|
| 1256 | + f2fs_err(sbi, "Allow to mount readonly mode only"); |
|---|
| 1257 | + return -EROFS; |
|---|
| 1258 | + } |
|---|
| 994 | 1259 | return 0; |
|---|
| 995 | 1260 | } |
|---|
| 996 | 1261 | |
|---|
| .. | .. |
|---|
| 1006 | 1271 | |
|---|
| 1007 | 1272 | /* Initialize f2fs-specific inode info */ |
|---|
| 1008 | 1273 | atomic_set(&fi->dirty_pages, 0); |
|---|
| 1009 | | - init_rwsem(&fi->i_sem); |
|---|
| 1274 | + atomic_set(&fi->i_compr_blocks, 0); |
|---|
| 1275 | + init_f2fs_rwsem(&fi->i_sem); |
|---|
| 1010 | 1276 | spin_lock_init(&fi->i_size_lock); |
|---|
| 1011 | 1277 | INIT_LIST_HEAD(&fi->dirty_list); |
|---|
| 1012 | 1278 | INIT_LIST_HEAD(&fi->gdirty_list); |
|---|
| 1013 | 1279 | INIT_LIST_HEAD(&fi->inmem_ilist); |
|---|
| 1014 | 1280 | INIT_LIST_HEAD(&fi->inmem_pages); |
|---|
| 1015 | 1281 | mutex_init(&fi->inmem_lock); |
|---|
| 1016 | | - init_rwsem(&fi->i_gc_rwsem[READ]); |
|---|
| 1017 | | - init_rwsem(&fi->i_gc_rwsem[WRITE]); |
|---|
| 1018 | | - init_rwsem(&fi->i_mmap_sem); |
|---|
| 1019 | | - init_rwsem(&fi->i_xattr_sem); |
|---|
| 1282 | + init_f2fs_rwsem(&fi->i_gc_rwsem[READ]); |
|---|
| 1283 | + init_f2fs_rwsem(&fi->i_gc_rwsem[WRITE]); |
|---|
| 1284 | + init_f2fs_rwsem(&fi->i_mmap_sem); |
|---|
| 1285 | + init_f2fs_rwsem(&fi->i_xattr_sem); |
|---|
| 1020 | 1286 | |
|---|
| 1021 | 1287 | /* Will be used by directory only */ |
|---|
| 1022 | 1288 | fi->i_dir_level = F2FS_SB(sb)->dir_level; |
|---|
| .. | .. |
|---|
| 1148 | 1414 | f2fs_inode_dirtied(inode, false); |
|---|
| 1149 | 1415 | } |
|---|
| 1150 | 1416 | |
|---|
| 1151 | | -static void f2fs_i_callback(struct rcu_head *head) |
|---|
| 1417 | +static void f2fs_free_inode(struct inode *inode) |
|---|
| 1152 | 1418 | { |
|---|
| 1153 | | - struct inode *inode = container_of(head, struct inode, i_rcu); |
|---|
| 1154 | | - |
|---|
| 1155 | 1419 | fscrypt_free_inode(inode); |
|---|
| 1156 | | - |
|---|
| 1157 | 1420 | kmem_cache_free(f2fs_inode_cachep, F2FS_I(inode)); |
|---|
| 1158 | | -} |
|---|
| 1159 | | - |
|---|
| 1160 | | -static void f2fs_destroy_inode(struct inode *inode) |
|---|
| 1161 | | -{ |
|---|
| 1162 | | - call_rcu(&inode->i_rcu, f2fs_i_callback); |
|---|
| 1163 | 1421 | } |
|---|
| 1164 | 1422 | |
|---|
| 1165 | 1423 | static void destroy_percpu_info(struct f2fs_sb_info *sbi) |
|---|
| .. | .. |
|---|
| 1194 | 1452 | |
|---|
| 1195 | 1453 | /* prevent remaining shrinker jobs */ |
|---|
| 1196 | 1454 | mutex_lock(&sbi->umount_mutex); |
|---|
| 1455 | + |
|---|
| 1456 | + /* |
|---|
| 1457 | + * flush all issued checkpoints and stop checkpoint issue thread. |
|---|
| 1458 | + * after then, all checkpoints should be done by each process context. |
|---|
| 1459 | + */ |
|---|
| 1460 | + f2fs_stop_ckpt_thread(sbi); |
|---|
| 1197 | 1461 | |
|---|
| 1198 | 1462 | /* |
|---|
| 1199 | 1463 | * We don't need to do checkpoint when superblock is clean. |
|---|
| .. | .. |
|---|
| 1235 | 1499 | |
|---|
| 1236 | 1500 | f2fs_bug_on(sbi, sbi->fsync_node_num); |
|---|
| 1237 | 1501 | |
|---|
| 1502 | + f2fs_destroy_compress_inode(sbi); |
|---|
| 1503 | + |
|---|
| 1238 | 1504 | iput(sbi->node_inode); |
|---|
| 1239 | 1505 | sbi->node_inode = NULL; |
|---|
| 1240 | 1506 | |
|---|
| .. | .. |
|---|
| 1258 | 1524 | sb->s_fs_info = NULL; |
|---|
| 1259 | 1525 | if (sbi->s_chksum_driver) |
|---|
| 1260 | 1526 | crypto_free_shash(sbi->s_chksum_driver); |
|---|
| 1261 | | - kvfree(sbi->raw_super); |
|---|
| 1527 | + kfree(sbi->raw_super); |
|---|
| 1262 | 1528 | |
|---|
| 1263 | 1529 | destroy_device_list(sbi); |
|---|
| 1530 | + f2fs_destroy_page_array_cache(sbi); |
|---|
| 1264 | 1531 | f2fs_destroy_xattr_caches(sbi); |
|---|
| 1265 | 1532 | mempool_destroy(sbi->write_io_dummy); |
|---|
| 1266 | 1533 | #ifdef CONFIG_QUOTA |
|---|
| 1267 | 1534 | for (i = 0; i < MAXQUOTAS; i++) |
|---|
| 1268 | | - kvfree(F2FS_OPTION(sbi).s_qf_names[i]); |
|---|
| 1535 | + kfree(F2FS_OPTION(sbi).s_qf_names[i]); |
|---|
| 1269 | 1536 | #endif |
|---|
| 1270 | | - fscrypt_free_dummy_context(&F2FS_OPTION(sbi).dummy_enc_ctx); |
|---|
| 1537 | + fscrypt_free_dummy_policy(&F2FS_OPTION(sbi).dummy_enc_policy); |
|---|
| 1271 | 1538 | destroy_percpu_info(sbi); |
|---|
| 1272 | 1539 | for (i = 0; i < NR_PAGE_TYPE; i++) |
|---|
| 1273 | 1540 | kvfree(sbi->write_io[i]); |
|---|
| 1274 | 1541 | #ifdef CONFIG_UNICODE |
|---|
| 1275 | 1542 | utf8_unload(sb->s_encoding); |
|---|
| 1276 | 1543 | #endif |
|---|
| 1277 | | - kvfree(sbi); |
|---|
| 1544 | + kfree(sbi); |
|---|
| 1278 | 1545 | } |
|---|
| 1279 | 1546 | |
|---|
| 1280 | 1547 | int f2fs_sync_fs(struct super_block *sb, int sync) |
|---|
| .. | .. |
|---|
| 1293 | 1560 | return -EAGAIN; |
|---|
| 1294 | 1561 | |
|---|
| 1295 | 1562 | if (sync) { |
|---|
| 1296 | | - struct cp_control cpc; |
|---|
| 1297 | | - |
|---|
| 1298 | | - cpc.reason = __get_cp_reason(sbi); |
|---|
| 1299 | | - |
|---|
| 1563 | + err = f2fs_issue_checkpoint(sbi); |
|---|
| 1300 | 1564 | atomic_set(&sbi->no_cp_fsync_pages, 0); |
|---|
| 1301 | | - down_write(&sbi->gc_lock); |
|---|
| 1302 | | - err = f2fs_write_checkpoint(sbi, &cpc); |
|---|
| 1303 | | - up_write(&sbi->gc_lock); |
|---|
| 1304 | 1565 | } |
|---|
| 1305 | | - f2fs_trace_ios(NULL, 1); |
|---|
| 1306 | 1566 | |
|---|
| 1307 | 1567 | return err; |
|---|
| 1308 | 1568 | } |
|---|
| .. | .. |
|---|
| 1319 | 1579 | /* must be clean, since sync_filesystem() was already called */ |
|---|
| 1320 | 1580 | if (is_sbi_flag_set(F2FS_SB(sb), SBI_IS_DIRTY)) |
|---|
| 1321 | 1581 | return -EINVAL; |
|---|
| 1582 | + |
|---|
| 1583 | + /* Let's flush checkpoints and stop the thread. */ |
|---|
| 1584 | + f2fs_flush_ckpt_thread(F2FS_SB(sb)); |
|---|
| 1585 | + |
|---|
| 1586 | + /* to avoid deadlock on f2fs_evict_inode->SB_FREEZE_FS */ |
|---|
| 1587 | + set_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING); |
|---|
| 1322 | 1588 | return 0; |
|---|
| 1323 | 1589 | } |
|---|
| 1324 | 1590 | |
|---|
| 1325 | 1591 | static int f2fs_unfreeze(struct super_block *sb) |
|---|
| 1326 | 1592 | { |
|---|
| 1593 | + clear_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING); |
|---|
| 1327 | 1594 | return 0; |
|---|
| 1328 | 1595 | } |
|---|
| 1329 | 1596 | |
|---|
| .. | .. |
|---|
| 1416 | 1683 | } |
|---|
| 1417 | 1684 | |
|---|
| 1418 | 1685 | buf->f_namelen = F2FS_NAME_LEN; |
|---|
| 1419 | | - buf->f_fsid.val[0] = (u32)id; |
|---|
| 1420 | | - buf->f_fsid.val[1] = (u32)(id >> 32); |
|---|
| 1686 | + buf->f_fsid = u64_to_fsid(id); |
|---|
| 1421 | 1687 | |
|---|
| 1422 | 1688 | #ifdef CONFIG_QUOTA |
|---|
| 1423 | 1689 | if (is_inode_flag_set(dentry->d_inode, FI_PROJ_INHERIT) && |
|---|
| .. | .. |
|---|
| 1465 | 1731 | #endif |
|---|
| 1466 | 1732 | } |
|---|
| 1467 | 1733 | |
|---|
| 1734 | +#ifdef CONFIG_F2FS_FS_COMPRESSION |
|---|
| 1468 | 1735 | static inline void f2fs_show_compress_options(struct seq_file *seq, |
|---|
| 1469 | 1736 | struct super_block *sb) |
|---|
| 1470 | 1737 | { |
|---|
| .. | .. |
|---|
| 1485 | 1752 | case COMPRESS_ZSTD: |
|---|
| 1486 | 1753 | algtype = "zstd"; |
|---|
| 1487 | 1754 | break; |
|---|
| 1755 | + case COMPRESS_LZORLE: |
|---|
| 1756 | + algtype = "lzo-rle"; |
|---|
| 1757 | + break; |
|---|
| 1488 | 1758 | } |
|---|
| 1489 | 1759 | seq_printf(seq, ",compress_algorithm=%s", algtype); |
|---|
| 1760 | + |
|---|
| 1761 | + if (F2FS_OPTION(sbi).compress_level) |
|---|
| 1762 | + seq_printf(seq, ":%d", F2FS_OPTION(sbi).compress_level); |
|---|
| 1490 | 1763 | |
|---|
| 1491 | 1764 | seq_printf(seq, ",compress_log_size=%u", |
|---|
| 1492 | 1765 | F2FS_OPTION(sbi).compress_log_size); |
|---|
| .. | .. |
|---|
| 1495 | 1768 | seq_printf(seq, ",compress_extension=%s", |
|---|
| 1496 | 1769 | F2FS_OPTION(sbi).extensions[i]); |
|---|
| 1497 | 1770 | } |
|---|
| 1771 | + |
|---|
| 1772 | + if (F2FS_OPTION(sbi).compress_chksum) |
|---|
| 1773 | + seq_puts(seq, ",compress_chksum"); |
|---|
| 1774 | + |
|---|
| 1775 | + if (F2FS_OPTION(sbi).compress_mode == COMPR_MODE_FS) |
|---|
| 1776 | + seq_printf(seq, ",compress_mode=%s", "fs"); |
|---|
| 1777 | + else if (F2FS_OPTION(sbi).compress_mode == COMPR_MODE_USER) |
|---|
| 1778 | + seq_printf(seq, ",compress_mode=%s", "user"); |
|---|
| 1779 | + |
|---|
| 1780 | + if (test_opt(sbi, COMPRESS_CACHE)) |
|---|
| 1781 | + seq_puts(seq, ",compress_cache"); |
|---|
| 1498 | 1782 | } |
|---|
| 1783 | +#endif |
|---|
| 1499 | 1784 | |
|---|
| 1500 | 1785 | static int f2fs_show_options(struct seq_file *seq, struct dentry *root) |
|---|
| 1501 | 1786 | { |
|---|
| .. | .. |
|---|
| 1507 | 1792 | seq_printf(seq, ",background_gc=%s", "on"); |
|---|
| 1508 | 1793 | else if (F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_OFF) |
|---|
| 1509 | 1794 | seq_printf(seq, ",background_gc=%s", "off"); |
|---|
| 1795 | + |
|---|
| 1796 | + if (test_opt(sbi, GC_MERGE)) |
|---|
| 1797 | + seq_puts(seq, ",gc_merge"); |
|---|
| 1510 | 1798 | |
|---|
| 1511 | 1799 | if (test_opt(sbi, DISABLE_ROLL_FORWARD)) |
|---|
| 1512 | 1800 | seq_puts(seq, ",disable_roll_forward"); |
|---|
| .. | .. |
|---|
| 1555 | 1843 | seq_puts(seq, ",nobarrier"); |
|---|
| 1556 | 1844 | if (test_opt(sbi, FASTBOOT)) |
|---|
| 1557 | 1845 | seq_puts(seq, ",fastboot"); |
|---|
| 1558 | | - if (test_opt(sbi, EXTENT_CACHE)) |
|---|
| 1846 | + if (test_opt(sbi, READ_EXTENT_CACHE)) |
|---|
| 1559 | 1847 | seq_puts(seq, ",extent_cache"); |
|---|
| 1560 | 1848 | else |
|---|
| 1561 | 1849 | seq_puts(seq, ",noextent_cache"); |
|---|
| 1850 | + if (test_opt(sbi, AGE_EXTENT_CACHE)) |
|---|
| 1851 | + seq_puts(seq, ",age_extent_cache"); |
|---|
| 1562 | 1852 | if (test_opt(sbi, DATA_FLUSH)) |
|---|
| 1563 | 1853 | seq_puts(seq, ",data_flush"); |
|---|
| 1564 | 1854 | |
|---|
| .. | .. |
|---|
| 1604 | 1894 | |
|---|
| 1605 | 1895 | fscrypt_show_test_dummy_encryption(seq, ',', sbi->sb); |
|---|
| 1606 | 1896 | |
|---|
| 1607 | | -#ifdef CONFIG_FS_ENCRYPTION |
|---|
| 1608 | | - if (F2FS_OPTION(sbi).inlinecrypt) |
|---|
| 1897 | + if (sbi->sb->s_flags & SB_INLINECRYPT) |
|---|
| 1609 | 1898 | seq_puts(seq, ",inlinecrypt"); |
|---|
| 1610 | | -#endif |
|---|
| 1611 | 1899 | |
|---|
| 1612 | 1900 | if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_DEFAULT) |
|---|
| 1613 | 1901 | seq_printf(seq, ",alloc_mode=%s", "default"); |
|---|
| .. | .. |
|---|
| 1617 | 1905 | if (test_opt(sbi, DISABLE_CHECKPOINT)) |
|---|
| 1618 | 1906 | seq_printf(seq, ",checkpoint=disable:%u", |
|---|
| 1619 | 1907 | F2FS_OPTION(sbi).unusable_cap); |
|---|
| 1908 | + if (test_opt(sbi, MERGE_CHECKPOINT)) |
|---|
| 1909 | + seq_puts(seq, ",checkpoint_merge"); |
|---|
| 1910 | + else |
|---|
| 1911 | + seq_puts(seq, ",nocheckpoint_merge"); |
|---|
| 1620 | 1912 | if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_POSIX) |
|---|
| 1621 | 1913 | seq_printf(seq, ",fsync_mode=%s", "posix"); |
|---|
| 1622 | 1914 | else if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) |
|---|
| .. | .. |
|---|
| 1624 | 1916 | else if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_NOBARRIER) |
|---|
| 1625 | 1917 | seq_printf(seq, ",fsync_mode=%s", "nobarrier"); |
|---|
| 1626 | 1918 | |
|---|
| 1919 | +#ifdef CONFIG_F2FS_FS_COMPRESSION |
|---|
| 1627 | 1920 | f2fs_show_compress_options(seq, sbi->sb); |
|---|
| 1921 | +#endif |
|---|
| 1922 | + |
|---|
| 1923 | + if (test_opt(sbi, ATGC)) |
|---|
| 1924 | + seq_puts(seq, ",atgc"); |
|---|
| 1925 | + |
|---|
| 1926 | + if (F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_NORMAL) |
|---|
| 1927 | + seq_printf(seq, ",memory=%s", "normal"); |
|---|
| 1928 | + else if (F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_LOW) |
|---|
| 1929 | + seq_printf(seq, ",memory=%s", "low"); |
|---|
| 1930 | + |
|---|
| 1628 | 1931 | return 0; |
|---|
| 1629 | 1932 | } |
|---|
| 1630 | 1933 | |
|---|
| 1631 | | -static void default_options(struct f2fs_sb_info *sbi) |
|---|
| 1934 | +static void default_options(struct f2fs_sb_info *sbi, bool remount) |
|---|
| 1632 | 1935 | { |
|---|
| 1633 | 1936 | /* init some FS parameters */ |
|---|
| 1634 | | - F2FS_OPTION(sbi).active_logs = NR_CURSEG_TYPE; |
|---|
| 1937 | + if (!remount) { |
|---|
| 1938 | + set_opt(sbi, READ_EXTENT_CACHE); |
|---|
| 1939 | + clear_opt(sbi, DISABLE_CHECKPOINT); |
|---|
| 1940 | + |
|---|
| 1941 | + if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi)) |
|---|
| 1942 | + set_opt(sbi, DISCARD); |
|---|
| 1943 | + } |
|---|
| 1944 | + |
|---|
| 1945 | + if (f2fs_sb_has_readonly(sbi)) |
|---|
| 1946 | + F2FS_OPTION(sbi).active_logs = NR_CURSEG_RO_TYPE; |
|---|
| 1947 | + else |
|---|
| 1948 | + F2FS_OPTION(sbi).active_logs = NR_CURSEG_PERSIST_TYPE; |
|---|
| 1949 | + |
|---|
| 1635 | 1950 | F2FS_OPTION(sbi).inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS; |
|---|
| 1636 | 1951 | F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF; |
|---|
| 1637 | 1952 | F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT; |
|---|
| 1638 | 1953 | F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_POSIX; |
|---|
| 1639 | | -#ifdef CONFIG_FS_ENCRYPTION |
|---|
| 1640 | | - F2FS_OPTION(sbi).inlinecrypt = false; |
|---|
| 1641 | | -#endif |
|---|
| 1642 | 1954 | F2FS_OPTION(sbi).s_resuid = make_kuid(&init_user_ns, F2FS_DEF_RESUID); |
|---|
| 1643 | 1955 | F2FS_OPTION(sbi).s_resgid = make_kgid(&init_user_ns, F2FS_DEF_RESGID); |
|---|
| 1644 | 1956 | F2FS_OPTION(sbi).compress_algorithm = COMPRESS_LZ4; |
|---|
| 1645 | 1957 | F2FS_OPTION(sbi).compress_log_size = MIN_COMPRESS_LOG_SIZE; |
|---|
| 1646 | 1958 | F2FS_OPTION(sbi).compress_ext_cnt = 0; |
|---|
| 1959 | + F2FS_OPTION(sbi).compress_mode = COMPR_MODE_FS; |
|---|
| 1647 | 1960 | F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_ON; |
|---|
| 1961 | + F2FS_OPTION(sbi).memory_mode = MEMORY_MODE_NORMAL; |
|---|
| 1962 | + |
|---|
| 1963 | + sbi->sb->s_flags &= ~SB_INLINECRYPT; |
|---|
| 1648 | 1964 | |
|---|
| 1649 | 1965 | set_opt(sbi, INLINE_XATTR); |
|---|
| 1650 | 1966 | set_opt(sbi, INLINE_DATA); |
|---|
| 1651 | 1967 | set_opt(sbi, INLINE_DENTRY); |
|---|
| 1652 | | - set_opt(sbi, EXTENT_CACHE); |
|---|
| 1653 | 1968 | set_opt(sbi, NOHEAP); |
|---|
| 1654 | | - clear_opt(sbi, DISABLE_CHECKPOINT); |
|---|
| 1969 | + set_opt(sbi, MERGE_CHECKPOINT); |
|---|
| 1655 | 1970 | F2FS_OPTION(sbi).unusable_cap = 0; |
|---|
| 1656 | 1971 | sbi->sb->s_flags |= SB_LAZYTIME; |
|---|
| 1657 | 1972 | set_opt(sbi, FLUSH_MERGE); |
|---|
| 1658 | | - set_opt(sbi, DISCARD); |
|---|
| 1659 | 1973 | if (f2fs_sb_has_blkzoned(sbi)) |
|---|
| 1660 | 1974 | F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS; |
|---|
| 1661 | 1975 | else |
|---|
| .. | .. |
|---|
| 1689 | 2003 | } |
|---|
| 1690 | 2004 | sbi->sb->s_flags |= SB_ACTIVE; |
|---|
| 1691 | 2005 | |
|---|
| 2006 | + /* check if we need more GC first */ |
|---|
| 2007 | + unusable = f2fs_get_unusable_blocks(sbi); |
|---|
| 2008 | + if (!f2fs_disable_cp_again(sbi, unusable)) |
|---|
| 2009 | + goto skip_gc; |
|---|
| 2010 | + |
|---|
| 1692 | 2011 | f2fs_update_time(sbi, DISABLE_TIME); |
|---|
| 1693 | 2012 | |
|---|
| 1694 | 2013 | while (!f2fs_time_over(sbi, DISABLE_TIME)) { |
|---|
| 1695 | | - down_write(&sbi->gc_lock); |
|---|
| 1696 | | - err = f2fs_gc(sbi, true, false, NULL_SEGNO); |
|---|
| 2014 | + f2fs_down_write(&sbi->gc_lock); |
|---|
| 2015 | + err = f2fs_gc(sbi, true, false, false, NULL_SEGNO); |
|---|
| 1697 | 2016 | if (err == -ENODATA) { |
|---|
| 1698 | 2017 | err = 0; |
|---|
| 1699 | 2018 | break; |
|---|
| .. | .. |
|---|
| 1704 | 2023 | |
|---|
| 1705 | 2024 | ret = sync_filesystem(sbi->sb); |
|---|
| 1706 | 2025 | if (ret || err) { |
|---|
| 1707 | | - err = ret ? ret: err; |
|---|
| 2026 | + err = ret ? ret : err; |
|---|
| 1708 | 2027 | goto restore_flag; |
|---|
| 1709 | 2028 | } |
|---|
| 1710 | 2029 | |
|---|
| .. | .. |
|---|
| 1714 | 2033 | goto restore_flag; |
|---|
| 1715 | 2034 | } |
|---|
| 1716 | 2035 | |
|---|
| 1717 | | - down_write(&sbi->gc_lock); |
|---|
| 2036 | +skip_gc: |
|---|
| 2037 | + f2fs_down_write(&sbi->gc_lock); |
|---|
| 1718 | 2038 | cpc.reason = CP_PAUSE; |
|---|
| 1719 | 2039 | set_sbi_flag(sbi, SBI_CP_DISABLED); |
|---|
| 1720 | 2040 | err = f2fs_write_checkpoint(sbi, &cpc); |
|---|
| .. | .. |
|---|
| 1726 | 2046 | spin_unlock(&sbi->stat_lock); |
|---|
| 1727 | 2047 | |
|---|
| 1728 | 2048 | out_unlock: |
|---|
| 1729 | | - up_write(&sbi->gc_lock); |
|---|
| 2049 | + f2fs_up_write(&sbi->gc_lock); |
|---|
| 1730 | 2050 | restore_flag: |
|---|
| 1731 | 2051 | sbi->sb->s_flags = s_flags; /* Restore SB_RDONLY status */ |
|---|
| 1732 | 2052 | return err; |
|---|
| .. | .. |
|---|
| 1734 | 2054 | |
|---|
| 1735 | 2055 | static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) |
|---|
| 1736 | 2056 | { |
|---|
| 1737 | | - /* we should flush all the data to keep data consistency */ |
|---|
| 1738 | | - sync_inodes_sb(sbi->sb); |
|---|
| 2057 | + int retry = DEFAULT_RETRY_IO_COUNT; |
|---|
| 1739 | 2058 | |
|---|
| 1740 | | - down_write(&sbi->gc_lock); |
|---|
| 2059 | + /* we should flush all the data to keep data consistency */ |
|---|
| 2060 | + do { |
|---|
| 2061 | + sync_inodes_sb(sbi->sb); |
|---|
| 2062 | + cond_resched(); |
|---|
| 2063 | + congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT); |
|---|
| 2064 | + } while (get_pages(sbi, F2FS_DIRTY_DATA) && retry--); |
|---|
| 2065 | + |
|---|
| 2066 | + if (unlikely(retry < 0)) |
|---|
| 2067 | + f2fs_warn(sbi, "checkpoint=enable has some unwritten data."); |
|---|
| 2068 | + |
|---|
| 2069 | + f2fs_down_write(&sbi->gc_lock); |
|---|
| 1741 | 2070 | f2fs_dirty_to_prefree(sbi); |
|---|
| 1742 | 2071 | |
|---|
| 1743 | 2072 | clear_sbi_flag(sbi, SBI_CP_DISABLED); |
|---|
| 1744 | 2073 | set_sbi_flag(sbi, SBI_IS_DIRTY); |
|---|
| 1745 | | - up_write(&sbi->gc_lock); |
|---|
| 2074 | + f2fs_up_write(&sbi->gc_lock); |
|---|
| 1746 | 2075 | |
|---|
| 1747 | 2076 | f2fs_sync_fs(sbi->sb, 1); |
|---|
| 2077 | + |
|---|
| 2078 | + /* Let's ensure there's no pending checkpoint anymore */ |
|---|
| 2079 | + f2fs_flush_ckpt_thread(sbi); |
|---|
| 1748 | 2080 | } |
|---|
| 1749 | 2081 | |
|---|
| 1750 | 2082 | static int f2fs_remount(struct super_block *sb, int *flags, char *data) |
|---|
| .. | .. |
|---|
| 1753 | 2085 | struct f2fs_mount_info org_mount_opt; |
|---|
| 1754 | 2086 | unsigned long old_sb_flags; |
|---|
| 1755 | 2087 | int err; |
|---|
| 1756 | | - bool need_restart_gc = false; |
|---|
| 1757 | | - bool need_stop_gc = false; |
|---|
| 1758 | | - bool no_extent_cache = !test_opt(sbi, EXTENT_CACHE); |
|---|
| 2088 | + bool need_restart_gc = false, need_stop_gc = false; |
|---|
| 2089 | + bool need_restart_ckpt = false, need_stop_ckpt = false; |
|---|
| 2090 | + bool need_restart_flush = false, need_stop_flush = false; |
|---|
| 2091 | + bool no_read_extent_cache = !test_opt(sbi, READ_EXTENT_CACHE); |
|---|
| 2092 | + bool no_age_extent_cache = !test_opt(sbi, AGE_EXTENT_CACHE); |
|---|
| 1759 | 2093 | bool disable_checkpoint = test_opt(sbi, DISABLE_CHECKPOINT); |
|---|
| 1760 | 2094 | bool no_io_align = !F2FS_IO_ALIGNED(sbi); |
|---|
| 2095 | + bool no_atgc = !test_opt(sbi, ATGC); |
|---|
| 2096 | + bool no_compress_cache = !test_opt(sbi, COMPRESS_CACHE); |
|---|
| 1761 | 2097 | bool checkpoint_changed; |
|---|
| 1762 | 2098 | #ifdef CONFIG_QUOTA |
|---|
| 1763 | 2099 | int i, j; |
|---|
| .. | .. |
|---|
| 1779 | 2115 | GFP_KERNEL); |
|---|
| 1780 | 2116 | if (!org_mount_opt.s_qf_names[i]) { |
|---|
| 1781 | 2117 | for (j = 0; j < i; j++) |
|---|
| 1782 | | - kvfree(org_mount_opt.s_qf_names[j]); |
|---|
| 2118 | + kfree(org_mount_opt.s_qf_names[j]); |
|---|
| 1783 | 2119 | return -ENOMEM; |
|---|
| 1784 | 2120 | } |
|---|
| 1785 | 2121 | } else { |
|---|
| .. | .. |
|---|
| 1797 | 2133 | clear_sbi_flag(sbi, SBI_NEED_SB_WRITE); |
|---|
| 1798 | 2134 | } |
|---|
| 1799 | 2135 | |
|---|
| 1800 | | - default_options(sbi); |
|---|
| 2136 | + default_options(sbi, true); |
|---|
| 1801 | 2137 | |
|---|
| 1802 | 2138 | /* parse mount options */ |
|---|
| 1803 | 2139 | err = parse_options(sb, data, true); |
|---|
| .. | .. |
|---|
| 1812 | 2148 | */ |
|---|
| 1813 | 2149 | if (f2fs_readonly(sb) && (*flags & SB_RDONLY)) |
|---|
| 1814 | 2150 | goto skip; |
|---|
| 2151 | + |
|---|
| 2152 | + if (f2fs_sb_has_readonly(sbi) && !(*flags & SB_RDONLY)) { |
|---|
| 2153 | + err = -EROFS; |
|---|
| 2154 | + goto restore_opts; |
|---|
| 2155 | + } |
|---|
| 1815 | 2156 | |
|---|
| 1816 | 2157 | #ifdef CONFIG_QUOTA |
|---|
| 1817 | 2158 | if (!f2fs_readonly(sb) && (*flags & SB_RDONLY)) { |
|---|
| .. | .. |
|---|
| 1830 | 2171 | } |
|---|
| 1831 | 2172 | } |
|---|
| 1832 | 2173 | #endif |
|---|
| 2174 | + /* disallow enable atgc dynamically */ |
|---|
| 2175 | + if (no_atgc == !!test_opt(sbi, ATGC)) { |
|---|
| 2176 | + err = -EINVAL; |
|---|
| 2177 | + f2fs_warn(sbi, "switch atgc option is not allowed"); |
|---|
| 2178 | + goto restore_opts; |
|---|
| 2179 | + } |
|---|
| 2180 | + |
|---|
| 1833 | 2181 | /* disallow enable/disable extent_cache dynamically */ |
|---|
| 1834 | | - if (no_extent_cache == !!test_opt(sbi, EXTENT_CACHE)) { |
|---|
| 2182 | + if (no_read_extent_cache == !!test_opt(sbi, READ_EXTENT_CACHE)) { |
|---|
| 1835 | 2183 | err = -EINVAL; |
|---|
| 1836 | 2184 | f2fs_warn(sbi, "switch extent_cache option is not allowed"); |
|---|
| 2185 | + goto restore_opts; |
|---|
| 2186 | + } |
|---|
| 2187 | + /* disallow enable/disable age extent_cache dynamically */ |
|---|
| 2188 | + if (no_age_extent_cache == !!test_opt(sbi, AGE_EXTENT_CACHE)) { |
|---|
| 2189 | + err = -EINVAL; |
|---|
| 2190 | + f2fs_warn(sbi, "switch age_extent_cache option is not allowed"); |
|---|
| 1837 | 2191 | goto restore_opts; |
|---|
| 1838 | 2192 | } |
|---|
| 1839 | 2193 | |
|---|
| 1840 | 2194 | if (no_io_align == !!F2FS_IO_ALIGNED(sbi)) { |
|---|
| 1841 | 2195 | err = -EINVAL; |
|---|
| 1842 | 2196 | f2fs_warn(sbi, "switch io_bits option is not allowed"); |
|---|
| 2197 | + goto restore_opts; |
|---|
| 2198 | + } |
|---|
| 2199 | + |
|---|
| 2200 | + if (no_compress_cache == !!test_opt(sbi, COMPRESS_CACHE)) { |
|---|
| 2201 | + err = -EINVAL; |
|---|
| 2202 | + f2fs_warn(sbi, "switch compress_cache option is not allowed"); |
|---|
| 1843 | 2203 | goto restore_opts; |
|---|
| 1844 | 2204 | } |
|---|
| 1845 | 2205 | |
|---|
| .. | .. |
|---|
| 1855 | 2215 | * option. Also sync the filesystem. |
|---|
| 1856 | 2216 | */ |
|---|
| 1857 | 2217 | if ((*flags & SB_RDONLY) || |
|---|
| 1858 | | - F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_OFF) { |
|---|
| 2218 | + (F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_OFF && |
|---|
| 2219 | + !test_opt(sbi, GC_MERGE))) { |
|---|
| 1859 | 2220 | if (sbi->gc_thread) { |
|---|
| 1860 | 2221 | f2fs_stop_gc_thread(sbi); |
|---|
| 1861 | 2222 | need_restart_gc = true; |
|---|
| .. | .. |
|---|
| 1869 | 2230 | |
|---|
| 1870 | 2231 | if (*flags & SB_RDONLY || |
|---|
| 1871 | 2232 | F2FS_OPTION(sbi).whint_mode != org_mount_opt.whint_mode) { |
|---|
| 1872 | | - writeback_inodes_sb(sb, WB_REASON_SYNC); |
|---|
| 1873 | 2233 | sync_inodes_sb(sb); |
|---|
| 1874 | 2234 | |
|---|
| 1875 | 2235 | set_sbi_flag(sbi, SBI_IS_DIRTY); |
|---|
| .. | .. |
|---|
| 1878 | 2238 | clear_sbi_flag(sbi, SBI_IS_CLOSE); |
|---|
| 1879 | 2239 | } |
|---|
| 1880 | 2240 | |
|---|
| 1881 | | - if (checkpoint_changed) { |
|---|
| 1882 | | - if (test_opt(sbi, DISABLE_CHECKPOINT)) { |
|---|
| 1883 | | - err = f2fs_disable_checkpoint(sbi); |
|---|
| 1884 | | - if (err) |
|---|
| 1885 | | - goto restore_gc; |
|---|
| 1886 | | - } else { |
|---|
| 1887 | | - f2fs_enable_checkpoint(sbi); |
|---|
| 2241 | + if ((*flags & SB_RDONLY) || test_opt(sbi, DISABLE_CHECKPOINT) || |
|---|
| 2242 | + !test_opt(sbi, MERGE_CHECKPOINT)) { |
|---|
| 2243 | + f2fs_stop_ckpt_thread(sbi); |
|---|
| 2244 | + need_restart_ckpt = true; |
|---|
| 2245 | + } else { |
|---|
| 2246 | + /* Flush if the prevous checkpoint, if exists. */ |
|---|
| 2247 | + f2fs_flush_ckpt_thread(sbi); |
|---|
| 2248 | + |
|---|
| 2249 | + err = f2fs_start_ckpt_thread(sbi); |
|---|
| 2250 | + if (err) { |
|---|
| 2251 | + f2fs_err(sbi, |
|---|
| 2252 | + "Failed to start F2FS issue_checkpoint_thread (%d)", |
|---|
| 2253 | + err); |
|---|
| 2254 | + goto restore_gc; |
|---|
| 1888 | 2255 | } |
|---|
| 2256 | + need_stop_ckpt = true; |
|---|
| 1889 | 2257 | } |
|---|
| 1890 | 2258 | |
|---|
| 1891 | 2259 | /* |
|---|
| .. | .. |
|---|
| 1895 | 2263 | if ((*flags & SB_RDONLY) || !test_opt(sbi, FLUSH_MERGE)) { |
|---|
| 1896 | 2264 | clear_opt(sbi, FLUSH_MERGE); |
|---|
| 1897 | 2265 | f2fs_destroy_flush_cmd_control(sbi, false); |
|---|
| 2266 | + need_restart_flush = true; |
|---|
| 1898 | 2267 | } else { |
|---|
| 1899 | 2268 | err = f2fs_create_flush_cmd_control(sbi); |
|---|
| 1900 | 2269 | if (err) |
|---|
| 1901 | | - goto restore_gc; |
|---|
| 2270 | + goto restore_ckpt; |
|---|
| 2271 | + need_stop_flush = true; |
|---|
| 1902 | 2272 | } |
|---|
| 2273 | + |
|---|
| 2274 | + if (checkpoint_changed) { |
|---|
| 2275 | + if (test_opt(sbi, DISABLE_CHECKPOINT)) { |
|---|
| 2276 | + err = f2fs_disable_checkpoint(sbi); |
|---|
| 2277 | + if (err) |
|---|
| 2278 | + goto restore_flush; |
|---|
| 2279 | + } else { |
|---|
| 2280 | + f2fs_enable_checkpoint(sbi); |
|---|
| 2281 | + } |
|---|
| 2282 | + } |
|---|
| 2283 | + |
|---|
| 1903 | 2284 | skip: |
|---|
| 1904 | 2285 | #ifdef CONFIG_QUOTA |
|---|
| 1905 | 2286 | /* Release old quota file names */ |
|---|
| 1906 | 2287 | for (i = 0; i < MAXQUOTAS; i++) |
|---|
| 1907 | | - kvfree(org_mount_opt.s_qf_names[i]); |
|---|
| 2288 | + kfree(org_mount_opt.s_qf_names[i]); |
|---|
| 1908 | 2289 | #endif |
|---|
| 1909 | 2290 | /* Update the POSIXACL Flag */ |
|---|
| 1910 | 2291 | sb->s_flags = (sb->s_flags & ~SB_POSIXACL) | |
|---|
| .. | .. |
|---|
| 1914 | 2295 | adjust_unusable_cap_perc(sbi); |
|---|
| 1915 | 2296 | *flags = (*flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME); |
|---|
| 1916 | 2297 | return 0; |
|---|
| 2298 | +restore_flush: |
|---|
| 2299 | + if (need_restart_flush) { |
|---|
| 2300 | + if (f2fs_create_flush_cmd_control(sbi)) |
|---|
| 2301 | + f2fs_warn(sbi, "background flush thread has stopped"); |
|---|
| 2302 | + } else if (need_stop_flush) { |
|---|
| 2303 | + clear_opt(sbi, FLUSH_MERGE); |
|---|
| 2304 | + f2fs_destroy_flush_cmd_control(sbi, false); |
|---|
| 2305 | + } |
|---|
| 2306 | +restore_ckpt: |
|---|
| 2307 | + if (need_restart_ckpt) { |
|---|
| 2308 | + if (f2fs_start_ckpt_thread(sbi)) |
|---|
| 2309 | + f2fs_warn(sbi, "background ckpt thread has stopped"); |
|---|
| 2310 | + } else if (need_stop_ckpt) { |
|---|
| 2311 | + f2fs_stop_ckpt_thread(sbi); |
|---|
| 2312 | + } |
|---|
| 1917 | 2313 | restore_gc: |
|---|
| 1918 | 2314 | if (need_restart_gc) { |
|---|
| 1919 | 2315 | if (f2fs_start_gc_thread(sbi)) |
|---|
| .. | .. |
|---|
| 1925 | 2321 | #ifdef CONFIG_QUOTA |
|---|
| 1926 | 2322 | F2FS_OPTION(sbi).s_jquota_fmt = org_mount_opt.s_jquota_fmt; |
|---|
| 1927 | 2323 | for (i = 0; i < MAXQUOTAS; i++) { |
|---|
| 1928 | | - kvfree(F2FS_OPTION(sbi).s_qf_names[i]); |
|---|
| 2324 | + kfree(F2FS_OPTION(sbi).s_qf_names[i]); |
|---|
| 1929 | 2325 | F2FS_OPTION(sbi).s_qf_names[i] = org_mount_opt.s_qf_names[i]; |
|---|
| 1930 | 2326 | } |
|---|
| 1931 | 2327 | #endif |
|---|
| .. | .. |
|---|
| 1947 | 2343 | size_t toread; |
|---|
| 1948 | 2344 | loff_t i_size = i_size_read(inode); |
|---|
| 1949 | 2345 | struct page *page; |
|---|
| 1950 | | - char *kaddr; |
|---|
| 1951 | 2346 | |
|---|
| 1952 | 2347 | if (off > i_size) |
|---|
| 1953 | 2348 | return 0; |
|---|
| .. | .. |
|---|
| 1981 | 2376 | return -EIO; |
|---|
| 1982 | 2377 | } |
|---|
| 1983 | 2378 | |
|---|
| 1984 | | - kaddr = kmap_atomic(page); |
|---|
| 1985 | | - memcpy(data, kaddr + offset, tocopy); |
|---|
| 1986 | | - kunmap_atomic(kaddr); |
|---|
| 2379 | + memcpy_from_page(data, page, offset, tocopy); |
|---|
| 1987 | 2380 | f2fs_put_page(page, 1); |
|---|
| 1988 | 2381 | |
|---|
| 1989 | 2382 | offset = 0; |
|---|
| .. | .. |
|---|
| 2005 | 2398 | size_t towrite = len; |
|---|
| 2006 | 2399 | struct page *page; |
|---|
| 2007 | 2400 | void *fsdata = NULL; |
|---|
| 2008 | | - char *kaddr; |
|---|
| 2009 | 2401 | int err = 0; |
|---|
| 2010 | 2402 | int tocopy; |
|---|
| 2011 | 2403 | |
|---|
| .. | .. |
|---|
| 2025 | 2417 | break; |
|---|
| 2026 | 2418 | } |
|---|
| 2027 | 2419 | |
|---|
| 2028 | | - kaddr = kmap_atomic(page); |
|---|
| 2029 | | - memcpy(kaddr + offset, data, tocopy); |
|---|
| 2030 | | - kunmap_atomic(kaddr); |
|---|
| 2031 | | - flush_dcache_page(page); |
|---|
| 2420 | + memcpy_to_page(page, offset, data, tocopy); |
|---|
| 2032 | 2421 | |
|---|
| 2033 | 2422 | a_ops->write_end(NULL, mapping, off, tocopy, tocopy, |
|---|
| 2034 | 2423 | page, fsdata); |
|---|
| .. | .. |
|---|
| 2116 | 2505 | |
|---|
| 2117 | 2506 | /* Don't account quota for quota files to avoid recursion */ |
|---|
| 2118 | 2507 | qf_inode->i_flags |= S_NOQUOTA; |
|---|
| 2119 | | - err = dquot_enable(qf_inode, type, format_id, flags); |
|---|
| 2508 | + err = dquot_load_quota_inode(qf_inode, type, format_id, flags); |
|---|
| 2120 | 2509 | iput(qf_inode); |
|---|
| 2121 | 2510 | return err; |
|---|
| 2122 | 2511 | } |
|---|
| .. | .. |
|---|
| 2159 | 2548 | return 0; |
|---|
| 2160 | 2549 | } |
|---|
| 2161 | 2550 | |
|---|
| 2551 | +static int f2fs_quota_sync_file(struct f2fs_sb_info *sbi, int type) |
|---|
| 2552 | +{ |
|---|
| 2553 | + struct quota_info *dqopt = sb_dqopt(sbi->sb); |
|---|
| 2554 | + struct address_space *mapping = dqopt->files[type]->i_mapping; |
|---|
| 2555 | + int ret = 0; |
|---|
| 2556 | + |
|---|
| 2557 | + ret = dquot_writeback_dquots(sbi->sb, type); |
|---|
| 2558 | + if (ret) |
|---|
| 2559 | + goto out; |
|---|
| 2560 | + |
|---|
| 2561 | + ret = filemap_fdatawrite(mapping); |
|---|
| 2562 | + if (ret) |
|---|
| 2563 | + goto out; |
|---|
| 2564 | + |
|---|
| 2565 | + /* if we are using journalled quota */ |
|---|
| 2566 | + if (is_journalled_quota(sbi)) |
|---|
| 2567 | + goto out; |
|---|
| 2568 | + |
|---|
| 2569 | + ret = filemap_fdatawait(mapping); |
|---|
| 2570 | + |
|---|
| 2571 | + truncate_inode_pages(&dqopt->files[type]->i_data, 0); |
|---|
| 2572 | +out: |
|---|
| 2573 | + if (ret) |
|---|
| 2574 | + set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); |
|---|
| 2575 | + return ret; |
|---|
| 2576 | +} |
|---|
| 2577 | + |
|---|
| 2162 | 2578 | int f2fs_quota_sync(struct super_block *sb, int type) |
|---|
| 2163 | 2579 | { |
|---|
| 2164 | 2580 | struct f2fs_sb_info *sbi = F2FS_SB(sb); |
|---|
| 2165 | 2581 | struct quota_info *dqopt = sb_dqopt(sb); |
|---|
| 2166 | 2582 | int cnt; |
|---|
| 2167 | | - int ret; |
|---|
| 2168 | | - |
|---|
| 2169 | | - /* |
|---|
| 2170 | | - * do_quotactl |
|---|
| 2171 | | - * f2fs_quota_sync |
|---|
| 2172 | | - * down_read(quota_sem) |
|---|
| 2173 | | - * dquot_writeback_dquots() |
|---|
| 2174 | | - * f2fs_dquot_commit |
|---|
| 2175 | | - * block_operation |
|---|
| 2176 | | - * down_read(quota_sem) |
|---|
| 2177 | | - */ |
|---|
| 2178 | | - f2fs_lock_op(sbi); |
|---|
| 2179 | | - |
|---|
| 2180 | | - down_read(&sbi->quota_sem); |
|---|
| 2181 | | - ret = dquot_writeback_dquots(sb, type); |
|---|
| 2182 | | - if (ret) |
|---|
| 2183 | | - goto out; |
|---|
| 2583 | + int ret = 0; |
|---|
| 2184 | 2584 | |
|---|
| 2185 | 2585 | /* |
|---|
| 2186 | 2586 | * Now when everything is written we can discard the pagecache so |
|---|
| 2187 | 2587 | * that userspace sees the changes. |
|---|
| 2188 | 2588 | */ |
|---|
| 2189 | 2589 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
|---|
| 2190 | | - struct address_space *mapping; |
|---|
| 2191 | 2590 | |
|---|
| 2192 | 2591 | if (type != -1 && cnt != type) |
|---|
| 2193 | 2592 | continue; |
|---|
| 2593 | + |
|---|
| 2194 | 2594 | if (!sb_has_quota_active(sb, cnt)) |
|---|
| 2195 | 2595 | continue; |
|---|
| 2196 | 2596 | |
|---|
| 2197 | | - mapping = dqopt->files[cnt]->i_mapping; |
|---|
| 2597 | + if (!f2fs_sb_has_quota_ino(sbi)) |
|---|
| 2598 | + inode_lock(dqopt->files[cnt]); |
|---|
| 2198 | 2599 | |
|---|
| 2199 | | - ret = filemap_fdatawrite(mapping); |
|---|
| 2600 | + /* |
|---|
| 2601 | + * do_quotactl |
|---|
| 2602 | + * f2fs_quota_sync |
|---|
| 2603 | + * f2fs_down_read(quota_sem) |
|---|
| 2604 | + * dquot_writeback_dquots() |
|---|
| 2605 | + * f2fs_dquot_commit |
|---|
| 2606 | + * block_operation |
|---|
| 2607 | + * f2fs_down_read(quota_sem) |
|---|
| 2608 | + */ |
|---|
| 2609 | + f2fs_lock_op(sbi); |
|---|
| 2610 | + f2fs_down_read(&sbi->quota_sem); |
|---|
| 2611 | + |
|---|
| 2612 | + ret = f2fs_quota_sync_file(sbi, cnt); |
|---|
| 2613 | + |
|---|
| 2614 | + f2fs_up_read(&sbi->quota_sem); |
|---|
| 2615 | + f2fs_unlock_op(sbi); |
|---|
| 2616 | + |
|---|
| 2617 | + if (!f2fs_sb_has_quota_ino(sbi)) |
|---|
| 2618 | + inode_unlock(dqopt->files[cnt]); |
|---|
| 2619 | + |
|---|
| 2200 | 2620 | if (ret) |
|---|
| 2201 | | - goto out; |
|---|
| 2202 | | - |
|---|
| 2203 | | - /* if we are using journalled quota */ |
|---|
| 2204 | | - if (is_journalled_quota(sbi)) |
|---|
| 2205 | | - continue; |
|---|
| 2206 | | - |
|---|
| 2207 | | - ret = filemap_fdatawait(mapping); |
|---|
| 2208 | | - if (ret) |
|---|
| 2209 | | - set_sbi_flag(F2FS_SB(sb), SBI_QUOTA_NEED_REPAIR); |
|---|
| 2210 | | - |
|---|
| 2211 | | - inode_lock(dqopt->files[cnt]); |
|---|
| 2212 | | - truncate_inode_pages(&dqopt->files[cnt]->i_data, 0); |
|---|
| 2213 | | - inode_unlock(dqopt->files[cnt]); |
|---|
| 2621 | + break; |
|---|
| 2214 | 2622 | } |
|---|
| 2215 | | -out: |
|---|
| 2216 | | - if (ret) |
|---|
| 2217 | | - set_sbi_flag(F2FS_SB(sb), SBI_QUOTA_NEED_REPAIR); |
|---|
| 2218 | | - up_read(&sbi->quota_sem); |
|---|
| 2219 | | - f2fs_unlock_op(sbi); |
|---|
| 2220 | 2623 | return ret; |
|---|
| 2221 | 2624 | } |
|---|
| 2222 | 2625 | |
|---|
| .. | .. |
|---|
| 2334 | 2737 | struct f2fs_sb_info *sbi = F2FS_SB(dquot->dq_sb); |
|---|
| 2335 | 2738 | int ret; |
|---|
| 2336 | 2739 | |
|---|
| 2337 | | - down_read_nested(&sbi->quota_sem, SINGLE_DEPTH_NESTING); |
|---|
| 2740 | + f2fs_down_read_nested(&sbi->quota_sem, SINGLE_DEPTH_NESTING); |
|---|
| 2338 | 2741 | ret = dquot_commit(dquot); |
|---|
| 2339 | 2742 | if (ret < 0) |
|---|
| 2340 | 2743 | set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); |
|---|
| 2341 | | - up_read(&sbi->quota_sem); |
|---|
| 2744 | + f2fs_up_read(&sbi->quota_sem); |
|---|
| 2342 | 2745 | return ret; |
|---|
| 2343 | 2746 | } |
|---|
| 2344 | 2747 | |
|---|
| .. | .. |
|---|
| 2347 | 2750 | struct f2fs_sb_info *sbi = F2FS_SB(dquot->dq_sb); |
|---|
| 2348 | 2751 | int ret; |
|---|
| 2349 | 2752 | |
|---|
| 2350 | | - down_read(&sbi->quota_sem); |
|---|
| 2753 | + f2fs_down_read(&sbi->quota_sem); |
|---|
| 2351 | 2754 | ret = dquot_acquire(dquot); |
|---|
| 2352 | 2755 | if (ret < 0) |
|---|
| 2353 | 2756 | set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); |
|---|
| 2354 | | - up_read(&sbi->quota_sem); |
|---|
| 2757 | + f2fs_up_read(&sbi->quota_sem); |
|---|
| 2355 | 2758 | return ret; |
|---|
| 2356 | 2759 | } |
|---|
| 2357 | 2760 | |
|---|
| .. | .. |
|---|
| 2430 | 2833 | |
|---|
| 2431 | 2834 | static const struct super_operations f2fs_sops = { |
|---|
| 2432 | 2835 | .alloc_inode = f2fs_alloc_inode, |
|---|
| 2836 | + .free_inode = f2fs_free_inode, |
|---|
| 2433 | 2837 | .drop_inode = f2fs_drop_inode, |
|---|
| 2434 | | - .destroy_inode = f2fs_destroy_inode, |
|---|
| 2435 | 2838 | .write_inode = f2fs_write_inode, |
|---|
| 2436 | 2839 | .dirty_inode = f2fs_dirty_inode, |
|---|
| 2437 | 2840 | .show_options = f2fs_show_options, |
|---|
| .. | .. |
|---|
| 2477 | 2880 | ctx, len, fs_data, XATTR_CREATE); |
|---|
| 2478 | 2881 | } |
|---|
| 2479 | 2882 | |
|---|
| 2480 | | -static const union fscrypt_context * |
|---|
| 2481 | | -f2fs_get_dummy_context(struct super_block *sb) |
|---|
| 2883 | +static const union fscrypt_policy *f2fs_get_dummy_policy(struct super_block *sb) |
|---|
| 2482 | 2884 | { |
|---|
| 2483 | | - return F2FS_OPTION(F2FS_SB(sb)).dummy_enc_ctx.ctx; |
|---|
| 2885 | + return F2FS_OPTION(F2FS_SB(sb)).dummy_enc_policy.policy; |
|---|
| 2484 | 2886 | } |
|---|
| 2485 | 2887 | |
|---|
| 2486 | 2888 | static bool f2fs_has_stable_inodes(struct super_block *sb) |
|---|
| .. | .. |
|---|
| 2493 | 2895 | { |
|---|
| 2494 | 2896 | *ino_bits_ret = 8 * sizeof(nid_t); |
|---|
| 2495 | 2897 | *lblk_bits_ret = 8 * sizeof(block_t); |
|---|
| 2496 | | -} |
|---|
| 2497 | | - |
|---|
| 2498 | | -static bool f2fs_inline_crypt_enabled(struct super_block *sb) |
|---|
| 2499 | | -{ |
|---|
| 2500 | | - return F2FS_OPTION(F2FS_SB(sb)).inlinecrypt; |
|---|
| 2501 | 2898 | } |
|---|
| 2502 | 2899 | |
|---|
| 2503 | 2900 | static int f2fs_get_num_devices(struct super_block *sb) |
|---|
| .. | .. |
|---|
| 2523 | 2920 | .key_prefix = "f2fs:", |
|---|
| 2524 | 2921 | .get_context = f2fs_get_context, |
|---|
| 2525 | 2922 | .set_context = f2fs_set_context, |
|---|
| 2526 | | - .get_dummy_context = f2fs_get_dummy_context, |
|---|
| 2923 | + .get_dummy_policy = f2fs_get_dummy_policy, |
|---|
| 2527 | 2924 | .empty_dir = f2fs_empty_dir, |
|---|
| 2528 | 2925 | .max_namelen = F2FS_NAME_LEN, |
|---|
| 2529 | 2926 | .has_stable_inodes = f2fs_has_stable_inodes, |
|---|
| 2530 | 2927 | .get_ino_and_lblk_bits = f2fs_get_ino_and_lblk_bits, |
|---|
| 2531 | | - .inline_crypt_enabled = f2fs_inline_crypt_enabled, |
|---|
| 2532 | 2928 | .get_num_devices = f2fs_get_num_devices, |
|---|
| 2533 | 2929 | .get_devices = f2fs_get_devices, |
|---|
| 2534 | 2930 | }; |
|---|
| .. | .. |
|---|
| 2579 | 2975 | .get_parent = f2fs_get_parent, |
|---|
| 2580 | 2976 | }; |
|---|
| 2581 | 2977 | |
|---|
| 2582 | | -static loff_t max_file_blocks(void) |
|---|
| 2978 | +loff_t max_file_blocks(struct inode *inode) |
|---|
| 2583 | 2979 | { |
|---|
| 2584 | 2980 | loff_t result = 0; |
|---|
| 2585 | | - loff_t leaf_count = DEF_ADDRS_PER_BLOCK; |
|---|
| 2981 | + loff_t leaf_count; |
|---|
| 2586 | 2982 | |
|---|
| 2587 | 2983 | /* |
|---|
| 2588 | 2984 | * note: previously, result is equal to (DEF_ADDRS_PER_INODE - |
|---|
| .. | .. |
|---|
| 2590 | 2986 | * space in inode.i_addr, it will be more safe to reassign |
|---|
| 2591 | 2987 | * result as zero. |
|---|
| 2592 | 2988 | */ |
|---|
| 2989 | + |
|---|
| 2990 | + if (inode && f2fs_compressed_file(inode)) |
|---|
| 2991 | + leaf_count = ADDRS_PER_BLOCK(inode); |
|---|
| 2992 | + else |
|---|
| 2993 | + leaf_count = DEF_ADDRS_PER_BLOCK; |
|---|
| 2593 | 2994 | |
|---|
| 2594 | 2995 | /* two direct node blocks */ |
|---|
| 2595 | 2996 | result += (leaf_count * 2); |
|---|
| .. | .. |
|---|
| 2681 | 3082 | } |
|---|
| 2682 | 3083 | |
|---|
| 2683 | 3084 | if (main_end_blkaddr > seg_end_blkaddr) { |
|---|
| 2684 | | - f2fs_info(sbi, "Wrong MAIN_AREA boundary, start(%u) end(%u) block(%u)", |
|---|
| 2685 | | - main_blkaddr, |
|---|
| 2686 | | - segment0_blkaddr + |
|---|
| 2687 | | - (segment_count << log_blocks_per_seg), |
|---|
| 3085 | + f2fs_info(sbi, "Wrong MAIN_AREA boundary, start(%u) end(%llu) block(%u)", |
|---|
| 3086 | + main_blkaddr, seg_end_blkaddr, |
|---|
| 2688 | 3087 | segment_count_main << log_blocks_per_seg); |
|---|
| 2689 | 3088 | return true; |
|---|
| 2690 | 3089 | } else if (main_end_blkaddr < seg_end_blkaddr) { |
|---|
| .. | .. |
|---|
| 2702 | 3101 | err = __f2fs_commit_super(bh, NULL); |
|---|
| 2703 | 3102 | res = err ? "failed" : "done"; |
|---|
| 2704 | 3103 | } |
|---|
| 2705 | | - f2fs_info(sbi, "Fix alignment : %s, start(%u) end(%u) block(%u)", |
|---|
| 2706 | | - res, main_blkaddr, |
|---|
| 2707 | | - segment0_blkaddr + |
|---|
| 2708 | | - (segment_count << log_blocks_per_seg), |
|---|
| 3104 | + f2fs_info(sbi, "Fix alignment : %s, start(%u) end(%llu) block(%u)", |
|---|
| 3105 | + res, main_blkaddr, seg_end_blkaddr, |
|---|
| 2709 | 3106 | segment_count_main << log_blocks_per_seg); |
|---|
| 2710 | 3107 | if (err) |
|---|
| 2711 | 3108 | return true; |
|---|
| .. | .. |
|---|
| 2716 | 3113 | static int sanity_check_raw_super(struct f2fs_sb_info *sbi, |
|---|
| 2717 | 3114 | struct buffer_head *bh) |
|---|
| 2718 | 3115 | { |
|---|
| 2719 | | - block_t segment_count, segs_per_sec, secs_per_zone; |
|---|
| 3116 | + block_t segment_count, segs_per_sec, secs_per_zone, segment_count_main; |
|---|
| 2720 | 3117 | block_t total_sections, blocks_per_seg; |
|---|
| 2721 | 3118 | struct f2fs_super_block *raw_super = (struct f2fs_super_block *) |
|---|
| 2722 | 3119 | (bh->b_data + F2FS_SUPER_OFFSET); |
|---|
| 2723 | | - unsigned int blocksize; |
|---|
| 2724 | 3120 | size_t crc_offset = 0; |
|---|
| 2725 | 3121 | __u32 crc = 0; |
|---|
| 2726 | 3122 | |
|---|
| .. | .. |
|---|
| 2746 | 3142 | } |
|---|
| 2747 | 3143 | } |
|---|
| 2748 | 3144 | |
|---|
| 2749 | | - /* Currently, support only 4KB page cache size */ |
|---|
| 2750 | | - if (F2FS_BLKSIZE != PAGE_SIZE) { |
|---|
| 2751 | | - f2fs_info(sbi, "Invalid page_cache_size (%lu), supports only 4KB", |
|---|
| 2752 | | - PAGE_SIZE); |
|---|
| 2753 | | - return -EFSCORRUPTED; |
|---|
| 2754 | | - } |
|---|
| 2755 | | - |
|---|
| 2756 | 3145 | /* Currently, support only 4KB block size */ |
|---|
| 2757 | | - blocksize = 1 << le32_to_cpu(raw_super->log_blocksize); |
|---|
| 2758 | | - if (blocksize != F2FS_BLKSIZE) { |
|---|
| 2759 | | - f2fs_info(sbi, "Invalid blocksize (%u), supports only 4KB", |
|---|
| 2760 | | - blocksize); |
|---|
| 3146 | + if (le32_to_cpu(raw_super->log_blocksize) != F2FS_BLKSIZE_BITS) { |
|---|
| 3147 | + f2fs_info(sbi, "Invalid log_blocksize (%u), supports only %u", |
|---|
| 3148 | + le32_to_cpu(raw_super->log_blocksize), |
|---|
| 3149 | + F2FS_BLKSIZE_BITS); |
|---|
| 2761 | 3150 | return -EFSCORRUPTED; |
|---|
| 2762 | 3151 | } |
|---|
| 2763 | 3152 | |
|---|
| .. | .. |
|---|
| 2787 | 3176 | } |
|---|
| 2788 | 3177 | |
|---|
| 2789 | 3178 | segment_count = le32_to_cpu(raw_super->segment_count); |
|---|
| 3179 | + segment_count_main = le32_to_cpu(raw_super->segment_count_main); |
|---|
| 2790 | 3180 | segs_per_sec = le32_to_cpu(raw_super->segs_per_sec); |
|---|
| 2791 | 3181 | secs_per_zone = le32_to_cpu(raw_super->secs_per_zone); |
|---|
| 2792 | 3182 | total_sections = le32_to_cpu(raw_super->section_count); |
|---|
| .. | .. |
|---|
| 2800 | 3190 | return -EFSCORRUPTED; |
|---|
| 2801 | 3191 | } |
|---|
| 2802 | 3192 | |
|---|
| 2803 | | - if (total_sections > segment_count || |
|---|
| 2804 | | - total_sections < F2FS_MIN_SEGMENTS || |
|---|
| 3193 | + if (total_sections > segment_count_main || total_sections < 1 || |
|---|
| 2805 | 3194 | segs_per_sec > segment_count || !segs_per_sec) { |
|---|
| 2806 | 3195 | f2fs_info(sbi, "Invalid segment/section count (%u, %u x %u)", |
|---|
| 2807 | 3196 | segment_count, total_sections, segs_per_sec); |
|---|
| 3197 | + return -EFSCORRUPTED; |
|---|
| 3198 | + } |
|---|
| 3199 | + |
|---|
| 3200 | + if (segment_count_main != total_sections * segs_per_sec) { |
|---|
| 3201 | + f2fs_info(sbi, "Invalid segment/section count (%u != %u * %u)", |
|---|
| 3202 | + segment_count_main, total_sections, segs_per_sec); |
|---|
| 2808 | 3203 | return -EFSCORRUPTED; |
|---|
| 2809 | 3204 | } |
|---|
| 2810 | 3205 | |
|---|
| .. | .. |
|---|
| 2833 | 3228 | segment_count, dev_seg_count); |
|---|
| 2834 | 3229 | return -EFSCORRUPTED; |
|---|
| 2835 | 3230 | } |
|---|
| 3231 | + } else { |
|---|
| 3232 | + if (__F2FS_HAS_FEATURE(raw_super, F2FS_FEATURE_BLKZONED) && |
|---|
| 3233 | + !bdev_is_zoned(sbi->sb->s_bdev)) { |
|---|
| 3234 | + f2fs_info(sbi, "Zoned block device path is missing"); |
|---|
| 3235 | + return -EFSCORRUPTED; |
|---|
| 3236 | + } |
|---|
| 2836 | 3237 | } |
|---|
| 2837 | 3238 | |
|---|
| 2838 | 3239 | if (secs_per_zone > total_sections || !secs_per_zone) { |
|---|
| .. | .. |
|---|
| 2851 | 3252 | return -EFSCORRUPTED; |
|---|
| 2852 | 3253 | } |
|---|
| 2853 | 3254 | |
|---|
| 2854 | | - if (le32_to_cpu(raw_super->cp_payload) > |
|---|
| 2855 | | - (blocks_per_seg - F2FS_CP_PACKS)) { |
|---|
| 2856 | | - f2fs_info(sbi, "Insane cp_payload (%u > %u)", |
|---|
| 3255 | + if (le32_to_cpu(raw_super->cp_payload) >= |
|---|
| 3256 | + (blocks_per_seg - F2FS_CP_PACKS - |
|---|
| 3257 | + NR_CURSEG_PERSIST_TYPE)) { |
|---|
| 3258 | + f2fs_info(sbi, "Insane cp_payload (%u >= %u)", |
|---|
| 2857 | 3259 | le32_to_cpu(raw_super->cp_payload), |
|---|
| 2858 | | - blocks_per_seg - F2FS_CP_PACKS); |
|---|
| 3260 | + blocks_per_seg - F2FS_CP_PACKS - |
|---|
| 3261 | + NR_CURSEG_PERSIST_TYPE); |
|---|
| 2859 | 3262 | return -EFSCORRUPTED; |
|---|
| 2860 | 3263 | } |
|---|
| 2861 | 3264 | |
|---|
| .. | .. |
|---|
| 2891 | 3294 | unsigned int cp_pack_start_sum, cp_payload; |
|---|
| 2892 | 3295 | block_t user_block_count, valid_user_blocks; |
|---|
| 2893 | 3296 | block_t avail_node_count, valid_node_count; |
|---|
| 3297 | + unsigned int nat_blocks, nat_bits_bytes, nat_bits_blocks; |
|---|
| 2894 | 3298 | int i, j; |
|---|
| 2895 | 3299 | |
|---|
| 2896 | 3300 | total = le32_to_cpu(raw_super->segment_count); |
|---|
| .. | .. |
|---|
| 2908 | 3312 | ovp_segments = le32_to_cpu(ckpt->overprov_segment_count); |
|---|
| 2909 | 3313 | reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count); |
|---|
| 2910 | 3314 | |
|---|
| 2911 | | - if (unlikely(fsmeta < F2FS_MIN_SEGMENTS || |
|---|
| 3315 | + if (!f2fs_sb_has_readonly(sbi) && |
|---|
| 3316 | + unlikely(fsmeta < F2FS_MIN_META_SEGMENTS || |
|---|
| 2912 | 3317 | ovp_segments == 0 || reserved_segments == 0)) { |
|---|
| 2913 | 3318 | f2fs_err(sbi, "Wrong layout: check mkfs.f2fs version"); |
|---|
| 2914 | 3319 | return 1; |
|---|
| 2915 | 3320 | } |
|---|
| 2916 | | - |
|---|
| 2917 | 3321 | user_block_count = le64_to_cpu(ckpt->user_block_count); |
|---|
| 2918 | | - segment_count_main = le32_to_cpu(raw_super->segment_count_main); |
|---|
| 3322 | + segment_count_main = le32_to_cpu(raw_super->segment_count_main) + |
|---|
| 3323 | + (f2fs_sb_has_readonly(sbi) ? 1 : 0); |
|---|
| 2919 | 3324 | log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg); |
|---|
| 2920 | 3325 | if (!user_block_count || user_block_count >= |
|---|
| 2921 | 3326 | segment_count_main << log_blocks_per_seg) { |
|---|
| .. | .. |
|---|
| 2946 | 3351 | if (le32_to_cpu(ckpt->cur_node_segno[i]) >= main_segs || |
|---|
| 2947 | 3352 | le16_to_cpu(ckpt->cur_node_blkoff[i]) >= blocks_per_seg) |
|---|
| 2948 | 3353 | return 1; |
|---|
| 3354 | + |
|---|
| 3355 | + if (f2fs_sb_has_readonly(sbi)) |
|---|
| 3356 | + goto check_data; |
|---|
| 3357 | + |
|---|
| 2949 | 3358 | for (j = i + 1; j < NR_CURSEG_NODE_TYPE; j++) { |
|---|
| 2950 | 3359 | if (le32_to_cpu(ckpt->cur_node_segno[i]) == |
|---|
| 2951 | 3360 | le32_to_cpu(ckpt->cur_node_segno[j])) { |
|---|
| .. | .. |
|---|
| 2956 | 3365 | } |
|---|
| 2957 | 3366 | } |
|---|
| 2958 | 3367 | } |
|---|
| 3368 | +check_data: |
|---|
| 2959 | 3369 | for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) { |
|---|
| 2960 | 3370 | if (le32_to_cpu(ckpt->cur_data_segno[i]) >= main_segs || |
|---|
| 2961 | 3371 | le16_to_cpu(ckpt->cur_data_blkoff[i]) >= blocks_per_seg) |
|---|
| 2962 | 3372 | return 1; |
|---|
| 3373 | + |
|---|
| 3374 | + if (f2fs_sb_has_readonly(sbi)) |
|---|
| 3375 | + goto skip_cross; |
|---|
| 3376 | + |
|---|
| 2963 | 3377 | for (j = i + 1; j < NR_CURSEG_DATA_TYPE; j++) { |
|---|
| 2964 | 3378 | if (le32_to_cpu(ckpt->cur_data_segno[i]) == |
|---|
| 2965 | 3379 | le32_to_cpu(ckpt->cur_data_segno[j])) { |
|---|
| .. | .. |
|---|
| 2981 | 3395 | } |
|---|
| 2982 | 3396 | } |
|---|
| 2983 | 3397 | } |
|---|
| 2984 | | - |
|---|
| 3398 | +skip_cross: |
|---|
| 2985 | 3399 | sit_bitmap_size = le32_to_cpu(ckpt->sit_ver_bitmap_bytesize); |
|---|
| 2986 | 3400 | nat_bitmap_size = le32_to_cpu(ckpt->nat_ver_bitmap_bytesize); |
|---|
| 2987 | 3401 | |
|---|
| .. | .. |
|---|
| 2996 | 3410 | cp_payload = __cp_payload(sbi); |
|---|
| 2997 | 3411 | if (cp_pack_start_sum < cp_payload + 1 || |
|---|
| 2998 | 3412 | cp_pack_start_sum > blocks_per_seg - 1 - |
|---|
| 2999 | | - NR_CURSEG_TYPE) { |
|---|
| 3413 | + NR_CURSEG_PERSIST_TYPE) { |
|---|
| 3000 | 3414 | f2fs_err(sbi, "Wrong cp_pack_start_sum: %u", |
|---|
| 3001 | 3415 | cp_pack_start_sum); |
|---|
| 3002 | 3416 | return 1; |
|---|
| .. | .. |
|---|
| 3008 | 3422 | "please run fsck v1.13.0 or higher to repair, chksum_offset: %u, " |
|---|
| 3009 | 3423 | "fixed with patch: \"f2fs-tools: relocate chksum_offset for large_nat_bitmap feature\"", |
|---|
| 3010 | 3424 | le32_to_cpu(ckpt->checksum_offset)); |
|---|
| 3425 | + return 1; |
|---|
| 3426 | + } |
|---|
| 3427 | + |
|---|
| 3428 | + nat_blocks = nat_segs << log_blocks_per_seg; |
|---|
| 3429 | + nat_bits_bytes = nat_blocks / BITS_PER_BYTE; |
|---|
| 3430 | + nat_bits_blocks = F2FS_BLK_ALIGN((nat_bits_bytes << 1) + 8); |
|---|
| 3431 | + if (__is_set_ckpt_flags(ckpt, CP_NAT_BITS_FLAG) && |
|---|
| 3432 | + (cp_payload + F2FS_CP_PACKS + |
|---|
| 3433 | + NR_CURSEG_PERSIST_TYPE + nat_bits_blocks >= blocks_per_seg)) { |
|---|
| 3434 | + f2fs_warn(sbi, "Insane cp_payload: %u, nat_bits_blocks: %u)", |
|---|
| 3435 | + cp_payload, nat_bits_blocks); |
|---|
| 3011 | 3436 | return 1; |
|---|
| 3012 | 3437 | } |
|---|
| 3013 | 3438 | |
|---|
| .. | .. |
|---|
| 3035 | 3460 | sbi->total_node_count = |
|---|
| 3036 | 3461 | (le32_to_cpu(raw_super->segment_count_nat) / 2) |
|---|
| 3037 | 3462 | * sbi->blocks_per_seg * NAT_ENTRY_PER_BLOCK; |
|---|
| 3038 | | - sbi->root_ino_num = le32_to_cpu(raw_super->root_ino); |
|---|
| 3039 | | - sbi->node_ino_num = le32_to_cpu(raw_super->node_ino); |
|---|
| 3040 | | - sbi->meta_ino_num = le32_to_cpu(raw_super->meta_ino); |
|---|
| 3463 | + F2FS_ROOT_INO(sbi) = le32_to_cpu(raw_super->root_ino); |
|---|
| 3464 | + F2FS_NODE_INO(sbi) = le32_to_cpu(raw_super->node_ino); |
|---|
| 3465 | + F2FS_META_INO(sbi) = le32_to_cpu(raw_super->meta_ino); |
|---|
| 3041 | 3466 | sbi->cur_victim_sec = NULL_SECNO; |
|---|
| 3042 | 3467 | sbi->next_victim_seg[BG_GC] = NULL_SEGNO; |
|---|
| 3043 | 3468 | sbi->next_victim_seg[FG_GC] = NULL_SEGNO; |
|---|
| .. | .. |
|---|
| 3062 | 3487 | |
|---|
| 3063 | 3488 | INIT_LIST_HEAD(&sbi->s_list); |
|---|
| 3064 | 3489 | mutex_init(&sbi->umount_mutex); |
|---|
| 3065 | | - init_rwsem(&sbi->io_order_lock); |
|---|
| 3490 | + init_f2fs_rwsem(&sbi->io_order_lock); |
|---|
| 3066 | 3491 | spin_lock_init(&sbi->cp_lock); |
|---|
| 3067 | 3492 | |
|---|
| 3068 | 3493 | sbi->dirty_device = 0; |
|---|
| 3069 | 3494 | spin_lock_init(&sbi->dev_lock); |
|---|
| 3070 | 3495 | |
|---|
| 3071 | | - init_rwsem(&sbi->sb_lock); |
|---|
| 3072 | | - init_rwsem(&sbi->pin_sem); |
|---|
| 3496 | + init_f2fs_rwsem(&sbi->sb_lock); |
|---|
| 3497 | + init_f2fs_rwsem(&sbi->pin_sem); |
|---|
| 3073 | 3498 | } |
|---|
| 3074 | 3499 | |
|---|
| 3075 | 3500 | static int init_percpu_info(struct f2fs_sb_info *sbi) |
|---|
| .. | .. |
|---|
| 3089 | 3514 | } |
|---|
| 3090 | 3515 | |
|---|
| 3091 | 3516 | #ifdef CONFIG_BLK_DEV_ZONED |
|---|
| 3517 | + |
|---|
| 3518 | +struct f2fs_report_zones_args { |
|---|
| 3519 | + struct f2fs_sb_info *sbi; |
|---|
| 3520 | + struct f2fs_dev_info *dev; |
|---|
| 3521 | +}; |
|---|
| 3522 | + |
|---|
| 3523 | +static int f2fs_report_zone_cb(struct blk_zone *zone, unsigned int idx, |
|---|
| 3524 | + void *data) |
|---|
| 3525 | +{ |
|---|
| 3526 | + struct f2fs_report_zones_args *rz_args = data; |
|---|
| 3527 | + block_t unusable_blocks = (zone->len - zone->capacity) >> |
|---|
| 3528 | + F2FS_LOG_SECTORS_PER_BLOCK; |
|---|
| 3529 | + |
|---|
| 3530 | + if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) |
|---|
| 3531 | + return 0; |
|---|
| 3532 | + |
|---|
| 3533 | + set_bit(idx, rz_args->dev->blkz_seq); |
|---|
| 3534 | + if (!rz_args->sbi->unusable_blocks_per_sec) { |
|---|
| 3535 | + rz_args->sbi->unusable_blocks_per_sec = unusable_blocks; |
|---|
| 3536 | + return 0; |
|---|
| 3537 | + } |
|---|
| 3538 | + if (rz_args->sbi->unusable_blocks_per_sec != unusable_blocks) { |
|---|
| 3539 | + f2fs_err(rz_args->sbi, "F2FS supports single zone capacity\n"); |
|---|
| 3540 | + return -EINVAL; |
|---|
| 3541 | + } |
|---|
| 3542 | + return 0; |
|---|
| 3543 | +} |
|---|
| 3544 | + |
|---|
| 3092 | 3545 | static int init_blkz_info(struct f2fs_sb_info *sbi, int devi) |
|---|
| 3093 | 3546 | { |
|---|
| 3094 | 3547 | struct block_device *bdev = FDEV(devi).bdev; |
|---|
| 3095 | 3548 | sector_t nr_sectors = bdev->bd_part->nr_sects; |
|---|
| 3096 | | - sector_t sector = 0; |
|---|
| 3097 | | - struct blk_zone *zones; |
|---|
| 3098 | | - unsigned int i, nr_zones; |
|---|
| 3099 | | - unsigned int n = 0; |
|---|
| 3100 | | - int err = -EIO; |
|---|
| 3549 | + struct f2fs_report_zones_args rep_zone_arg; |
|---|
| 3550 | + int ret; |
|---|
| 3101 | 3551 | |
|---|
| 3102 | 3552 | if (!f2fs_sb_has_blkzoned(sbi)) |
|---|
| 3103 | 3553 | return 0; |
|---|
| .. | .. |
|---|
| 3122 | 3572 | if (!FDEV(devi).blkz_seq) |
|---|
| 3123 | 3573 | return -ENOMEM; |
|---|
| 3124 | 3574 | |
|---|
| 3125 | | -#define F2FS_REPORT_NR_ZONES 4096 |
|---|
| 3575 | + rep_zone_arg.sbi = sbi; |
|---|
| 3576 | + rep_zone_arg.dev = &FDEV(devi); |
|---|
| 3126 | 3577 | |
|---|
| 3127 | | - zones = f2fs_kzalloc(sbi, |
|---|
| 3128 | | - array_size(F2FS_REPORT_NR_ZONES, |
|---|
| 3129 | | - sizeof(struct blk_zone)), |
|---|
| 3130 | | - GFP_KERNEL); |
|---|
| 3131 | | - if (!zones) |
|---|
| 3132 | | - return -ENOMEM; |
|---|
| 3133 | | - |
|---|
| 3134 | | - /* Get block zones type */ |
|---|
| 3135 | | - while (zones && sector < nr_sectors) { |
|---|
| 3136 | | - |
|---|
| 3137 | | - nr_zones = F2FS_REPORT_NR_ZONES; |
|---|
| 3138 | | - err = blkdev_report_zones(bdev, sector, |
|---|
| 3139 | | - zones, &nr_zones, |
|---|
| 3140 | | - GFP_KERNEL); |
|---|
| 3141 | | - if (err) |
|---|
| 3142 | | - break; |
|---|
| 3143 | | - if (!nr_zones) { |
|---|
| 3144 | | - err = -EIO; |
|---|
| 3145 | | - break; |
|---|
| 3146 | | - } |
|---|
| 3147 | | - |
|---|
| 3148 | | - for (i = 0; i < nr_zones; i++) { |
|---|
| 3149 | | - if (zones[i].type != BLK_ZONE_TYPE_CONVENTIONAL) |
|---|
| 3150 | | - set_bit(n, FDEV(devi).blkz_seq); |
|---|
| 3151 | | - sector += zones[i].len; |
|---|
| 3152 | | - n++; |
|---|
| 3153 | | - } |
|---|
| 3154 | | - } |
|---|
| 3155 | | - |
|---|
| 3156 | | - kvfree(zones); |
|---|
| 3157 | | - |
|---|
| 3158 | | - return err; |
|---|
| 3578 | + ret = blkdev_report_zones(bdev, 0, BLK_ALL_ZONES, f2fs_report_zone_cb, |
|---|
| 3579 | + &rep_zone_arg); |
|---|
| 3580 | + if (ret < 0) |
|---|
| 3581 | + return ret; |
|---|
| 3582 | + return 0; |
|---|
| 3159 | 3583 | } |
|---|
| 3160 | 3584 | #endif |
|---|
| 3161 | 3585 | |
|---|
| .. | .. |
|---|
| 3210 | 3634 | |
|---|
| 3211 | 3635 | /* No valid superblock */ |
|---|
| 3212 | 3636 | if (!*raw_super) |
|---|
| 3213 | | - kvfree(super); |
|---|
| 3637 | + kfree(super); |
|---|
| 3214 | 3638 | else |
|---|
| 3215 | 3639 | err = 0; |
|---|
| 3216 | 3640 | |
|---|
| .. | .. |
|---|
| 3254 | 3678 | err = __f2fs_commit_super(bh, F2FS_RAW_SUPER(sbi)); |
|---|
| 3255 | 3679 | brelse(bh); |
|---|
| 3256 | 3680 | return err; |
|---|
| 3681 | +} |
|---|
| 3682 | + |
|---|
| 3683 | +void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason) |
|---|
| 3684 | +{ |
|---|
| 3685 | + struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); |
|---|
| 3686 | + int err; |
|---|
| 3687 | + |
|---|
| 3688 | + f2fs_bug_on(sbi, reason >= MAX_STOP_REASON); |
|---|
| 3689 | + |
|---|
| 3690 | + f2fs_down_write(&sbi->sb_lock); |
|---|
| 3691 | + |
|---|
| 3692 | + if (raw_super->s_stop_reason[reason] < ((1 << BITS_PER_BYTE) - 1)) |
|---|
| 3693 | + raw_super->s_stop_reason[reason]++; |
|---|
| 3694 | + |
|---|
| 3695 | + err = f2fs_commit_super(sbi, false); |
|---|
| 3696 | + if (err) |
|---|
| 3697 | + f2fs_err(sbi, "f2fs_commit_super fails to record reason:%u err:%d", |
|---|
| 3698 | + reason, err); |
|---|
| 3699 | + |
|---|
| 3700 | + f2fs_up_write(&sbi->sb_lock); |
|---|
| 3257 | 3701 | } |
|---|
| 3258 | 3702 | |
|---|
| 3259 | 3703 | static int f2fs_scan_devices(struct f2fs_sb_info *sbi) |
|---|
| .. | .. |
|---|
| 3319 | 3763 | #ifdef CONFIG_BLK_DEV_ZONED |
|---|
| 3320 | 3764 | if (bdev_zoned_model(FDEV(i).bdev) == BLK_ZONED_HM && |
|---|
| 3321 | 3765 | !f2fs_sb_has_blkzoned(sbi)) { |
|---|
| 3322 | | - f2fs_err(sbi, "Zoned block device feature not enabled\n"); |
|---|
| 3766 | + f2fs_err(sbi, "Zoned block device feature not enabled"); |
|---|
| 3323 | 3767 | return -EINVAL; |
|---|
| 3324 | 3768 | } |
|---|
| 3325 | 3769 | if (bdev_zoned_model(FDEV(i).bdev) != BLK_ZONED_NONE) { |
|---|
| .. | .. |
|---|
| 3396 | 3840 | if (sm_i->main_segments <= SMALL_VOLUME_SEGMENTS) { |
|---|
| 3397 | 3841 | F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_REUSE; |
|---|
| 3398 | 3842 | sm_i->dcc_info->discard_granularity = 1; |
|---|
| 3399 | | - sm_i->ipu_policy = 1 << F2FS_IPU_FORCE; |
|---|
| 3843 | + sm_i->ipu_policy = 1 << F2FS_IPU_FORCE | |
|---|
| 3844 | + 1 << F2FS_IPU_HONOR_OPU_WRITE; |
|---|
| 3400 | 3845 | } |
|---|
| 3401 | 3846 | |
|---|
| 3402 | 3847 | sbi->readdir_ra = 1; |
|---|
| .. | .. |
|---|
| 3455 | 3900 | sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid, |
|---|
| 3456 | 3901 | sizeof(raw_super->uuid)); |
|---|
| 3457 | 3902 | |
|---|
| 3458 | | - /* |
|---|
| 3459 | | - * The BLKZONED feature indicates that the drive was formatted with |
|---|
| 3460 | | - * zone alignment optimization. This is optional for host-aware |
|---|
| 3461 | | - * devices, but mandatory for host-managed zoned block devices. |
|---|
| 3462 | | - */ |
|---|
| 3463 | | -#ifndef CONFIG_BLK_DEV_ZONED |
|---|
| 3464 | | - if (f2fs_sb_has_blkzoned(sbi)) { |
|---|
| 3465 | | - f2fs_err(sbi, "Zoned block device support is not enabled"); |
|---|
| 3466 | | - err = -EOPNOTSUPP; |
|---|
| 3467 | | - goto free_sb_buf; |
|---|
| 3468 | | - } |
|---|
| 3469 | | -#endif |
|---|
| 3470 | | - default_options(sbi); |
|---|
| 3903 | + default_options(sbi, false); |
|---|
| 3471 | 3904 | /* parse mount options */ |
|---|
| 3472 | 3905 | options = kstrdup((const char *)data, GFP_KERNEL); |
|---|
| 3473 | 3906 | if (data && !options) { |
|---|
| .. | .. |
|---|
| 3479 | 3912 | if (err) |
|---|
| 3480 | 3913 | goto free_options; |
|---|
| 3481 | 3914 | |
|---|
| 3482 | | - sbi->max_file_blocks = max_file_blocks(); |
|---|
| 3483 | | - sb->s_maxbytes = sbi->max_file_blocks << |
|---|
| 3915 | + sb->s_maxbytes = max_file_blocks(NULL) << |
|---|
| 3484 | 3916 | le32_to_cpu(raw_super->log_blocksize); |
|---|
| 3485 | 3917 | sb->s_max_links = F2FS_LINK_MAX; |
|---|
| 3486 | 3918 | |
|---|
| .. | .. |
|---|
| 3519 | 3951 | |
|---|
| 3520 | 3952 | /* init f2fs-specific super block info */ |
|---|
| 3521 | 3953 | sbi->valid_super_block = valid_super_block; |
|---|
| 3522 | | - init_rwsem(&sbi->gc_lock); |
|---|
| 3954 | + init_f2fs_rwsem(&sbi->gc_lock); |
|---|
| 3523 | 3955 | mutex_init(&sbi->writepages); |
|---|
| 3524 | | - mutex_init(&sbi->cp_mutex); |
|---|
| 3525 | | - init_rwsem(&sbi->node_write); |
|---|
| 3526 | | - init_rwsem(&sbi->node_change); |
|---|
| 3956 | + init_f2fs_rwsem(&sbi->cp_global_sem); |
|---|
| 3957 | + init_f2fs_rwsem(&sbi->node_write); |
|---|
| 3958 | + init_f2fs_rwsem(&sbi->node_change); |
|---|
| 3527 | 3959 | |
|---|
| 3528 | 3960 | /* disallow all the data/node/meta page writes */ |
|---|
| 3529 | 3961 | set_sbi_flag(sbi, SBI_POR_DOING); |
|---|
| .. | .. |
|---|
| 3535 | 3967 | sbi->iostat_period_ms = DEFAULT_IOSTAT_PERIOD_MS; |
|---|
| 3536 | 3968 | |
|---|
| 3537 | 3969 | for (i = 0; i < NR_PAGE_TYPE; i++) { |
|---|
| 3538 | | - int n = (i == META) ? 1: NR_TEMP_TYPE; |
|---|
| 3970 | + int n = (i == META) ? 1 : NR_TEMP_TYPE; |
|---|
| 3539 | 3971 | int j; |
|---|
| 3540 | 3972 | |
|---|
| 3541 | 3973 | sbi->write_io[i] = |
|---|
| .. | .. |
|---|
| 3549 | 3981 | } |
|---|
| 3550 | 3982 | |
|---|
| 3551 | 3983 | for (j = HOT; j < n; j++) { |
|---|
| 3552 | | - init_rwsem(&sbi->write_io[i][j].io_rwsem); |
|---|
| 3984 | + init_f2fs_rwsem(&sbi->write_io[i][j].io_rwsem); |
|---|
| 3553 | 3985 | sbi->write_io[i][j].sbi = sbi; |
|---|
| 3554 | 3986 | sbi->write_io[i][j].bio = NULL; |
|---|
| 3555 | 3987 | spin_lock_init(&sbi->write_io[i][j].io_lock); |
|---|
| 3556 | 3988 | INIT_LIST_HEAD(&sbi->write_io[i][j].io_list); |
|---|
| 3557 | 3989 | INIT_LIST_HEAD(&sbi->write_io[i][j].bio_list); |
|---|
| 3558 | | - init_rwsem(&sbi->write_io[i][j].bio_list_lock); |
|---|
| 3990 | + init_f2fs_rwsem(&sbi->write_io[i][j].bio_list_lock); |
|---|
| 3559 | 3991 | } |
|---|
| 3560 | 3992 | } |
|---|
| 3561 | 3993 | |
|---|
| 3562 | | - init_rwsem(&sbi->cp_rwsem); |
|---|
| 3563 | | - init_rwsem(&sbi->quota_sem); |
|---|
| 3994 | + init_f2fs_rwsem(&sbi->cp_rwsem); |
|---|
| 3995 | + init_f2fs_rwsem(&sbi->quota_sem); |
|---|
| 3564 | 3996 | init_waitqueue_head(&sbi->cp_wait); |
|---|
| 3565 | 3997 | init_sb_info(sbi); |
|---|
| 3566 | 3998 | |
|---|
| .. | .. |
|---|
| 3581 | 4013 | err = f2fs_init_xattr_caches(sbi); |
|---|
| 3582 | 4014 | if (err) |
|---|
| 3583 | 4015 | goto free_io_dummy; |
|---|
| 4016 | + err = f2fs_init_page_array_cache(sbi); |
|---|
| 4017 | + if (err) |
|---|
| 4018 | + goto free_xattr_cache; |
|---|
| 3584 | 4019 | |
|---|
| 3585 | 4020 | /* get an inode for meta space */ |
|---|
| 3586 | 4021 | sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi)); |
|---|
| 3587 | 4022 | if (IS_ERR(sbi->meta_inode)) { |
|---|
| 3588 | 4023 | f2fs_err(sbi, "Failed to read F2FS meta data inode"); |
|---|
| 3589 | 4024 | err = PTR_ERR(sbi->meta_inode); |
|---|
| 3590 | | - goto free_xattr_cache; |
|---|
| 4025 | + goto free_page_array_cache; |
|---|
| 3591 | 4026 | } |
|---|
| 3592 | 4027 | |
|---|
| 3593 | 4028 | err = f2fs_get_valid_checkpoint(sbi); |
|---|
| .. | .. |
|---|
| 3644 | 4079 | |
|---|
| 3645 | 4080 | f2fs_init_fsync_node_info(sbi); |
|---|
| 3646 | 4081 | |
|---|
| 4082 | + /* setup checkpoint request control and start checkpoint issue thread */ |
|---|
| 4083 | + f2fs_init_ckpt_req_control(sbi); |
|---|
| 4084 | + if (!f2fs_readonly(sb) && !test_opt(sbi, DISABLE_CHECKPOINT) && |
|---|
| 4085 | + test_opt(sbi, MERGE_CHECKPOINT)) { |
|---|
| 4086 | + err = f2fs_start_ckpt_thread(sbi); |
|---|
| 4087 | + if (err) { |
|---|
| 4088 | + f2fs_err(sbi, |
|---|
| 4089 | + "Failed to start F2FS issue_checkpoint_thread (%d)", |
|---|
| 4090 | + err); |
|---|
| 4091 | + goto stop_ckpt_thread; |
|---|
| 4092 | + } |
|---|
| 4093 | + } |
|---|
| 4094 | + |
|---|
| 3647 | 4095 | /* setup f2fs internal modules */ |
|---|
| 3648 | 4096 | err = f2fs_build_segment_manager(sbi); |
|---|
| 3649 | 4097 | if (err) { |
|---|
| .. | .. |
|---|
| 3658 | 4106 | goto free_nm; |
|---|
| 3659 | 4107 | } |
|---|
| 3660 | 4108 | |
|---|
| 4109 | + err = adjust_reserved_segment(sbi); |
|---|
| 4110 | + if (err) |
|---|
| 4111 | + goto free_nm; |
|---|
| 4112 | + |
|---|
| 3661 | 4113 | /* For write statistics */ |
|---|
| 3662 | | - if (sb->s_bdev->bd_part) |
|---|
| 3663 | | - sbi->sectors_written_start = |
|---|
| 3664 | | - (u64)part_stat_read(sb->s_bdev->bd_part, |
|---|
| 3665 | | - sectors[STAT_WRITE]); |
|---|
| 4114 | + sbi->sectors_written_start = f2fs_get_sectors_written(sbi); |
|---|
| 3666 | 4115 | |
|---|
| 3667 | 4116 | /* Read accumulated write IO statistics if exists */ |
|---|
| 3668 | 4117 | seg_i = CURSEG_I(sbi, CURSEG_HOT_NODE); |
|---|
| .. | .. |
|---|
| 3706 | 4155 | goto free_node_inode; |
|---|
| 3707 | 4156 | } |
|---|
| 3708 | 4157 | |
|---|
| 3709 | | - err = f2fs_register_sysfs(sbi); |
|---|
| 4158 | + err = f2fs_init_compress_inode(sbi); |
|---|
| 3710 | 4159 | if (err) |
|---|
| 3711 | 4160 | goto free_root_inode; |
|---|
| 4161 | + |
|---|
| 4162 | + err = f2fs_register_sysfs(sbi); |
|---|
| 4163 | + if (err) |
|---|
| 4164 | + goto free_compress_inode; |
|---|
| 3712 | 4165 | |
|---|
| 3713 | 4166 | #ifdef CONFIG_QUOTA |
|---|
| 3714 | 4167 | /* Enable quota usage during mount */ |
|---|
| .. | .. |
|---|
| 3735 | 4188 | */ |
|---|
| 3736 | 4189 | if (f2fs_hw_is_readonly(sbi)) { |
|---|
| 3737 | 4190 | if (!is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { |
|---|
| 3738 | | - err = -EROFS; |
|---|
| 3739 | | - f2fs_err(sbi, "Need to recover fsync data, but write access unavailable"); |
|---|
| 3740 | | - goto free_meta; |
|---|
| 4191 | + err = f2fs_recover_fsync_data(sbi, true); |
|---|
| 4192 | + if (err > 0) { |
|---|
| 4193 | + err = -EROFS; |
|---|
| 4194 | + f2fs_err(sbi, "Need to recover fsync data, but " |
|---|
| 4195 | + "write access unavailable, please try " |
|---|
| 4196 | + "mount w/ disable_roll_forward or norecovery"); |
|---|
| 4197 | + } |
|---|
| 4198 | + if (err < 0) |
|---|
| 4199 | + goto free_meta; |
|---|
| 3741 | 4200 | } |
|---|
| 3742 | 4201 | f2fs_info(sbi, "write access unavailable, skipping recovery"); |
|---|
| 3743 | 4202 | goto reset_checkpoint; |
|---|
| .. | .. |
|---|
| 3767 | 4226 | goto free_meta; |
|---|
| 3768 | 4227 | } |
|---|
| 3769 | 4228 | } |
|---|
| 4229 | + |
|---|
| 4230 | + /* |
|---|
| 4231 | + * If the f2fs is not readonly and fsync data recovery succeeds, |
|---|
| 4232 | + * check zoned block devices' write pointer consistency. |
|---|
| 4233 | + */ |
|---|
| 4234 | + if (!err && !f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) { |
|---|
| 4235 | + err = f2fs_check_write_pointer(sbi); |
|---|
| 4236 | + if (err) |
|---|
| 4237 | + goto free_meta; |
|---|
| 4238 | + } |
|---|
| 4239 | + |
|---|
| 3770 | 4240 | reset_checkpoint: |
|---|
| 4241 | + f2fs_init_inmem_curseg(sbi); |
|---|
| 4242 | + |
|---|
| 3771 | 4243 | /* f2fs_recover_fsync_data() cleared this already */ |
|---|
| 3772 | 4244 | clear_sbi_flag(sbi, SBI_POR_DOING); |
|---|
| 3773 | 4245 | |
|---|
| .. | .. |
|---|
| 3783 | 4255 | * If filesystem is not mounted as read-only then |
|---|
| 3784 | 4256 | * do start the gc_thread. |
|---|
| 3785 | 4257 | */ |
|---|
| 3786 | | - if (F2FS_OPTION(sbi).bggc_mode != BGGC_MODE_OFF && !f2fs_readonly(sb)) { |
|---|
| 4258 | + if ((F2FS_OPTION(sbi).bggc_mode != BGGC_MODE_OFF || |
|---|
| 4259 | + test_opt(sbi, GC_MERGE)) && !f2fs_readonly(sb)) { |
|---|
| 3787 | 4260 | /* After POR, we can run background GC thread.*/ |
|---|
| 3788 | 4261 | err = f2fs_start_gc_thread(sbi); |
|---|
| 3789 | 4262 | if (err) |
|---|
| .. | .. |
|---|
| 3830 | 4303 | /* evict some inodes being cached by GC */ |
|---|
| 3831 | 4304 | evict_inodes(sb); |
|---|
| 3832 | 4305 | f2fs_unregister_sysfs(sbi); |
|---|
| 4306 | +free_compress_inode: |
|---|
| 4307 | + f2fs_destroy_compress_inode(sbi); |
|---|
| 3833 | 4308 | free_root_inode: |
|---|
| 3834 | 4309 | dput(sb->s_root); |
|---|
| 3835 | 4310 | sb->s_root = NULL; |
|---|
| .. | .. |
|---|
| 3841 | 4316 | free_stats: |
|---|
| 3842 | 4317 | f2fs_destroy_stats(sbi); |
|---|
| 3843 | 4318 | free_nm: |
|---|
| 4319 | + /* stop discard thread before destroying node manager */ |
|---|
| 4320 | + f2fs_stop_discard_thread(sbi); |
|---|
| 3844 | 4321 | f2fs_destroy_node_manager(sbi); |
|---|
| 3845 | 4322 | free_sm: |
|---|
| 3846 | 4323 | f2fs_destroy_segment_manager(sbi); |
|---|
| 3847 | 4324 | f2fs_destroy_post_read_wq(sbi); |
|---|
| 4325 | +stop_ckpt_thread: |
|---|
| 4326 | + f2fs_stop_ckpt_thread(sbi); |
|---|
| 3848 | 4327 | free_devices: |
|---|
| 3849 | 4328 | destroy_device_list(sbi); |
|---|
| 3850 | 4329 | kvfree(sbi->ckpt); |
|---|
| .. | .. |
|---|
| 3852 | 4331 | make_bad_inode(sbi->meta_inode); |
|---|
| 3853 | 4332 | iput(sbi->meta_inode); |
|---|
| 3854 | 4333 | sbi->meta_inode = NULL; |
|---|
| 4334 | +free_page_array_cache: |
|---|
| 4335 | + f2fs_destroy_page_array_cache(sbi); |
|---|
| 3855 | 4336 | free_xattr_cache: |
|---|
| 3856 | 4337 | f2fs_destroy_xattr_caches(sbi); |
|---|
| 3857 | 4338 | free_io_dummy: |
|---|
| .. | .. |
|---|
| 3864 | 4345 | |
|---|
| 3865 | 4346 | #ifdef CONFIG_UNICODE |
|---|
| 3866 | 4347 | utf8_unload(sb->s_encoding); |
|---|
| 4348 | + sb->s_encoding = NULL; |
|---|
| 3867 | 4349 | #endif |
|---|
| 3868 | 4350 | free_options: |
|---|
| 3869 | 4351 | #ifdef CONFIG_QUOTA |
|---|
| 3870 | 4352 | for (i = 0; i < MAXQUOTAS; i++) |
|---|
| 3871 | | - kvfree(F2FS_OPTION(sbi).s_qf_names[i]); |
|---|
| 4353 | + kfree(F2FS_OPTION(sbi).s_qf_names[i]); |
|---|
| 3872 | 4354 | #endif |
|---|
| 3873 | | - fscrypt_free_dummy_context(&F2FS_OPTION(sbi).dummy_enc_ctx); |
|---|
| 4355 | + fscrypt_free_dummy_policy(&F2FS_OPTION(sbi).dummy_enc_policy); |
|---|
| 3874 | 4356 | kvfree(options); |
|---|
| 3875 | 4357 | free_sb_buf: |
|---|
| 3876 | | - kvfree(raw_super); |
|---|
| 4358 | + kfree(raw_super); |
|---|
| 3877 | 4359 | free_sbi: |
|---|
| 3878 | 4360 | if (sbi->s_chksum_driver) |
|---|
| 3879 | 4361 | crypto_free_shash(sbi->s_chksum_driver); |
|---|
| 3880 | | - kvfree(sbi); |
|---|
| 4362 | + kfree(sbi); |
|---|
| 3881 | 4363 | |
|---|
| 3882 | 4364 | /* give only one another chance */ |
|---|
| 3883 | 4365 | if (retry_cnt > 0 && skip_recovery) { |
|---|
| .. | .. |
|---|
| 3902 | 4384 | set_sbi_flag(sbi, SBI_IS_CLOSE); |
|---|
| 3903 | 4385 | f2fs_stop_gc_thread(sbi); |
|---|
| 3904 | 4386 | f2fs_stop_discard_thread(sbi); |
|---|
| 4387 | + |
|---|
| 4388 | +#ifdef CONFIG_F2FS_FS_COMPRESSION |
|---|
| 4389 | + /* |
|---|
| 4390 | + * latter evict_inode() can bypass checking and invalidating |
|---|
| 4391 | + * compress inode cache. |
|---|
| 4392 | + */ |
|---|
| 4393 | + if (test_opt(sbi, COMPRESS_CACHE)) |
|---|
| 4394 | + truncate_inode_pages_final(COMPRESS_MAPPING(sbi)); |
|---|
| 4395 | +#endif |
|---|
| 3905 | 4396 | |
|---|
| 3906 | 4397 | if (is_sbi_flag_set(sbi, SBI_IS_DIRTY) || |
|---|
| 3907 | 4398 | !is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { |
|---|
| .. | .. |
|---|
| 3956 | 4447 | return -EINVAL; |
|---|
| 3957 | 4448 | } |
|---|
| 3958 | 4449 | |
|---|
| 3959 | | - f2fs_build_trace_ios(); |
|---|
| 3960 | | - |
|---|
| 3961 | 4450 | err = init_inodecache(); |
|---|
| 3962 | 4451 | if (err) |
|---|
| 3963 | 4452 | goto fail; |
|---|
| .. | .. |
|---|
| 3970 | 4459 | err = f2fs_create_checkpoint_caches(); |
|---|
| 3971 | 4460 | if (err) |
|---|
| 3972 | 4461 | goto free_segment_manager_caches; |
|---|
| 3973 | | - err = f2fs_create_extent_cache(); |
|---|
| 4462 | + err = f2fs_create_recovery_cache(); |
|---|
| 3974 | 4463 | if (err) |
|---|
| 3975 | 4464 | goto free_checkpoint_caches; |
|---|
| 3976 | | - err = f2fs_init_sysfs(); |
|---|
| 4465 | + err = f2fs_create_extent_cache(); |
|---|
| 4466 | + if (err) |
|---|
| 4467 | + goto free_recovery_cache; |
|---|
| 4468 | + err = f2fs_create_garbage_collection_cache(); |
|---|
| 3977 | 4469 | if (err) |
|---|
| 3978 | 4470 | goto free_extent_cache; |
|---|
| 4471 | + err = f2fs_init_sysfs(); |
|---|
| 4472 | + if (err) |
|---|
| 4473 | + goto free_garbage_collection_cache; |
|---|
| 3979 | 4474 | err = register_shrinker(&f2fs_shrinker_info); |
|---|
| 3980 | 4475 | if (err) |
|---|
| 3981 | 4476 | goto free_sysfs; |
|---|
| .. | .. |
|---|
| 3995 | 4490 | err = f2fs_init_compress_mempool(); |
|---|
| 3996 | 4491 | if (err) |
|---|
| 3997 | 4492 | goto free_bioset; |
|---|
| 4493 | + err = f2fs_init_compress_cache(); |
|---|
| 4494 | + if (err) |
|---|
| 4495 | + goto free_compress_mempool; |
|---|
| 4496 | + err = f2fs_create_casefold_cache(); |
|---|
| 4497 | + if (err) |
|---|
| 4498 | + goto free_compress_cache; |
|---|
| 3998 | 4499 | return 0; |
|---|
| 4500 | +free_compress_cache: |
|---|
| 4501 | + f2fs_destroy_compress_cache(); |
|---|
| 4502 | +free_compress_mempool: |
|---|
| 4503 | + f2fs_destroy_compress_mempool(); |
|---|
| 3999 | 4504 | free_bioset: |
|---|
| 4000 | 4505 | f2fs_destroy_bioset(); |
|---|
| 4001 | 4506 | free_bio_enrty_cache: |
|---|
| .. | .. |
|---|
| 4009 | 4514 | unregister_shrinker(&f2fs_shrinker_info); |
|---|
| 4010 | 4515 | free_sysfs: |
|---|
| 4011 | 4516 | f2fs_exit_sysfs(); |
|---|
| 4517 | +free_garbage_collection_cache: |
|---|
| 4518 | + f2fs_destroy_garbage_collection_cache(); |
|---|
| 4012 | 4519 | free_extent_cache: |
|---|
| 4013 | 4520 | f2fs_destroy_extent_cache(); |
|---|
| 4521 | +free_recovery_cache: |
|---|
| 4522 | + f2fs_destroy_recovery_cache(); |
|---|
| 4014 | 4523 | free_checkpoint_caches: |
|---|
| 4015 | 4524 | f2fs_destroy_checkpoint_caches(); |
|---|
| 4016 | 4525 | free_segment_manager_caches: |
|---|
| .. | .. |
|---|
| 4025 | 4534 | |
|---|
| 4026 | 4535 | static void __exit exit_f2fs_fs(void) |
|---|
| 4027 | 4536 | { |
|---|
| 4537 | + f2fs_destroy_casefold_cache(); |
|---|
| 4538 | + f2fs_destroy_compress_cache(); |
|---|
| 4028 | 4539 | f2fs_destroy_compress_mempool(); |
|---|
| 4029 | 4540 | f2fs_destroy_bioset(); |
|---|
| 4030 | 4541 | f2fs_destroy_bio_entry_cache(); |
|---|
| .. | .. |
|---|
| 4033 | 4544 | unregister_filesystem(&f2fs_fs_type); |
|---|
| 4034 | 4545 | unregister_shrinker(&f2fs_shrinker_info); |
|---|
| 4035 | 4546 | f2fs_exit_sysfs(); |
|---|
| 4547 | + f2fs_destroy_garbage_collection_cache(); |
|---|
| 4036 | 4548 | f2fs_destroy_extent_cache(); |
|---|
| 4549 | + f2fs_destroy_recovery_cache(); |
|---|
| 4037 | 4550 | f2fs_destroy_checkpoint_caches(); |
|---|
| 4038 | 4551 | f2fs_destroy_segment_manager_caches(); |
|---|
| 4039 | 4552 | f2fs_destroy_node_manager_caches(); |
|---|
| 4040 | 4553 | destroy_inodecache(); |
|---|
| 4041 | | - f2fs_destroy_trace_ios(); |
|---|
| 4042 | 4554 | } |
|---|
| 4043 | 4555 | |
|---|
| 4044 | 4556 | module_init(init_f2fs_fs) |
|---|
| .. | .. |
|---|
| 4047 | 4559 | MODULE_AUTHOR("Samsung Electronics's Praesto Team"); |
|---|
| 4048 | 4560 | MODULE_DESCRIPTION("Flash Friendly File System"); |
|---|
| 4049 | 4561 | MODULE_LICENSE("GPL"); |
|---|
| 4562 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 4050 | 4563 | MODULE_SOFTDEP("pre: crc32"); |
|---|
| 4051 | 4564 | |
|---|