.. | .. |
---|
42 | 42 | #include "dev-replace.h" |
---|
43 | 43 | #include "free-space-cache.h" |
---|
44 | 44 | #include "backref.h" |
---|
| 45 | +#include "space-info.h" |
---|
| 46 | +#include "sysfs.h" |
---|
45 | 47 | #include "tests/btrfs-tests.h" |
---|
| 48 | +#include "block-group.h" |
---|
| 49 | +#include "discard.h" |
---|
46 | 50 | |
---|
47 | 51 | #include "qgroup.h" |
---|
48 | 52 | #define CREATE_TRACE_POINTS |
---|
.. | .. |
---|
63 | 67 | |
---|
64 | 68 | static int btrfs_remount(struct super_block *sb, int *flags, char *data); |
---|
65 | 69 | |
---|
66 | | -const char *btrfs_decode_error(int errno) |
---|
| 70 | +/* |
---|
| 71 | + * Generally the error codes correspond to their respective errors, but there |
---|
| 72 | + * are a few special cases. |
---|
| 73 | + * |
---|
| 74 | + * EUCLEAN: Any sort of corruption that we encounter. The tree-checker for |
---|
| 75 | + * instance will return EUCLEAN if any of the blocks are corrupted in |
---|
| 76 | + * a way that is problematic. We want to reserve EUCLEAN for these |
---|
| 77 | + * sort of corruptions. |
---|
| 78 | + * |
---|
| 79 | + * EROFS: If we check BTRFS_FS_STATE_ERROR and fail out with a return error, we |
---|
| 80 | + * need to use EROFS for this case. We will have no idea of the |
---|
| 81 | + * original failure, that will have been reported at the time we tripped |
---|
| 82 | + * over the error. Each subsequent error that doesn't have any context |
---|
| 83 | + * of the original error should use EROFS when handling BTRFS_FS_STATE_ERROR. |
---|
| 84 | + */ |
---|
| 85 | +const char * __attribute_const__ btrfs_decode_error(int errno) |
---|
67 | 86 | { |
---|
68 | 87 | char *errstr = "unknown"; |
---|
69 | 88 | |
---|
70 | 89 | switch (errno) { |
---|
71 | | - case -EIO: |
---|
| 90 | + case -ENOENT: /* -2 */ |
---|
| 91 | + errstr = "No such entry"; |
---|
| 92 | + break; |
---|
| 93 | + case -EIO: /* -5 */ |
---|
72 | 94 | errstr = "IO failure"; |
---|
73 | 95 | break; |
---|
74 | | - case -ENOMEM: |
---|
| 96 | + case -ENOMEM: /* -12*/ |
---|
75 | 97 | errstr = "Out of memory"; |
---|
76 | 98 | break; |
---|
77 | | - case -EROFS: |
---|
78 | | - errstr = "Readonly filesystem"; |
---|
79 | | - break; |
---|
80 | | - case -EEXIST: |
---|
| 99 | + case -EEXIST: /* -17 */ |
---|
81 | 100 | errstr = "Object already exists"; |
---|
82 | 101 | break; |
---|
83 | | - case -ENOSPC: |
---|
| 102 | + case -ENOSPC: /* -28 */ |
---|
84 | 103 | errstr = "No space left"; |
---|
85 | 104 | break; |
---|
86 | | - case -ENOENT: |
---|
87 | | - errstr = "No such entry"; |
---|
| 105 | + case -EROFS: /* -30 */ |
---|
| 106 | + errstr = "Readonly filesystem"; |
---|
| 107 | + break; |
---|
| 108 | + case -EOPNOTSUPP: /* -95 */ |
---|
| 109 | + errstr = "Operation not supported"; |
---|
| 110 | + break; |
---|
| 111 | + case -EUCLEAN: /* -117 */ |
---|
| 112 | + errstr = "Filesystem corrupted"; |
---|
| 113 | + break; |
---|
| 114 | + case -EDQUOT: /* -122 */ |
---|
| 115 | + errstr = "Quota exceeded"; |
---|
88 | 116 | break; |
---|
89 | 117 | } |
---|
90 | 118 | |
---|
.. | .. |
---|
93 | 121 | |
---|
94 | 122 | /* |
---|
95 | 123 | * __btrfs_handle_fs_error decodes expected errors from the caller and |
---|
96 | | - * invokes the approciate error response. |
---|
| 124 | + * invokes the appropriate error response. |
---|
97 | 125 | */ |
---|
98 | 126 | __cold |
---|
99 | 127 | void __btrfs_handle_fs_error(struct btrfs_fs_info *fs_info, const char *function, |
---|
.. | .. |
---|
143 | 171 | if (sb_rdonly(sb)) |
---|
144 | 172 | return; |
---|
145 | 173 | |
---|
| 174 | + btrfs_discard_stop(fs_info); |
---|
| 175 | + |
---|
146 | 176 | /* btrfs handle error by forcing the filesystem readonly */ |
---|
147 | 177 | sb->s_flags |= SB_RDONLY; |
---|
148 | 178 | btrfs_info(fs_info, "forced readonly"); |
---|
.. | .. |
---|
151 | 181 | * although there is no way to update the progress. It would add the |
---|
152 | 182 | * risk of a deadlock, therefore the canceling is omitted. The only |
---|
153 | 183 | * penalty is that some I/O remains active until the procedure |
---|
154 | | - * completes. The next time when the filesystem is mounted writeable |
---|
| 184 | + * completes. The next time when the filesystem is mounted writable |
---|
155 | 185 | * again, the device replace operation continues. |
---|
156 | 186 | */ |
---|
157 | 187 | } |
---|
.. | .. |
---|
184 | 214 | RATELIMIT_STATE_INIT(printk_limits[7], DEFAULT_RATELIMIT_INTERVAL, 100), |
---|
185 | 215 | }; |
---|
186 | 216 | |
---|
187 | | -void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...) |
---|
| 217 | +void __cold btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...) |
---|
188 | 218 | { |
---|
189 | 219 | char lvl[PRINTK_MAX_SINGLE_HEADER_LEN + 1] = "\0"; |
---|
190 | 220 | struct va_format vaf; |
---|
.. | .. |
---|
238 | 268 | { |
---|
239 | 269 | struct btrfs_fs_info *fs_info = trans->fs_info; |
---|
240 | 270 | |
---|
241 | | - trans->aborted = errno; |
---|
| 271 | + WRITE_ONCE(trans->aborted, errno); |
---|
242 | 272 | /* Nothing used. The other threads that have joined this |
---|
243 | 273 | * transaction may be able to continue. */ |
---|
244 | 274 | if (!trans->dirty && list_empty(&trans->new_bgs)) { |
---|
.. | .. |
---|
310 | 340 | Opt_datasum, Opt_nodatasum, |
---|
311 | 341 | Opt_defrag, Opt_nodefrag, |
---|
312 | 342 | Opt_discard, Opt_nodiscard, |
---|
313 | | - Opt_nologreplay, |
---|
| 343 | + Opt_discard_mode, |
---|
314 | 344 | Opt_norecovery, |
---|
315 | 345 | Opt_ratio, |
---|
316 | 346 | Opt_rescan_uuid_tree, |
---|
.. | .. |
---|
324 | 354 | Opt_subvolid, |
---|
325 | 355 | Opt_thread_pool, |
---|
326 | 356 | Opt_treelog, Opt_notreelog, |
---|
327 | | - Opt_usebackuproot, |
---|
328 | 357 | Opt_user_subvol_rm_allowed, |
---|
329 | 358 | |
---|
| 359 | + /* Rescue options */ |
---|
| 360 | + Opt_rescue, |
---|
| 361 | + Opt_usebackuproot, |
---|
| 362 | + Opt_nologreplay, |
---|
| 363 | + |
---|
330 | 364 | /* Deprecated options */ |
---|
331 | | - Opt_alloc_start, |
---|
332 | 365 | Opt_recovery, |
---|
333 | | - Opt_subvolrootid, |
---|
334 | 366 | |
---|
335 | 367 | /* Debugging options */ |
---|
336 | 368 | Opt_check_integrity, |
---|
.. | .. |
---|
372 | 404 | {Opt_defrag, "autodefrag"}, |
---|
373 | 405 | {Opt_nodefrag, "noautodefrag"}, |
---|
374 | 406 | {Opt_discard, "discard"}, |
---|
| 407 | + {Opt_discard_mode, "discard=%s"}, |
---|
375 | 408 | {Opt_nodiscard, "nodiscard"}, |
---|
376 | | - {Opt_nologreplay, "nologreplay"}, |
---|
377 | 409 | {Opt_norecovery, "norecovery"}, |
---|
378 | 410 | {Opt_ratio, "metadata_ratio=%u"}, |
---|
379 | 411 | {Opt_rescan_uuid_tree, "rescan_uuid_tree"}, |
---|
.. | .. |
---|
391 | 423 | {Opt_thread_pool, "thread_pool=%u"}, |
---|
392 | 424 | {Opt_treelog, "treelog"}, |
---|
393 | 425 | {Opt_notreelog, "notreelog"}, |
---|
394 | | - {Opt_usebackuproot, "usebackuproot"}, |
---|
395 | 426 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, |
---|
396 | 427 | |
---|
| 428 | + /* Rescue options */ |
---|
| 429 | + {Opt_rescue, "rescue=%s"}, |
---|
| 430 | + /* Deprecated, with alias rescue=nologreplay */ |
---|
| 431 | + {Opt_nologreplay, "nologreplay"}, |
---|
| 432 | + /* Deprecated, with alias rescue=usebackuproot */ |
---|
| 433 | + {Opt_usebackuproot, "usebackuproot"}, |
---|
| 434 | + |
---|
397 | 435 | /* Deprecated options */ |
---|
398 | | - {Opt_alloc_start, "alloc_start=%s"}, |
---|
399 | 436 | {Opt_recovery, "recovery"}, |
---|
400 | | - {Opt_subvolrootid, "subvolrootid=%d"}, |
---|
401 | 437 | |
---|
402 | 438 | /* Debugging options */ |
---|
403 | 439 | {Opt_check_integrity, "check_int"}, |
---|
.. | .. |
---|
415 | 451 | #endif |
---|
416 | 452 | {Opt_err, NULL}, |
---|
417 | 453 | }; |
---|
| 454 | + |
---|
| 455 | +static const match_table_t rescue_tokens = { |
---|
| 456 | + {Opt_usebackuproot, "usebackuproot"}, |
---|
| 457 | + {Opt_nologreplay, "nologreplay"}, |
---|
| 458 | + {Opt_err, NULL}, |
---|
| 459 | +}; |
---|
| 460 | + |
---|
| 461 | +static int parse_rescue_options(struct btrfs_fs_info *info, const char *options) |
---|
| 462 | +{ |
---|
| 463 | + char *opts; |
---|
| 464 | + char *orig; |
---|
| 465 | + char *p; |
---|
| 466 | + substring_t args[MAX_OPT_ARGS]; |
---|
| 467 | + int ret = 0; |
---|
| 468 | + |
---|
| 469 | + opts = kstrdup(options, GFP_KERNEL); |
---|
| 470 | + if (!opts) |
---|
| 471 | + return -ENOMEM; |
---|
| 472 | + orig = opts; |
---|
| 473 | + |
---|
| 474 | + while ((p = strsep(&opts, ":")) != NULL) { |
---|
| 475 | + int token; |
---|
| 476 | + |
---|
| 477 | + if (!*p) |
---|
| 478 | + continue; |
---|
| 479 | + token = match_token(p, rescue_tokens, args); |
---|
| 480 | + switch (token){ |
---|
| 481 | + case Opt_usebackuproot: |
---|
| 482 | + btrfs_info(info, |
---|
| 483 | + "trying to use backup root at mount time"); |
---|
| 484 | + btrfs_set_opt(info->mount_opt, USEBACKUPROOT); |
---|
| 485 | + break; |
---|
| 486 | + case Opt_nologreplay: |
---|
| 487 | + btrfs_set_and_info(info, NOLOGREPLAY, |
---|
| 488 | + "disabling log replay at mount time"); |
---|
| 489 | + break; |
---|
| 490 | + case Opt_err: |
---|
| 491 | + btrfs_info(info, "unrecognized rescue option '%s'", p); |
---|
| 492 | + ret = -EINVAL; |
---|
| 493 | + goto out; |
---|
| 494 | + default: |
---|
| 495 | + break; |
---|
| 496 | + } |
---|
| 497 | + |
---|
| 498 | + } |
---|
| 499 | +out: |
---|
| 500 | + kfree(orig); |
---|
| 501 | + return ret; |
---|
| 502 | +} |
---|
418 | 503 | |
---|
419 | 504 | /* |
---|
420 | 505 | * Regular mount options parser. Everything that is needed only when |
---|
.. | .. |
---|
463 | 548 | case Opt_subvol: |
---|
464 | 549 | case Opt_subvol_empty: |
---|
465 | 550 | case Opt_subvolid: |
---|
466 | | - case Opt_subvolrootid: |
---|
467 | 551 | case Opt_device: |
---|
468 | 552 | /* |
---|
469 | 553 | * These are parsed by btrfs_parse_subvol_options or |
---|
.. | .. |
---|
507 | 591 | case Opt_compress_force: |
---|
508 | 592 | case Opt_compress_force_type: |
---|
509 | 593 | compress_force = true; |
---|
510 | | - /* Fallthrough */ |
---|
| 594 | + fallthrough; |
---|
511 | 595 | case Opt_compress: |
---|
512 | 596 | case Opt_compress_type: |
---|
513 | 597 | saved_compress_type = btrfs_test_opt(info, |
---|
.. | .. |
---|
531 | 615 | if (token != Opt_compress && |
---|
532 | 616 | token != Opt_compress_force) |
---|
533 | 617 | info->compress_level = |
---|
534 | | - btrfs_compress_str2level(args[0].from); |
---|
| 618 | + btrfs_compress_str2level( |
---|
| 619 | + BTRFS_COMPRESS_ZLIB, |
---|
| 620 | + args[0].from + 4); |
---|
535 | 621 | btrfs_set_opt(info->mount_opt, COMPRESS); |
---|
536 | 622 | btrfs_clear_opt(info->mount_opt, NODATACOW); |
---|
537 | 623 | btrfs_clear_opt(info->mount_opt, NODATASUM); |
---|
.. | .. |
---|
545 | 631 | btrfs_clear_opt(info->mount_opt, NODATASUM); |
---|
546 | 632 | btrfs_set_fs_incompat(info, COMPRESS_LZO); |
---|
547 | 633 | no_compress = 0; |
---|
548 | | - } else if (strcmp(args[0].from, "zstd") == 0) { |
---|
| 634 | + } else if (strncmp(args[0].from, "zstd", 4) == 0) { |
---|
549 | 635 | compress_type = "zstd"; |
---|
550 | 636 | info->compress_type = BTRFS_COMPRESS_ZSTD; |
---|
| 637 | + info->compress_level = |
---|
| 638 | + btrfs_compress_str2level( |
---|
| 639 | + BTRFS_COMPRESS_ZSTD, |
---|
| 640 | + args[0].from + 4); |
---|
551 | 641 | btrfs_set_opt(info->mount_opt, COMPRESS); |
---|
552 | 642 | btrfs_clear_opt(info->mount_opt, NODATACOW); |
---|
553 | 643 | btrfs_clear_opt(info->mount_opt, NODATASUM); |
---|
.. | .. |
---|
562 | 652 | compress_force = false; |
---|
563 | 653 | no_compress++; |
---|
564 | 654 | } else { |
---|
| 655 | + btrfs_err(info, "unrecognized compression value %s", |
---|
| 656 | + args[0].from); |
---|
565 | 657 | ret = -EINVAL; |
---|
566 | 658 | goto out; |
---|
567 | 659 | } |
---|
.. | .. |
---|
604 | 696 | btrfs_set_opt(info->mount_opt, NOSSD); |
---|
605 | 697 | btrfs_clear_and_info(info, SSD, |
---|
606 | 698 | "not using ssd optimizations"); |
---|
607 | | - /* Fallthrough */ |
---|
| 699 | + fallthrough; |
---|
608 | 700 | case Opt_nossd_spread: |
---|
609 | 701 | btrfs_clear_and_info(info, SSD_SPREAD, |
---|
610 | 702 | "not using spread ssd allocation scheme"); |
---|
.. | .. |
---|
620 | 712 | case Opt_thread_pool: |
---|
621 | 713 | ret = match_int(&args[0], &intarg); |
---|
622 | 714 | if (ret) { |
---|
| 715 | + btrfs_err(info, "unrecognized thread_pool value %s", |
---|
| 716 | + args[0].from); |
---|
623 | 717 | goto out; |
---|
624 | 718 | } else if (intarg == 0) { |
---|
| 719 | + btrfs_err(info, "invalid value 0 for thread_pool"); |
---|
625 | 720 | ret = -EINVAL; |
---|
626 | 721 | goto out; |
---|
627 | 722 | } |
---|
.. | .. |
---|
645 | 740 | goto out; |
---|
646 | 741 | } |
---|
647 | 742 | break; |
---|
648 | | - case Opt_alloc_start: |
---|
649 | | - btrfs_info(info, |
---|
650 | | - "option alloc_start is obsolete, ignored"); |
---|
651 | | - break; |
---|
652 | 743 | case Opt_acl: |
---|
653 | 744 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL |
---|
654 | 745 | info->sb->s_flags |= SB_POSIXACL; |
---|
.. | .. |
---|
671 | 762 | break; |
---|
672 | 763 | case Opt_norecovery: |
---|
673 | 764 | case Opt_nologreplay: |
---|
| 765 | + btrfs_warn(info, |
---|
| 766 | + "'nologreplay' is deprecated, use 'rescue=nologreplay' instead"); |
---|
674 | 767 | btrfs_set_and_info(info, NOLOGREPLAY, |
---|
675 | 768 | "disabling log replay at mount time"); |
---|
676 | 769 | break; |
---|
.. | .. |
---|
684 | 777 | break; |
---|
685 | 778 | case Opt_ratio: |
---|
686 | 779 | ret = match_int(&args[0], &intarg); |
---|
687 | | - if (ret) |
---|
| 780 | + if (ret) { |
---|
| 781 | + btrfs_err(info, "unrecognized metadata_ratio value %s", |
---|
| 782 | + args[0].from); |
---|
688 | 783 | goto out; |
---|
| 784 | + } |
---|
689 | 785 | info->metadata_ratio = intarg; |
---|
690 | 786 | btrfs_info(info, "metadata ratio %u", |
---|
691 | 787 | info->metadata_ratio); |
---|
692 | 788 | break; |
---|
693 | 789 | case Opt_discard: |
---|
694 | | - btrfs_set_and_info(info, DISCARD, |
---|
695 | | - "turning on discard"); |
---|
| 790 | + case Opt_discard_mode: |
---|
| 791 | + if (token == Opt_discard || |
---|
| 792 | + strcmp(args[0].from, "sync") == 0) { |
---|
| 793 | + btrfs_clear_opt(info->mount_opt, DISCARD_ASYNC); |
---|
| 794 | + btrfs_set_and_info(info, DISCARD_SYNC, |
---|
| 795 | + "turning on sync discard"); |
---|
| 796 | + } else if (strcmp(args[0].from, "async") == 0) { |
---|
| 797 | + btrfs_clear_opt(info->mount_opt, DISCARD_SYNC); |
---|
| 798 | + btrfs_set_and_info(info, DISCARD_ASYNC, |
---|
| 799 | + "turning on async discard"); |
---|
| 800 | + } else { |
---|
| 801 | + btrfs_err(info, "unrecognized discard mode value %s", |
---|
| 802 | + args[0].from); |
---|
| 803 | + ret = -EINVAL; |
---|
| 804 | + goto out; |
---|
| 805 | + } |
---|
696 | 806 | break; |
---|
697 | 807 | case Opt_nodiscard: |
---|
698 | | - btrfs_clear_and_info(info, DISCARD, |
---|
| 808 | + btrfs_clear_and_info(info, DISCARD_SYNC, |
---|
699 | 809 | "turning off discard"); |
---|
| 810 | + btrfs_clear_and_info(info, DISCARD_ASYNC, |
---|
| 811 | + "turning off async discard"); |
---|
700 | 812 | break; |
---|
701 | 813 | case Opt_space_cache: |
---|
702 | 814 | case Opt_space_cache_version: |
---|
.. | .. |
---|
712 | 824 | btrfs_set_and_info(info, FREE_SPACE_TREE, |
---|
713 | 825 | "enabling free space tree"); |
---|
714 | 826 | } else { |
---|
| 827 | + btrfs_err(info, "unrecognized space_cache value %s", |
---|
| 828 | + args[0].from); |
---|
715 | 829 | ret = -EINVAL; |
---|
716 | 830 | goto out; |
---|
717 | 831 | } |
---|
.. | .. |
---|
730 | 844 | } |
---|
731 | 845 | break; |
---|
732 | 846 | case Opt_inode_cache: |
---|
| 847 | + btrfs_warn(info, |
---|
| 848 | + "the 'inode_cache' option is deprecated and will have no effect from 5.11"); |
---|
733 | 849 | btrfs_set_pending_and_info(info, INODE_MAP_CACHE, |
---|
734 | 850 | "enabling inode map caching"); |
---|
735 | 851 | break; |
---|
.. | .. |
---|
759 | 875 | "disabling auto defrag"); |
---|
760 | 876 | break; |
---|
761 | 877 | case Opt_recovery: |
---|
762 | | - btrfs_warn(info, |
---|
763 | | - "'recovery' is deprecated, use 'usebackuproot' instead"); |
---|
764 | | - /* fall through */ |
---|
765 | 878 | case Opt_usebackuproot: |
---|
| 879 | + btrfs_warn(info, |
---|
| 880 | + "'%s' is deprecated, use 'rescue=usebackuproot' instead", |
---|
| 881 | + token == Opt_recovery ? "recovery" : |
---|
| 882 | + "usebackuproot"); |
---|
766 | 883 | btrfs_info(info, |
---|
767 | 884 | "trying to use backup root at mount time"); |
---|
768 | 885 | btrfs_set_opt(info->mount_opt, USEBACKUPROOT); |
---|
.. | .. |
---|
784 | 901 | break; |
---|
785 | 902 | case Opt_check_integrity_print_mask: |
---|
786 | 903 | ret = match_int(&args[0], &intarg); |
---|
787 | | - if (ret) |
---|
| 904 | + if (ret) { |
---|
| 905 | + btrfs_err(info, |
---|
| 906 | + "unrecognized check_integrity_print_mask value %s", |
---|
| 907 | + args[0].from); |
---|
788 | 908 | goto out; |
---|
| 909 | + } |
---|
789 | 910 | info->check_integrity_print_mask = intarg; |
---|
790 | 911 | btrfs_info(info, "check_integrity_print_mask 0x%x", |
---|
791 | 912 | info->check_integrity_print_mask); |
---|
.. | .. |
---|
800 | 921 | goto out; |
---|
801 | 922 | #endif |
---|
802 | 923 | case Opt_fatal_errors: |
---|
803 | | - if (strcmp(args[0].from, "panic") == 0) |
---|
| 924 | + if (strcmp(args[0].from, "panic") == 0) { |
---|
804 | 925 | btrfs_set_opt(info->mount_opt, |
---|
805 | 926 | PANIC_ON_FATAL_ERROR); |
---|
806 | | - else if (strcmp(args[0].from, "bug") == 0) |
---|
| 927 | + } else if (strcmp(args[0].from, "bug") == 0) { |
---|
807 | 928 | btrfs_clear_opt(info->mount_opt, |
---|
808 | 929 | PANIC_ON_FATAL_ERROR); |
---|
809 | | - else { |
---|
| 930 | + } else { |
---|
| 931 | + btrfs_err(info, "unrecognized fatal_errors value %s", |
---|
| 932 | + args[0].from); |
---|
810 | 933 | ret = -EINVAL; |
---|
811 | 934 | goto out; |
---|
812 | 935 | } |
---|
.. | .. |
---|
814 | 937 | case Opt_commit_interval: |
---|
815 | 938 | intarg = 0; |
---|
816 | 939 | ret = match_int(&args[0], &intarg); |
---|
817 | | - if (ret) |
---|
| 940 | + if (ret) { |
---|
| 941 | + btrfs_err(info, "unrecognized commit_interval value %s", |
---|
| 942 | + args[0].from); |
---|
| 943 | + ret = -EINVAL; |
---|
818 | 944 | goto out; |
---|
| 945 | + } |
---|
819 | 946 | if (intarg == 0) { |
---|
820 | 947 | btrfs_info(info, |
---|
821 | 948 | "using default commit interval %us", |
---|
.. | .. |
---|
826 | 953 | intarg); |
---|
827 | 954 | } |
---|
828 | 955 | info->commit_interval = intarg; |
---|
| 956 | + break; |
---|
| 957 | + case Opt_rescue: |
---|
| 958 | + ret = parse_rescue_options(info, args[0].from); |
---|
| 959 | + if (ret < 0) { |
---|
| 960 | + btrfs_err(info, "unrecognized rescue value %s", |
---|
| 961 | + args[0].from); |
---|
| 962 | + goto out; |
---|
| 963 | + } |
---|
829 | 964 | break; |
---|
830 | 965 | #ifdef CONFIG_BTRFS_DEBUG |
---|
831 | 966 | case Opt_fragment_all: |
---|
.. | .. |
---|
850 | 985 | break; |
---|
851 | 986 | #endif |
---|
852 | 987 | case Opt_err: |
---|
853 | | - btrfs_info(info, "unrecognized mount option '%s'", p); |
---|
| 988 | + btrfs_err(info, "unrecognized mount option '%s'", p); |
---|
854 | 989 | ret = -EINVAL; |
---|
855 | 990 | goto out; |
---|
856 | 991 | default: |
---|
.. | .. |
---|
988 | 1123 | |
---|
989 | 1124 | *subvol_objectid = subvolid; |
---|
990 | 1125 | break; |
---|
991 | | - case Opt_subvolrootid: |
---|
992 | | - pr_warn("BTRFS: 'subvolrootid' mount option is deprecated and has no effect\n"); |
---|
993 | | - break; |
---|
994 | 1126 | default: |
---|
995 | 1127 | break; |
---|
996 | 1128 | } |
---|
.. | .. |
---|
1005 | 1137 | u64 subvol_objectid) |
---|
1006 | 1138 | { |
---|
1007 | 1139 | struct btrfs_root *root = fs_info->tree_root; |
---|
1008 | | - struct btrfs_root *fs_root; |
---|
| 1140 | + struct btrfs_root *fs_root = NULL; |
---|
1009 | 1141 | struct btrfs_root_ref *root_ref; |
---|
1010 | 1142 | struct btrfs_inode_ref *inode_ref; |
---|
1011 | 1143 | struct btrfs_key key; |
---|
.. | .. |
---|
1070 | 1202 | dirid = btrfs_root_ref_dirid(path->nodes[0], root_ref); |
---|
1071 | 1203 | btrfs_release_path(path); |
---|
1072 | 1204 | |
---|
1073 | | - key.objectid = subvol_objectid; |
---|
1074 | | - key.type = BTRFS_ROOT_ITEM_KEY; |
---|
1075 | | - key.offset = (u64)-1; |
---|
1076 | | - fs_root = btrfs_read_fs_root_no_name(fs_info, &key); |
---|
| 1205 | + fs_root = btrfs_get_fs_root(fs_info, subvol_objectid, true); |
---|
1077 | 1206 | if (IS_ERR(fs_root)) { |
---|
1078 | 1207 | ret = PTR_ERR(fs_root); |
---|
| 1208 | + fs_root = NULL; |
---|
1079 | 1209 | goto err; |
---|
1080 | 1210 | } |
---|
1081 | 1211 | |
---|
.. | .. |
---|
1120 | 1250 | ptr[0] = '/'; |
---|
1121 | 1251 | btrfs_release_path(path); |
---|
1122 | 1252 | } |
---|
| 1253 | + btrfs_put_root(fs_root); |
---|
| 1254 | + fs_root = NULL; |
---|
1123 | 1255 | } |
---|
1124 | 1256 | |
---|
1125 | 1257 | btrfs_free_path(path); |
---|
.. | .. |
---|
1132 | 1264 | return name; |
---|
1133 | 1265 | |
---|
1134 | 1266 | err: |
---|
| 1267 | + btrfs_put_root(fs_root); |
---|
1135 | 1268 | btrfs_free_path(path); |
---|
1136 | 1269 | kfree(name); |
---|
1137 | 1270 | return ERR_PTR(ret); |
---|
.. | .. |
---|
1184 | 1317 | { |
---|
1185 | 1318 | struct inode *inode; |
---|
1186 | 1319 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
---|
1187 | | - struct btrfs_key key; |
---|
1188 | 1320 | int err; |
---|
1189 | 1321 | |
---|
1190 | 1322 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
---|
.. | .. |
---|
1212 | 1344 | return err; |
---|
1213 | 1345 | } |
---|
1214 | 1346 | |
---|
1215 | | - key.objectid = BTRFS_FIRST_FREE_OBJECTID; |
---|
1216 | | - key.type = BTRFS_INODE_ITEM_KEY; |
---|
1217 | | - key.offset = 0; |
---|
1218 | | - inode = btrfs_iget(sb, &key, fs_info->fs_root, NULL); |
---|
| 1347 | + inode = btrfs_iget(sb, BTRFS_FIRST_FREE_OBJECTID, fs_info->fs_root); |
---|
1219 | 1348 | if (IS_ERR(inode)) { |
---|
1220 | 1349 | err = PTR_ERR(inode); |
---|
1221 | 1350 | goto fail_close; |
---|
.. | .. |
---|
1316 | 1445 | if (btrfs_test_opt(info, NOTREELOG)) |
---|
1317 | 1446 | seq_puts(seq, ",notreelog"); |
---|
1318 | 1447 | if (btrfs_test_opt(info, NOLOGREPLAY)) |
---|
1319 | | - seq_puts(seq, ",nologreplay"); |
---|
| 1448 | + seq_puts(seq, ",rescue=nologreplay"); |
---|
1320 | 1449 | if (btrfs_test_opt(info, FLUSHONCOMMIT)) |
---|
1321 | 1450 | seq_puts(seq, ",flushoncommit"); |
---|
1322 | | - if (btrfs_test_opt(info, DISCARD)) |
---|
| 1451 | + if (btrfs_test_opt(info, DISCARD_SYNC)) |
---|
1323 | 1452 | seq_puts(seq, ",discard"); |
---|
| 1453 | + if (btrfs_test_opt(info, DISCARD_ASYNC)) |
---|
| 1454 | + seq_puts(seq, ",discard=async"); |
---|
1324 | 1455 | if (!(info->sb->s_flags & SB_POSIXACL)) |
---|
1325 | 1456 | seq_puts(seq, ",noacl"); |
---|
1326 | 1457 | if (btrfs_test_opt(info, SPACE_CACHE)) |
---|
.. | .. |
---|
1405 | 1536 | } |
---|
1406 | 1537 | |
---|
1407 | 1538 | static struct dentry *mount_subvol(const char *subvol_name, u64 subvol_objectid, |
---|
1408 | | - const char *device_name, struct vfsmount *mnt) |
---|
| 1539 | + struct vfsmount *mnt) |
---|
1409 | 1540 | { |
---|
1410 | 1541 | struct dentry *root; |
---|
1411 | 1542 | int ret; |
---|
.. | .. |
---|
1469 | 1600 | return root; |
---|
1470 | 1601 | } |
---|
1471 | 1602 | |
---|
1472 | | -static int parse_security_options(char *orig_opts, |
---|
1473 | | - struct security_mnt_opts *sec_opts) |
---|
1474 | | -{ |
---|
1475 | | - char *secdata = NULL; |
---|
1476 | | - int ret = 0; |
---|
1477 | | - |
---|
1478 | | - secdata = alloc_secdata(); |
---|
1479 | | - if (!secdata) |
---|
1480 | | - return -ENOMEM; |
---|
1481 | | - ret = security_sb_copy_data(orig_opts, secdata); |
---|
1482 | | - if (ret) { |
---|
1483 | | - free_secdata(secdata); |
---|
1484 | | - return ret; |
---|
1485 | | - } |
---|
1486 | | - ret = security_sb_parse_opts_str(secdata, sec_opts); |
---|
1487 | | - free_secdata(secdata); |
---|
1488 | | - return ret; |
---|
1489 | | -} |
---|
1490 | | - |
---|
1491 | | -static int setup_security_options(struct btrfs_fs_info *fs_info, |
---|
1492 | | - struct super_block *sb, |
---|
1493 | | - struct security_mnt_opts *sec_opts) |
---|
1494 | | -{ |
---|
1495 | | - int ret = 0; |
---|
1496 | | - |
---|
1497 | | - /* |
---|
1498 | | - * Call security_sb_set_mnt_opts() to check whether new sec_opts |
---|
1499 | | - * is valid. |
---|
1500 | | - */ |
---|
1501 | | - ret = security_sb_set_mnt_opts(sb, sec_opts, 0, NULL); |
---|
1502 | | - if (ret) |
---|
1503 | | - return ret; |
---|
1504 | | - |
---|
1505 | | -#ifdef CONFIG_SECURITY |
---|
1506 | | - if (!fs_info->security_opts.num_mnt_opts) { |
---|
1507 | | - /* first time security setup, copy sec_opts to fs_info */ |
---|
1508 | | - memcpy(&fs_info->security_opts, sec_opts, sizeof(*sec_opts)); |
---|
1509 | | - } else { |
---|
1510 | | - /* |
---|
1511 | | - * Since SELinux (the only one supporting security_mnt_opts) |
---|
1512 | | - * does NOT support changing context during remount/mount of |
---|
1513 | | - * the same sb, this must be the same or part of the same |
---|
1514 | | - * security options, just free it. |
---|
1515 | | - */ |
---|
1516 | | - security_free_mnt_opts(sec_opts); |
---|
1517 | | - } |
---|
1518 | | -#endif |
---|
1519 | | - return ret; |
---|
1520 | | -} |
---|
1521 | | - |
---|
1522 | 1603 | /* |
---|
1523 | 1604 | * Find a superblock for the given device / mount point. |
---|
1524 | 1605 | * |
---|
.. | .. |
---|
1533 | 1614 | struct btrfs_device *device = NULL; |
---|
1534 | 1615 | struct btrfs_fs_devices *fs_devices = NULL; |
---|
1535 | 1616 | struct btrfs_fs_info *fs_info = NULL; |
---|
1536 | | - struct security_mnt_opts new_sec_opts; |
---|
| 1617 | + void *new_sec_opts = NULL; |
---|
1537 | 1618 | fmode_t mode = FMODE_READ; |
---|
1538 | 1619 | int error = 0; |
---|
1539 | 1620 | |
---|
1540 | 1621 | if (!(flags & SB_RDONLY)) |
---|
1541 | 1622 | mode |= FMODE_WRITE; |
---|
1542 | 1623 | |
---|
1543 | | - security_init_mnt_opts(&new_sec_opts); |
---|
1544 | 1624 | if (data) { |
---|
1545 | | - error = parse_security_options(data, &new_sec_opts); |
---|
| 1625 | + error = security_sb_eat_lsm_opts(data, &new_sec_opts); |
---|
1546 | 1626 | if (error) |
---|
1547 | 1627 | return ERR_PTR(error); |
---|
1548 | 1628 | } |
---|
.. | .. |
---|
1550 | 1630 | /* |
---|
1551 | 1631 | * Setup a dummy root and fs_info for test/set super. This is because |
---|
1552 | 1632 | * we don't actually fill this stuff out until open_ctree, but we need |
---|
1553 | | - * it for searching for existing supers, so this lets us do that and |
---|
1554 | | - * then open_ctree will properly initialize everything later. |
---|
| 1633 | + * then open_ctree will properly initialize the file system specific |
---|
| 1634 | + * settings later. btrfs_init_fs_info initializes the static elements |
---|
| 1635 | + * of the fs_info (locks and such) to make cleanup easier if we find a |
---|
| 1636 | + * superblock with our given fs_devices later on at sget() time. |
---|
1555 | 1637 | */ |
---|
1556 | 1638 | fs_info = kvzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL); |
---|
1557 | 1639 | if (!fs_info) { |
---|
1558 | 1640 | error = -ENOMEM; |
---|
1559 | 1641 | goto error_sec_opts; |
---|
1560 | 1642 | } |
---|
| 1643 | + btrfs_init_fs_info(fs_info); |
---|
1561 | 1644 | |
---|
1562 | 1645 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); |
---|
1563 | 1646 | fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); |
---|
1564 | | - security_init_mnt_opts(&fs_info->security_opts); |
---|
1565 | 1647 | if (!fs_info->super_copy || !fs_info->super_for_commit) { |
---|
1566 | 1648 | error = -ENOMEM; |
---|
1567 | 1649 | goto error_fs_info; |
---|
.. | .. |
---|
1604 | 1686 | |
---|
1605 | 1687 | if (s->s_root) { |
---|
1606 | 1688 | btrfs_close_devices(fs_devices); |
---|
1607 | | - free_fs_info(fs_info); |
---|
| 1689 | + btrfs_free_fs_info(fs_info); |
---|
1608 | 1690 | if ((flags ^ s->s_flags) & SB_RDONLY) |
---|
1609 | 1691 | error = -EBUSY; |
---|
1610 | 1692 | } else { |
---|
.. | .. |
---|
1612 | 1694 | btrfs_sb(s)->bdev_holder = fs_type; |
---|
1613 | 1695 | error = btrfs_fill_super(s, fs_devices, data); |
---|
1614 | 1696 | } |
---|
| 1697 | + if (!error) |
---|
| 1698 | + error = security_sb_set_mnt_opts(s, new_sec_opts, 0, NULL); |
---|
| 1699 | + security_free_mnt_opts(&new_sec_opts); |
---|
1615 | 1700 | if (error) { |
---|
1616 | 1701 | deactivate_locked_super(s); |
---|
1617 | | - goto error_sec_opts; |
---|
1618 | | - } |
---|
1619 | | - |
---|
1620 | | - fs_info = btrfs_sb(s); |
---|
1621 | | - error = setup_security_options(fs_info, s, &new_sec_opts); |
---|
1622 | | - if (error) { |
---|
1623 | | - deactivate_locked_super(s); |
---|
1624 | | - goto error_sec_opts; |
---|
| 1702 | + return ERR_PTR(error); |
---|
1625 | 1703 | } |
---|
1626 | 1704 | |
---|
1627 | 1705 | return dget(s->s_root); |
---|
.. | .. |
---|
1629 | 1707 | error_close_devices: |
---|
1630 | 1708 | btrfs_close_devices(fs_devices); |
---|
1631 | 1709 | error_fs_info: |
---|
1632 | | - free_fs_info(fs_info); |
---|
| 1710 | + btrfs_free_fs_info(fs_info); |
---|
1633 | 1711 | error_sec_opts: |
---|
1634 | 1712 | security_free_mnt_opts(&new_sec_opts); |
---|
1635 | 1713 | return ERR_PTR(error); |
---|
.. | .. |
---|
1662 | 1740 | { |
---|
1663 | 1741 | struct vfsmount *mnt_root; |
---|
1664 | 1742 | struct dentry *root; |
---|
1665 | | - fmode_t mode = FMODE_READ; |
---|
1666 | 1743 | char *subvol_name = NULL; |
---|
1667 | 1744 | u64 subvol_objectid = 0; |
---|
1668 | 1745 | int error = 0; |
---|
1669 | | - |
---|
1670 | | - if (!(flags & SB_RDONLY)) |
---|
1671 | | - mode |= FMODE_WRITE; |
---|
1672 | 1746 | |
---|
1673 | 1747 | error = btrfs_parse_subvol_options(data, &subvol_name, |
---|
1674 | 1748 | &subvol_objectid); |
---|
.. | .. |
---|
1710 | 1784 | } |
---|
1711 | 1785 | |
---|
1712 | 1786 | /* mount_subvol() will free subvol_name and mnt_root */ |
---|
1713 | | - root = mount_subvol(subvol_name, subvol_objectid, device_name, mnt_root); |
---|
| 1787 | + root = mount_subvol(subvol_name, subvol_objectid, mnt_root); |
---|
1714 | 1788 | |
---|
1715 | 1789 | out: |
---|
1716 | 1790 | return root; |
---|
.. | .. |
---|
1729 | 1803 | |
---|
1730 | 1804 | btrfs_workqueue_set_max(fs_info->workers, new_pool_size); |
---|
1731 | 1805 | btrfs_workqueue_set_max(fs_info->delalloc_workers, new_pool_size); |
---|
1732 | | - btrfs_workqueue_set_max(fs_info->submit_workers, new_pool_size); |
---|
1733 | 1806 | btrfs_workqueue_set_max(fs_info->caching_workers, new_pool_size); |
---|
1734 | 1807 | btrfs_workqueue_set_max(fs_info->endio_workers, new_pool_size); |
---|
1735 | 1808 | btrfs_workqueue_set_max(fs_info->endio_meta_workers, new_pool_size); |
---|
.. | .. |
---|
1741 | 1814 | btrfs_workqueue_set_max(fs_info->readahead_workers, new_pool_size); |
---|
1742 | 1815 | btrfs_workqueue_set_max(fs_info->scrub_wr_completion_workers, |
---|
1743 | 1816 | new_pool_size); |
---|
1744 | | -} |
---|
1745 | | - |
---|
1746 | | -static inline void btrfs_remount_prepare(struct btrfs_fs_info *fs_info) |
---|
1747 | | -{ |
---|
1748 | | - set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); |
---|
1749 | 1817 | } |
---|
1750 | 1818 | |
---|
1751 | 1819 | static inline void btrfs_remount_begin(struct btrfs_fs_info *fs_info, |
---|
.. | .. |
---|
1774 | 1842 | btrfs_cleanup_defrag_inodes(fs_info); |
---|
1775 | 1843 | } |
---|
1776 | 1844 | |
---|
1777 | | - clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); |
---|
| 1845 | + /* If we toggled discard async */ |
---|
| 1846 | + if (!btrfs_raw_test_opt(old_opts, DISCARD_ASYNC) && |
---|
| 1847 | + btrfs_test_opt(fs_info, DISCARD_ASYNC)) |
---|
| 1848 | + btrfs_discard_resume(fs_info); |
---|
| 1849 | + else if (btrfs_raw_test_opt(old_opts, DISCARD_ASYNC) && |
---|
| 1850 | + !btrfs_test_opt(fs_info, DISCARD_ASYNC)) |
---|
| 1851 | + btrfs_discard_cleanup(fs_info); |
---|
1778 | 1852 | } |
---|
1779 | 1853 | |
---|
1780 | 1854 | static int btrfs_remount(struct super_block *sb, int *flags, char *data) |
---|
.. | .. |
---|
1790 | 1864 | int ret; |
---|
1791 | 1865 | |
---|
1792 | 1866 | sync_filesystem(sb); |
---|
1793 | | - btrfs_remount_prepare(fs_info); |
---|
| 1867 | + set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); |
---|
1794 | 1868 | |
---|
1795 | 1869 | if (data) { |
---|
1796 | | - struct security_mnt_opts new_sec_opts; |
---|
| 1870 | + void *new_sec_opts = NULL; |
---|
1797 | 1871 | |
---|
1798 | | - security_init_mnt_opts(&new_sec_opts); |
---|
1799 | | - ret = parse_security_options(data, &new_sec_opts); |
---|
| 1872 | + ret = security_sb_eat_lsm_opts(data, &new_sec_opts); |
---|
| 1873 | + if (!ret) |
---|
| 1874 | + ret = security_sb_remount(sb, new_sec_opts); |
---|
| 1875 | + security_free_mnt_opts(&new_sec_opts); |
---|
1800 | 1876 | if (ret) |
---|
1801 | 1877 | goto restore; |
---|
1802 | | - ret = setup_security_options(fs_info, sb, |
---|
1803 | | - &new_sec_opts); |
---|
1804 | | - if (ret) { |
---|
1805 | | - security_free_mnt_opts(&new_sec_opts); |
---|
1806 | | - goto restore; |
---|
1807 | | - } |
---|
1808 | 1878 | } |
---|
1809 | 1879 | |
---|
1810 | 1880 | ret = btrfs_parse_options(fs_info, data, *flags); |
---|
.. | .. |
---|
1824 | 1894 | * the filesystem is busy. |
---|
1825 | 1895 | */ |
---|
1826 | 1896 | cancel_work_sync(&fs_info->async_reclaim_work); |
---|
| 1897 | + cancel_work_sync(&fs_info->async_data_reclaim_work); |
---|
| 1898 | + |
---|
| 1899 | + btrfs_discard_cleanup(fs_info); |
---|
1827 | 1900 | |
---|
1828 | 1901 | /* wait for the uuid_scan task to finish */ |
---|
1829 | 1902 | down(&fs_info->uuid_tree_rescan_sem); |
---|
.. | .. |
---|
1870 | 1943 | |
---|
1871 | 1944 | if (!btrfs_check_rw_degradable(fs_info, NULL)) { |
---|
1872 | 1945 | btrfs_warn(fs_info, |
---|
1873 | | - "too many missing devices, writeable remount is not allowed"); |
---|
| 1946 | + "too many missing devices, writable remount is not allowed"); |
---|
1874 | 1947 | ret = -EACCES; |
---|
1875 | 1948 | goto restore; |
---|
1876 | 1949 | } |
---|
.. | .. |
---|
1920 | 1993 | set_bit(BTRFS_FS_OPEN, &fs_info->flags); |
---|
1921 | 1994 | } |
---|
1922 | 1995 | out: |
---|
| 1996 | + /* |
---|
| 1997 | + * We need to set SB_I_VERSION here otherwise it'll get cleared by VFS, |
---|
| 1998 | + * since the absence of the flag means it can be toggled off by remount. |
---|
| 1999 | + */ |
---|
| 2000 | + *flags |= SB_I_VERSION; |
---|
| 2001 | + |
---|
1923 | 2002 | wake_up_process(fs_info->transaction_kthread); |
---|
1924 | 2003 | btrfs_remount_cleanup(fs_info, old_opts); |
---|
| 2004 | + clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); |
---|
| 2005 | + |
---|
1925 | 2006 | return 0; |
---|
1926 | 2007 | |
---|
1927 | 2008 | restore: |
---|
.. | .. |
---|
1936 | 2017 | old_thread_pool_size, fs_info->thread_pool_size); |
---|
1937 | 2018 | fs_info->metadata_ratio = old_metadata_ratio; |
---|
1938 | 2019 | btrfs_remount_cleanup(fs_info, old_opts); |
---|
| 2020 | + clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); |
---|
| 2021 | + |
---|
1939 | 2022 | return ret; |
---|
1940 | 2023 | } |
---|
1941 | 2024 | |
---|
.. | .. |
---|
1975 | 2058 | struct btrfs_device_info *devices_info; |
---|
1976 | 2059 | struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; |
---|
1977 | 2060 | struct btrfs_device *device; |
---|
1978 | | - u64 skip_space; |
---|
1979 | 2061 | u64 type; |
---|
1980 | 2062 | u64 avail_space; |
---|
1981 | 2063 | u64 min_stripe_size; |
---|
1982 | | - int min_stripes = 1, num_stripes = 1; |
---|
| 2064 | + int num_stripes = 1; |
---|
1983 | 2065 | int i = 0, nr_devices; |
---|
| 2066 | + const struct btrfs_raid_attr *rattr; |
---|
1984 | 2067 | |
---|
1985 | 2068 | /* |
---|
1986 | 2069 | * We aren't under the device list lock, so this is racy-ish, but good |
---|
.. | .. |
---|
2004 | 2087 | |
---|
2005 | 2088 | /* calc min stripe number for data space allocation */ |
---|
2006 | 2089 | type = btrfs_data_alloc_profile(fs_info); |
---|
2007 | | - if (type & BTRFS_BLOCK_GROUP_RAID0) { |
---|
2008 | | - min_stripes = 2; |
---|
2009 | | - num_stripes = nr_devices; |
---|
2010 | | - } else if (type & BTRFS_BLOCK_GROUP_RAID1) { |
---|
2011 | | - min_stripes = 2; |
---|
2012 | | - num_stripes = 2; |
---|
2013 | | - } else if (type & BTRFS_BLOCK_GROUP_RAID10) { |
---|
2014 | | - min_stripes = 4; |
---|
2015 | | - num_stripes = 4; |
---|
2016 | | - } |
---|
| 2090 | + rattr = &btrfs_raid_array[btrfs_bg_flags_to_raid_index(type)]; |
---|
2017 | 2091 | |
---|
2018 | | - if (type & BTRFS_BLOCK_GROUP_DUP) |
---|
2019 | | - min_stripe_size = 2 * BTRFS_STRIPE_LEN; |
---|
2020 | | - else |
---|
2021 | | - min_stripe_size = BTRFS_STRIPE_LEN; |
---|
| 2092 | + if (type & BTRFS_BLOCK_GROUP_RAID0) |
---|
| 2093 | + num_stripes = nr_devices; |
---|
| 2094 | + else if (type & BTRFS_BLOCK_GROUP_RAID1) |
---|
| 2095 | + num_stripes = 2; |
---|
| 2096 | + else if (type & BTRFS_BLOCK_GROUP_RAID1C3) |
---|
| 2097 | + num_stripes = 3; |
---|
| 2098 | + else if (type & BTRFS_BLOCK_GROUP_RAID1C4) |
---|
| 2099 | + num_stripes = 4; |
---|
| 2100 | + else if (type & BTRFS_BLOCK_GROUP_RAID10) |
---|
| 2101 | + num_stripes = 4; |
---|
| 2102 | + |
---|
| 2103 | + /* Adjust for more than 1 stripe per device */ |
---|
| 2104 | + min_stripe_size = rattr->dev_stripes * BTRFS_STRIPE_LEN; |
---|
2022 | 2105 | |
---|
2023 | 2106 | rcu_read_lock(); |
---|
2024 | 2107 | list_for_each_entry_rcu(device, &fs_devices->devices, dev_list) { |
---|
.. | .. |
---|
2034 | 2117 | avail_space = device->total_bytes - device->bytes_used; |
---|
2035 | 2118 | |
---|
2036 | 2119 | /* align with stripe_len */ |
---|
2037 | | - avail_space = div_u64(avail_space, BTRFS_STRIPE_LEN); |
---|
2038 | | - avail_space *= BTRFS_STRIPE_LEN; |
---|
| 2120 | + avail_space = rounddown(avail_space, BTRFS_STRIPE_LEN); |
---|
2039 | 2121 | |
---|
2040 | 2122 | /* |
---|
2041 | 2123 | * In order to avoid overwriting the superblock on the drive, |
---|
2042 | 2124 | * btrfs starts at an offset of at least 1MB when doing chunk |
---|
2043 | 2125 | * allocation. |
---|
| 2126 | + * |
---|
| 2127 | + * This ensures we have at least min_stripe_size free space |
---|
| 2128 | + * after excluding 1MB. |
---|
2044 | 2129 | */ |
---|
2045 | | - skip_space = SZ_1M; |
---|
2046 | | - |
---|
2047 | | - /* |
---|
2048 | | - * we can use the free space in [0, skip_space - 1], subtract |
---|
2049 | | - * it from the total. |
---|
2050 | | - */ |
---|
2051 | | - if (avail_space && avail_space >= skip_space) |
---|
2052 | | - avail_space -= skip_space; |
---|
2053 | | - else |
---|
2054 | | - avail_space = 0; |
---|
2055 | | - |
---|
2056 | | - if (avail_space < min_stripe_size) |
---|
| 2130 | + if (avail_space <= SZ_1M + min_stripe_size) |
---|
2057 | 2131 | continue; |
---|
| 2132 | + |
---|
| 2133 | + avail_space -= SZ_1M; |
---|
2058 | 2134 | |
---|
2059 | 2135 | devices_info[i].dev = device; |
---|
2060 | 2136 | devices_info[i].max_avail = avail_space; |
---|
.. | .. |
---|
2069 | 2145 | |
---|
2070 | 2146 | i = nr_devices - 1; |
---|
2071 | 2147 | avail_space = 0; |
---|
2072 | | - while (nr_devices >= min_stripes) { |
---|
2073 | | - if (num_stripes > nr_devices) |
---|
2074 | | - num_stripes = nr_devices; |
---|
| 2148 | + while (nr_devices >= rattr->devs_min) { |
---|
| 2149 | + num_stripes = min(num_stripes, nr_devices); |
---|
2075 | 2150 | |
---|
2076 | 2151 | if (devices_info[i].max_avail >= min_stripe_size) { |
---|
2077 | 2152 | int j; |
---|
.. | .. |
---|
2108 | 2183 | { |
---|
2109 | 2184 | struct btrfs_fs_info *fs_info = btrfs_sb(dentry->d_sb); |
---|
2110 | 2185 | struct btrfs_super_block *disk_super = fs_info->super_copy; |
---|
2111 | | - struct list_head *head = &fs_info->space_info; |
---|
2112 | 2186 | struct btrfs_space_info *found; |
---|
2113 | 2187 | u64 total_used = 0; |
---|
2114 | 2188 | u64 total_free_data = 0; |
---|
2115 | 2189 | u64 total_free_meta = 0; |
---|
2116 | 2190 | int bits = dentry->d_sb->s_blocksize_bits; |
---|
2117 | | - __be32 *fsid = (__be32 *)fs_info->fsid; |
---|
| 2191 | + __be32 *fsid = (__be32 *)fs_info->fs_devices->fsid; |
---|
2118 | 2192 | unsigned factor = 1; |
---|
2119 | 2193 | struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; |
---|
2120 | 2194 | int ret; |
---|
2121 | 2195 | u64 thresh = 0; |
---|
2122 | 2196 | int mixed = 0; |
---|
2123 | 2197 | |
---|
2124 | | - rcu_read_lock(); |
---|
2125 | | - list_for_each_entry_rcu(found, head, list) { |
---|
| 2198 | + list_for_each_entry(found, &fs_info->space_info, list) { |
---|
2126 | 2199 | if (found->flags & BTRFS_BLOCK_GROUP_DATA) { |
---|
2127 | 2200 | int i; |
---|
2128 | 2201 | |
---|
.. | .. |
---|
2150 | 2223 | |
---|
2151 | 2224 | total_used += found->disk_used; |
---|
2152 | 2225 | } |
---|
2153 | | - |
---|
2154 | | - rcu_read_unlock(); |
---|
2155 | 2226 | |
---|
2156 | 2227 | buf->f_blocks = div_u64(btrfs_super_total_bytes(disk_super), factor); |
---|
2157 | 2228 | buf->f_blocks >>= bits; |
---|
.. | .. |
---|
2196 | 2267 | * calculated f_bavail. |
---|
2197 | 2268 | */ |
---|
2198 | 2269 | if (!mixed && block_rsv->space_info->full && |
---|
2199 | | - total_free_meta - thresh < block_rsv->size) |
---|
| 2270 | + (total_free_meta < thresh || total_free_meta - thresh < block_rsv->size)) |
---|
2200 | 2271 | buf->f_bavail = 0; |
---|
2201 | 2272 | |
---|
2202 | 2273 | buf->f_type = BTRFS_SUPER_MAGIC; |
---|
.. | .. |
---|
2209 | 2280 | buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]); |
---|
2210 | 2281 | buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]); |
---|
2211 | 2282 | /* Mask in the root object ID too, to disambiguate subvols */ |
---|
2212 | | - buf->f_fsid.val[0] ^= BTRFS_I(d_inode(dentry))->root->objectid >> 32; |
---|
2213 | | - buf->f_fsid.val[1] ^= BTRFS_I(d_inode(dentry))->root->objectid; |
---|
| 2283 | + buf->f_fsid.val[0] ^= |
---|
| 2284 | + BTRFS_I(d_inode(dentry))->root->root_key.objectid >> 32; |
---|
| 2285 | + buf->f_fsid.val[1] ^= |
---|
| 2286 | + BTRFS_I(d_inode(dentry))->root->root_key.objectid; |
---|
2214 | 2287 | |
---|
2215 | 2288 | return 0; |
---|
2216 | 2289 | } |
---|
.. | .. |
---|
2219 | 2292 | { |
---|
2220 | 2293 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
---|
2221 | 2294 | kill_anon_super(sb); |
---|
2222 | | - free_fs_info(fs_info); |
---|
| 2295 | + btrfs_free_fs_info(fs_info); |
---|
2223 | 2296 | } |
---|
2224 | 2297 | |
---|
2225 | 2298 | static struct file_system_type btrfs_fs_type = { |
---|
.. | .. |
---|
2252 | 2325 | } |
---|
2253 | 2326 | |
---|
2254 | 2327 | /* |
---|
2255 | | - * used by btrfsctl to scan devices when no FS is mounted |
---|
| 2328 | + * Used by /dev/btrfs-control for devices ioctls. |
---|
2256 | 2329 | */ |
---|
2257 | 2330 | static long btrfs_control_ioctl(struct file *file, unsigned int cmd, |
---|
2258 | 2331 | unsigned long arg) |
---|
.. | .. |
---|
2276 | 2349 | &btrfs_root_fs_type); |
---|
2277 | 2350 | ret = PTR_ERR_OR_ZERO(device); |
---|
2278 | 2351 | mutex_unlock(&uuid_mutex); |
---|
| 2352 | + break; |
---|
| 2353 | + case BTRFS_IOC_FORGET_DEV: |
---|
| 2354 | + ret = btrfs_forget_devices(vol->name); |
---|
2279 | 2355 | break; |
---|
2280 | 2356 | case BTRFS_IOC_DEVICES_READY: |
---|
2281 | 2357 | mutex_lock(&uuid_mutex); |
---|
.. | .. |
---|
2340 | 2416 | * device_list_mutex here as we only read the device data and the list |
---|
2341 | 2417 | * is protected by RCU. Even if a device is deleted during the list |
---|
2342 | 2418 | * traversals, we'll get valid data, the freeing callback will wait at |
---|
2343 | | - * least until until the rcu_read_unlock. |
---|
| 2419 | + * least until the rcu_read_unlock. |
---|
2344 | 2420 | */ |
---|
2345 | 2421 | rcu_read_lock(); |
---|
2346 | 2422 | list_for_each_entry_rcu(dev, &fs_info->fs_devices->devices, dev_list) { |
---|
.. | .. |
---|
2369 | 2445 | .show_devname = btrfs_show_devname, |
---|
2370 | 2446 | .alloc_inode = btrfs_alloc_inode, |
---|
2371 | 2447 | .destroy_inode = btrfs_destroy_inode, |
---|
| 2448 | + .free_inode = btrfs_free_inode, |
---|
2372 | 2449 | .statfs = btrfs_statfs, |
---|
2373 | 2450 | .remount_fs = btrfs_remount, |
---|
2374 | 2451 | .freeze_fs = btrfs_freeze, |
---|
.. | .. |
---|
2378 | 2455 | static const struct file_operations btrfs_ctl_fops = { |
---|
2379 | 2456 | .open = btrfs_control_open, |
---|
2380 | 2457 | .unlocked_ioctl = btrfs_control_ioctl, |
---|
2381 | | - .compat_ioctl = btrfs_control_ioctl, |
---|
| 2458 | + .compat_ioctl = compat_ptr_ioctl, |
---|
2382 | 2459 | .owner = THIS_MODULE, |
---|
2383 | 2460 | .llseek = noop_llseek, |
---|
2384 | 2461 | }; |
---|
.. | .. |
---|
2441 | 2518 | if (err) |
---|
2442 | 2519 | goto free_cachep; |
---|
2443 | 2520 | |
---|
2444 | | - err = extent_map_init(); |
---|
| 2521 | + err = extent_state_cache_init(); |
---|
2445 | 2522 | if (err) |
---|
2446 | 2523 | goto free_extent_io; |
---|
| 2524 | + |
---|
| 2525 | + err = extent_map_init(); |
---|
| 2526 | + if (err) |
---|
| 2527 | + goto free_extent_state_cache; |
---|
2447 | 2528 | |
---|
2448 | 2529 | err = ordered_data_init(); |
---|
2449 | 2530 | if (err) |
---|
.. | .. |
---|
2503 | 2584 | ordered_data_exit(); |
---|
2504 | 2585 | free_extent_map: |
---|
2505 | 2586 | extent_map_exit(); |
---|
| 2587 | +free_extent_state_cache: |
---|
| 2588 | + extent_state_cache_exit(); |
---|
2506 | 2589 | free_extent_io: |
---|
2507 | 2590 | extent_io_exit(); |
---|
2508 | 2591 | free_cachep: |
---|
.. | .. |
---|
2523 | 2606 | btrfs_prelim_ref_exit(); |
---|
2524 | 2607 | ordered_data_exit(); |
---|
2525 | 2608 | extent_map_exit(); |
---|
| 2609 | + extent_state_cache_exit(); |
---|
2526 | 2610 | extent_io_exit(); |
---|
2527 | 2611 | btrfs_interface_exit(); |
---|
2528 | 2612 | btrfs_end_io_wq_exit(); |
---|
.. | .. |
---|
2536 | 2620 | module_exit(exit_btrfs_fs) |
---|
2537 | 2621 | |
---|
2538 | 2622 | MODULE_LICENSE("GPL"); |
---|
| 2623 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
---|
| 2624 | +MODULE_SOFTDEP("pre: crc32c"); |
---|
| 2625 | +MODULE_SOFTDEP("pre: xxhash64"); |
---|
| 2626 | +MODULE_SOFTDEP("pre: sha256"); |
---|
| 2627 | +MODULE_SOFTDEP("pre: blake2b-256"); |
---|