1c1d7c514SDavid Sterba // SPDX-License-Identifier: GPL-2.0 26cbd5570SChris Mason /* 36cbd5570SChris Mason * Copyright (C) 2007 Oracle. All rights reserved. 46cbd5570SChris Mason */ 56cbd5570SChris Mason 64b82d6e4SYan #include <linux/blkdev.h> 72e635a27SChris Mason #include <linux/module.h> 82e635a27SChris Mason #include <linux/fs.h> 92e635a27SChris Mason #include <linux/pagemap.h> 102e635a27SChris Mason #include <linux/highmem.h> 112e635a27SChris Mason #include <linux/time.h> 122e635a27SChris Mason #include <linux/init.h> 13a9572a15SEric Paris #include <linux/seq_file.h> 142e635a27SChris Mason #include <linux/string.h> 152e635a27SChris Mason #include <linux/backing-dev.h> 164b82d6e4SYan #include <linux/mount.h> 1775dfe396SChris Mason #include <linux/writeback.h> 188fd17795SChris Mason #include <linux/statfs.h> 1908607c1bSChris Mason #include <linux/compat.h> 2095e05289SChris Mason #include <linux/parser.h> 21c59f8951SChris Mason #include <linux/ctype.h> 226da6abaeSChris Mason #include <linux/namei.h> 23a9218f6bSChris Mason #include <linux/miscdevice.h> 241bcbf313SQinghuang Feng #include <linux/magic.h> 255a0e3ad6STejun Heo #include <linux/slab.h> 2622c44fe6SJosef Bacik #include <linux/ratelimit.h> 279678c543SNikolay Borisov #include <linux/crc32c.h> 2855e301fdSFilipe Brandenburger #include <linux/btrfs.h> 299b569ea0SJosef Bacik #include "messages.h" 3016cdcec7SMiao Xie #include "delayed-inode.h" 312e635a27SChris Mason #include "ctree.h" 32e20d96d6SChris Mason #include "disk-io.h" 33d5719762SChris Mason #include "transaction.h" 342c90e5d6SChris Mason #include "btrfs_inode.h" 353a686375SChris Mason #include "print-tree.h" 3663541927SFilipe David Borba Manana #include "props.h" 375103e947SJosef Bacik #include "xattr.h" 38103c1972SChristoph Hellwig #include "bio.h" 39be6e8dc0SBalaji Rao #include "export.h" 40c8b97818SChris Mason #include "compression.h" 419c5085c1SJosef Bacik #include "rcu-string.h" 428dabb742SStefan Behrens #include "dev-replace.h" 4374255aa0SJosef Bacik #include "free-space-cache.h" 44b9e9a6cbSWang Shilong #include "backref.h" 458719aaaeSJosef Bacik #include "space-info.h" 4689439109SDavid Sterba #include "sysfs.h" 47b70f5097SNaohiro Aota #include "zoned.h" 48dc11dd5dSJosef Bacik #include "tests/btrfs-tests.h" 49aac0023cSJosef Bacik #include "block-group.h" 50b0643e59SDennis Zhou #include "discard.h" 51d3982100SMark Fasheh #include "qgroup.h" 52b8bea09aSQu Wenruo #include "raid56.h" 53c7f13d42SJosef Bacik #include "fs.h" 5407e81dc9SJosef Bacik #include "accessors.h" 5559b818e0SJosef Bacik #include "defrag.h" 56f2b39277SJosef Bacik #include "dir-item.h" 577572dec8SJosef Bacik #include "ioctl.h" 582fc6822cSJosef Bacik #include "scrub.h" 595c11adccSJosef Bacik #include "verity.h" 60c03b2207SJosef Bacik #include "super.h" 61cfc2de0fSBoris Burkov #include "extent-tree.h" 621abe9b8aSliubo #define CREATE_TRACE_POINTS 631abe9b8aSliubo #include <trace/events/btrfs.h> 641abe9b8aSliubo 65b87221deSAlexey Dobriyan static const struct super_operations btrfs_super_ops; 6672fa39f5SMisono, Tomohiro 6772fa39f5SMisono, Tomohiro /* 6872fa39f5SMisono, Tomohiro * Types for mounting the default subvolume and a subvolume explicitly 6972fa39f5SMisono, Tomohiro * requested by subvol=/path. That way the callchain is straightforward and we 7072fa39f5SMisono, Tomohiro * don't have to play tricks with the mount options and recursive calls to 7172fa39f5SMisono, Tomohiro * btrfs_mount. 72312c89fbSMisono, Tomohiro * 73312c89fbSMisono, Tomohiro * The new btrfs_root_fs_type also servers as a tag for the bdev_holder. 7472fa39f5SMisono, Tomohiro */ 75830c4adbSJosef Bacik static struct file_system_type btrfs_fs_type; 7672fa39f5SMisono, Tomohiro static struct file_system_type btrfs_root_fs_type; 77e20d96d6SChris Mason 780723a047SHarald Hoyer static int btrfs_remount(struct super_block *sb, int *flags, char *data); 790723a047SHarald Hoyer 80e20d96d6SChris Mason static void btrfs_put_super(struct super_block *sb) 81e20d96d6SChris Mason { 826bccf3abSJeff Mahoney close_ctree(btrfs_sb(sb)); 83e20d96d6SChris Mason } 842e635a27SChris Mason 8595e05289SChris Mason enum { 86416a7202SDavid Sterba Opt_acl, Opt_noacl, 87416a7202SDavid Sterba Opt_clear_cache, 88416a7202SDavid Sterba Opt_commit_interval, 89416a7202SDavid Sterba Opt_compress, 90416a7202SDavid Sterba Opt_compress_force, 91416a7202SDavid Sterba Opt_compress_force_type, 92416a7202SDavid Sterba Opt_compress_type, 93416a7202SDavid Sterba Opt_degraded, 94416a7202SDavid Sterba Opt_device, 95416a7202SDavid Sterba Opt_fatal_errors, 96416a7202SDavid Sterba Opt_flushoncommit, Opt_noflushoncommit, 97416a7202SDavid Sterba Opt_max_inline, 98416a7202SDavid Sterba Opt_barrier, Opt_nobarrier, 99416a7202SDavid Sterba Opt_datacow, Opt_nodatacow, 100416a7202SDavid Sterba Opt_datasum, Opt_nodatasum, 101416a7202SDavid Sterba Opt_defrag, Opt_nodefrag, 102416a7202SDavid Sterba Opt_discard, Opt_nodiscard, 103b0643e59SDennis Zhou Opt_discard_mode, 104416a7202SDavid Sterba Opt_norecovery, 105416a7202SDavid Sterba Opt_ratio, 106416a7202SDavid Sterba Opt_rescan_uuid_tree, 107416a7202SDavid Sterba Opt_skip_balance, 108416a7202SDavid Sterba Opt_space_cache, Opt_no_space_cache, 109416a7202SDavid Sterba Opt_space_cache_version, 110416a7202SDavid Sterba Opt_ssd, Opt_nossd, 111416a7202SDavid Sterba Opt_ssd_spread, Opt_nossd_spread, 112416a7202SDavid Sterba Opt_subvol, 11337becec9SOmar Sandoval Opt_subvol_empty, 114416a7202SDavid Sterba Opt_subvolid, 115416a7202SDavid Sterba Opt_thread_pool, 116416a7202SDavid Sterba Opt_treelog, Opt_notreelog, 117416a7202SDavid Sterba Opt_user_subvol_rm_allowed, 118416a7202SDavid Sterba 11974ef0018SQu Wenruo /* Rescue options */ 12074ef0018SQu Wenruo Opt_rescue, 12174ef0018SQu Wenruo Opt_usebackuproot, 12274ef0018SQu Wenruo Opt_nologreplay, 12342437a63SJosef Bacik Opt_ignorebadroots, 124882dbe0cSJosef Bacik Opt_ignoredatacsums, 1259037d3cbSJosef Bacik Opt_rescue_all, 12674ef0018SQu Wenruo 127416a7202SDavid Sterba /* Deprecated options */ 128416a7202SDavid Sterba Opt_recovery, 1295297199aSNikolay Borisov Opt_inode_cache, Opt_noinode_cache, 130416a7202SDavid Sterba 131416a7202SDavid Sterba /* Debugging options */ 132416a7202SDavid Sterba Opt_check_integrity, 13370f6d82eSOmar Sandoval Opt_check_integrity_including_extent_data, 134416a7202SDavid Sterba Opt_check_integrity_print_mask, 135416a7202SDavid Sterba Opt_enospc_debug, Opt_noenospc_debug, 136d0bd4560SJosef Bacik #ifdef CONFIG_BTRFS_DEBUG 137d0bd4560SJosef Bacik Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all, 138d0bd4560SJosef Bacik #endif 139fb592373SJosef Bacik #ifdef CONFIG_BTRFS_FS_REF_VERIFY 140fb592373SJosef Bacik Opt_ref_verify, 141fb592373SJosef Bacik #endif 1429555c6c1SIlya Dryomov Opt_err, 14395e05289SChris Mason }; 14495e05289SChris Mason 1454d4ab6d6SDavid Sterba static const match_table_t tokens = { 146416a7202SDavid Sterba {Opt_acl, "acl"}, 147416a7202SDavid Sterba {Opt_noacl, "noacl"}, 148416a7202SDavid Sterba {Opt_clear_cache, "clear_cache"}, 149416a7202SDavid Sterba {Opt_commit_interval, "commit=%u"}, 150c8b97818SChris Mason {Opt_compress, "compress"}, 151261507a0SLi Zefan {Opt_compress_type, "compress=%s"}, 152a555f810SChris Mason {Opt_compress_force, "compress-force"}, 153261507a0SLi Zefan {Opt_compress_force_type, "compress-force=%s"}, 154416a7202SDavid Sterba {Opt_degraded, "degraded"}, 155416a7202SDavid Sterba {Opt_device, "device=%s"}, 156416a7202SDavid Sterba {Opt_fatal_errors, "fatal_errors=%s"}, 157dccae999SSage Weil {Opt_flushoncommit, "flushoncommit"}, 1582c9ee856SQu Wenruo {Opt_noflushoncommit, "noflushoncommit"}, 1594b9465cbSChris Mason {Opt_inode_cache, "inode_cache"}, 1603818aea2SQu Wenruo {Opt_noinode_cache, "noinode_cache"}, 161416a7202SDavid Sterba {Opt_max_inline, "max_inline=%s"}, 162416a7202SDavid Sterba {Opt_barrier, "barrier"}, 163416a7202SDavid Sterba {Opt_nobarrier, "nobarrier"}, 164416a7202SDavid Sterba {Opt_datacow, "datacow"}, 165416a7202SDavid Sterba {Opt_nodatacow, "nodatacow"}, 166416a7202SDavid Sterba {Opt_datasum, "datasum"}, 167416a7202SDavid Sterba {Opt_nodatasum, "nodatasum"}, 168416a7202SDavid Sterba {Opt_defrag, "autodefrag"}, 169416a7202SDavid Sterba {Opt_nodefrag, "noautodefrag"}, 170416a7202SDavid Sterba {Opt_discard, "discard"}, 171b0643e59SDennis Zhou {Opt_discard_mode, "discard=%s"}, 172416a7202SDavid Sterba {Opt_nodiscard, "nodiscard"}, 173416a7202SDavid Sterba {Opt_norecovery, "norecovery"}, 174416a7202SDavid Sterba {Opt_ratio, "metadata_ratio=%u"}, 175416a7202SDavid Sterba {Opt_rescan_uuid_tree, "rescan_uuid_tree"}, 1769555c6c1SIlya Dryomov {Opt_skip_balance, "skip_balance"}, 177416a7202SDavid Sterba {Opt_space_cache, "space_cache"}, 178416a7202SDavid Sterba {Opt_no_space_cache, "nospace_cache"}, 179416a7202SDavid Sterba {Opt_space_cache_version, "space_cache=%s"}, 180416a7202SDavid Sterba {Opt_ssd, "ssd"}, 181416a7202SDavid Sterba {Opt_nossd, "nossd"}, 182416a7202SDavid Sterba {Opt_ssd_spread, "ssd_spread"}, 183416a7202SDavid Sterba {Opt_nossd_spread, "nossd_spread"}, 184416a7202SDavid Sterba {Opt_subvol, "subvol=%s"}, 18537becec9SOmar Sandoval {Opt_subvol_empty, "subvol="}, 186416a7202SDavid Sterba {Opt_subvolid, "subvolid=%s"}, 187416a7202SDavid Sterba {Opt_thread_pool, "thread_pool=%u"}, 188416a7202SDavid Sterba {Opt_treelog, "treelog"}, 189416a7202SDavid Sterba {Opt_notreelog, "notreelog"}, 190416a7202SDavid Sterba {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, 191416a7202SDavid Sterba 19274ef0018SQu Wenruo /* Rescue options */ 19374ef0018SQu Wenruo {Opt_rescue, "rescue=%s"}, 19474ef0018SQu Wenruo /* Deprecated, with alias rescue=nologreplay */ 19574ef0018SQu Wenruo {Opt_nologreplay, "nologreplay"}, 19674ef0018SQu Wenruo /* Deprecated, with alias rescue=usebackuproot */ 19774ef0018SQu Wenruo {Opt_usebackuproot, "usebackuproot"}, 19874ef0018SQu Wenruo 199416a7202SDavid Sterba /* Deprecated options */ 200416a7202SDavid Sterba {Opt_recovery, "recovery"}, 201416a7202SDavid Sterba 202416a7202SDavid Sterba /* Debugging options */ 20321adbd5cSStefan Behrens {Opt_check_integrity, "check_int"}, 20421adbd5cSStefan Behrens {Opt_check_integrity_including_extent_data, "check_int_data"}, 20502453bdeSAnand Jain {Opt_check_integrity_print_mask, "check_int_print_mask=%u"}, 206416a7202SDavid Sterba {Opt_enospc_debug, "enospc_debug"}, 207416a7202SDavid Sterba {Opt_noenospc_debug, "noenospc_debug"}, 208d0bd4560SJosef Bacik #ifdef CONFIG_BTRFS_DEBUG 209d0bd4560SJosef Bacik {Opt_fragment_data, "fragment=data"}, 210d0bd4560SJosef Bacik {Opt_fragment_metadata, "fragment=metadata"}, 211d0bd4560SJosef Bacik {Opt_fragment_all, "fragment=all"}, 212d0bd4560SJosef Bacik #endif 213fb592373SJosef Bacik #ifdef CONFIG_BTRFS_FS_REF_VERIFY 214fb592373SJosef Bacik {Opt_ref_verify, "ref_verify"}, 215fb592373SJosef Bacik #endif 21633268eafSJosef Bacik {Opt_err, NULL}, 21795e05289SChris Mason }; 21895e05289SChris Mason 21974ef0018SQu Wenruo static const match_table_t rescue_tokens = { 22074ef0018SQu Wenruo {Opt_usebackuproot, "usebackuproot"}, 22174ef0018SQu Wenruo {Opt_nologreplay, "nologreplay"}, 22242437a63SJosef Bacik {Opt_ignorebadroots, "ignorebadroots"}, 22342437a63SJosef Bacik {Opt_ignorebadroots, "ibadroots"}, 224882dbe0cSJosef Bacik {Opt_ignoredatacsums, "ignoredatacsums"}, 225882dbe0cSJosef Bacik {Opt_ignoredatacsums, "idatacsums"}, 2269037d3cbSJosef Bacik {Opt_rescue_all, "all"}, 22774ef0018SQu Wenruo {Opt_err, NULL}, 22874ef0018SQu Wenruo }; 22974ef0018SQu Wenruo 230d70bf748SJosef Bacik static bool check_ro_option(struct btrfs_fs_info *fs_info, unsigned long opt, 231d70bf748SJosef Bacik const char *opt_name) 232d70bf748SJosef Bacik { 233d70bf748SJosef Bacik if (fs_info->mount_opt & opt) { 234d70bf748SJosef Bacik btrfs_err(fs_info, "%s must be used with ro mount option", 235d70bf748SJosef Bacik opt_name); 236d70bf748SJosef Bacik return true; 237d70bf748SJosef Bacik } 238d70bf748SJosef Bacik return false; 239d70bf748SJosef Bacik } 240d70bf748SJosef Bacik 24174ef0018SQu Wenruo static int parse_rescue_options(struct btrfs_fs_info *info, const char *options) 24274ef0018SQu Wenruo { 24374ef0018SQu Wenruo char *opts; 24474ef0018SQu Wenruo char *orig; 24574ef0018SQu Wenruo char *p; 24674ef0018SQu Wenruo substring_t args[MAX_OPT_ARGS]; 24774ef0018SQu Wenruo int ret = 0; 24874ef0018SQu Wenruo 24974ef0018SQu Wenruo opts = kstrdup(options, GFP_KERNEL); 25074ef0018SQu Wenruo if (!opts) 25174ef0018SQu Wenruo return -ENOMEM; 25274ef0018SQu Wenruo orig = opts; 25374ef0018SQu Wenruo 25474ef0018SQu Wenruo while ((p = strsep(&opts, ":")) != NULL) { 25574ef0018SQu Wenruo int token; 25674ef0018SQu Wenruo 25774ef0018SQu Wenruo if (!*p) 25874ef0018SQu Wenruo continue; 25974ef0018SQu Wenruo token = match_token(p, rescue_tokens, args); 26074ef0018SQu Wenruo switch (token){ 26174ef0018SQu Wenruo case Opt_usebackuproot: 26274ef0018SQu Wenruo btrfs_info(info, 26374ef0018SQu Wenruo "trying to use backup root at mount time"); 26474ef0018SQu Wenruo btrfs_set_opt(info->mount_opt, USEBACKUPROOT); 26574ef0018SQu Wenruo break; 26674ef0018SQu Wenruo case Opt_nologreplay: 26774ef0018SQu Wenruo btrfs_set_and_info(info, NOLOGREPLAY, 26874ef0018SQu Wenruo "disabling log replay at mount time"); 26974ef0018SQu Wenruo break; 27042437a63SJosef Bacik case Opt_ignorebadroots: 27142437a63SJosef Bacik btrfs_set_and_info(info, IGNOREBADROOTS, 27242437a63SJosef Bacik "ignoring bad roots"); 27342437a63SJosef Bacik break; 274882dbe0cSJosef Bacik case Opt_ignoredatacsums: 275882dbe0cSJosef Bacik btrfs_set_and_info(info, IGNOREDATACSUMS, 276882dbe0cSJosef Bacik "ignoring data csums"); 277882dbe0cSJosef Bacik break; 2789037d3cbSJosef Bacik case Opt_rescue_all: 2799037d3cbSJosef Bacik btrfs_info(info, "enabling all of the rescue options"); 2809037d3cbSJosef Bacik btrfs_set_and_info(info, IGNOREDATACSUMS, 2819037d3cbSJosef Bacik "ignoring data csums"); 2829037d3cbSJosef Bacik btrfs_set_and_info(info, IGNOREBADROOTS, 2839037d3cbSJosef Bacik "ignoring bad roots"); 2849037d3cbSJosef Bacik btrfs_set_and_info(info, NOLOGREPLAY, 2859037d3cbSJosef Bacik "disabling log replay at mount time"); 2869037d3cbSJosef Bacik break; 28774ef0018SQu Wenruo case Opt_err: 28874ef0018SQu Wenruo btrfs_info(info, "unrecognized rescue option '%s'", p); 28974ef0018SQu Wenruo ret = -EINVAL; 29074ef0018SQu Wenruo goto out; 29174ef0018SQu Wenruo default: 29274ef0018SQu Wenruo break; 29374ef0018SQu Wenruo } 29474ef0018SQu Wenruo 29574ef0018SQu Wenruo } 29674ef0018SQu Wenruo out: 29774ef0018SQu Wenruo kfree(orig); 29874ef0018SQu Wenruo return ret; 29974ef0018SQu Wenruo } 30074ef0018SQu Wenruo 301edf24abeSChristoph Hellwig /* 302edf24abeSChristoph Hellwig * Regular mount options parser. Everything that is needed only when 303edf24abeSChristoph Hellwig * reading in a new superblock is parsed here. 30449b25e05SJeff Mahoney * XXX JDM: This needs to be cleaned up for remount. 305edf24abeSChristoph Hellwig */ 3062ff7e61eSJeff Mahoney int btrfs_parse_options(struct btrfs_fs_info *info, char *options, 30796da0919SQu Wenruo unsigned long new_flags) 30895e05289SChris Mason { 30995e05289SChris Mason substring_t args[MAX_OPT_ARGS]; 310e215772cSMisono, Tomohiro char *p, *num; 3114543df7eSChris Mason int intarg; 312a7a3f7caSSage Weil int ret = 0; 313261507a0SLi Zefan char *compress_type; 314261507a0SLi Zefan bool compress_force = false; 315b7c47bbbSTsutomu Itoh enum btrfs_compression_type saved_compress_type; 31627942c99SDavid Sterba int saved_compress_level; 317b7c47bbbSTsutomu Itoh bool saved_compress_force; 318b7c47bbbSTsutomu Itoh int no_compress = 0; 319dbecac26SMaciej S. Szmigiero const bool remounting = test_bit(BTRFS_FS_STATE_REMOUNTING, &info->fs_state); 320b6cda9bcSChris Mason 3210b246afaSJeff Mahoney if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE)) 32270f6d82eSOmar Sandoval btrfs_set_opt(info->mount_opt, FREE_SPACE_TREE); 32394846229SBoris Burkov else if (btrfs_free_space_cache_v1_active(info)) { 3245d1ab66cSNaohiro Aota if (btrfs_is_zoned(info)) { 3255d1ab66cSNaohiro Aota btrfs_info(info, 3265d1ab66cSNaohiro Aota "zoned: clearing existing space cache"); 3275d1ab66cSNaohiro Aota btrfs_set_super_cache_generation(info->super_copy, 0); 3285d1ab66cSNaohiro Aota } else { 32973bc1876SJosef Bacik btrfs_set_opt(info->mount_opt, SPACE_CACHE); 3305d1ab66cSNaohiro Aota } 3315d1ab66cSNaohiro Aota } 33273bc1876SJosef Bacik 33396da0919SQu Wenruo /* 33496da0919SQu Wenruo * Even the options are empty, we still need to do extra check 33596da0919SQu Wenruo * against new flags 33696da0919SQu Wenruo */ 33795e05289SChris Mason if (!options) 33896da0919SQu Wenruo goto check; 33995e05289SChris Mason 34095e05289SChris Mason while ((p = strsep(&options, ",")) != NULL) { 34195e05289SChris Mason int token; 34295e05289SChris Mason if (!*p) 34395e05289SChris Mason continue; 34495e05289SChris Mason 34595e05289SChris Mason token = match_token(p, tokens, args); 34695e05289SChris Mason switch (token) { 347dfe25020SChris Mason case Opt_degraded: 3480b246afaSJeff Mahoney btrfs_info(info, "allowing degraded mounts"); 349dfe25020SChris Mason btrfs_set_opt(info->mount_opt, DEGRADED); 350dfe25020SChris Mason break; 35195e05289SChris Mason case Opt_subvol: 35237becec9SOmar Sandoval case Opt_subvol_empty: 35373f73415SJosef Bacik case Opt_subvolid: 35443e570b0SChristoph Hellwig case Opt_device: 355edf24abeSChristoph Hellwig /* 356fa59f27cSAnand Jain * These are parsed by btrfs_parse_subvol_options or 357fa59f27cSAnand Jain * btrfs_parse_device_options and can be ignored here. 358edf24abeSChristoph Hellwig */ 35995e05289SChris Mason break; 360b6cda9bcSChris Mason case Opt_nodatasum: 3613cdde224SJeff Mahoney btrfs_set_and_info(info, NODATASUM, 36207802534SQu Wenruo "setting nodatasum"); 363be20aa9dSChris Mason break; 364d399167dSQu Wenruo case Opt_datasum: 3653cdde224SJeff Mahoney if (btrfs_test_opt(info, NODATASUM)) { 3663cdde224SJeff Mahoney if (btrfs_test_opt(info, NODATACOW)) 3670b246afaSJeff Mahoney btrfs_info(info, 3685d163e0eSJeff Mahoney "setting datasum, datacow enabled"); 369d399167dSQu Wenruo else 3700b246afaSJeff Mahoney btrfs_info(info, "setting datasum"); 37107802534SQu Wenruo } 372d399167dSQu Wenruo btrfs_clear_opt(info->mount_opt, NODATACOW); 373d399167dSQu Wenruo btrfs_clear_opt(info->mount_opt, NODATASUM); 374d399167dSQu Wenruo break; 375be20aa9dSChris Mason case Opt_nodatacow: 3763cdde224SJeff Mahoney if (!btrfs_test_opt(info, NODATACOW)) { 3773cdde224SJeff Mahoney if (!btrfs_test_opt(info, COMPRESS) || 3783cdde224SJeff Mahoney !btrfs_test_opt(info, FORCE_COMPRESS)) { 3790b246afaSJeff Mahoney btrfs_info(info, 380efe120a0SFrank Holton "setting nodatacow, compression disabled"); 381bedb2ccaSAndrei Popa } else { 3820b246afaSJeff Mahoney btrfs_info(info, "setting nodatacow"); 383bedb2ccaSAndrei Popa } 38407802534SQu Wenruo } 385bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, COMPRESS); 386bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS); 387be20aa9dSChris Mason btrfs_set_opt(info->mount_opt, NODATACOW); 388be20aa9dSChris Mason btrfs_set_opt(info->mount_opt, NODATASUM); 389b6cda9bcSChris Mason break; 390a258af7aSQu Wenruo case Opt_datacow: 3913cdde224SJeff Mahoney btrfs_clear_and_info(info, NODATACOW, 39207802534SQu Wenruo "setting datacow"); 393a258af7aSQu Wenruo break; 394a555f810SChris Mason case Opt_compress_force: 395261507a0SLi Zefan case Opt_compress_force_type: 396261507a0SLi Zefan compress_force = true; 397c730ae0cSMarcos Paulo de Souza fallthrough; 398261507a0SLi Zefan case Opt_compress: 399261507a0SLi Zefan case Opt_compress_type: 4003cdde224SJeff Mahoney saved_compress_type = btrfs_test_opt(info, 4013cdde224SJeff Mahoney COMPRESS) ? 402b7c47bbbSTsutomu Itoh info->compress_type : BTRFS_COMPRESS_NONE; 403b7c47bbbSTsutomu Itoh saved_compress_force = 4043cdde224SJeff Mahoney btrfs_test_opt(info, FORCE_COMPRESS); 40527942c99SDavid Sterba saved_compress_level = info->compress_level; 406261507a0SLi Zefan if (token == Opt_compress || 407261507a0SLi Zefan token == Opt_compress_force || 408a7164fa4SDavid Sterba strncmp(args[0].from, "zlib", 4) == 0) { 409261507a0SLi Zefan compress_type = "zlib"; 410eae8d825SQu Wenruo 411261507a0SLi Zefan info->compress_type = BTRFS_COMPRESS_ZLIB; 412eae8d825SQu Wenruo info->compress_level = BTRFS_ZLIB_DEFAULT_LEVEL; 413eae8d825SQu Wenruo /* 414eae8d825SQu Wenruo * args[0] contains uninitialized data since 415eae8d825SQu Wenruo * for these tokens we don't expect any 416eae8d825SQu Wenruo * parameter. 417eae8d825SQu Wenruo */ 418eae8d825SQu Wenruo if (token != Opt_compress && 419eae8d825SQu Wenruo token != Opt_compress_force) 420f51d2b59SDavid Sterba info->compress_level = 421d0ab62ceSDennis Zhou btrfs_compress_str2level( 422d0ab62ceSDennis Zhou BTRFS_COMPRESS_ZLIB, 423d0ab62ceSDennis Zhou args[0].from + 4); 424063849eaSArnd Hannemann btrfs_set_opt(info->mount_opt, COMPRESS); 425bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, NODATACOW); 426bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, NODATASUM); 427b7c47bbbSTsutomu Itoh no_compress = 0; 428a7164fa4SDavid Sterba } else if (strncmp(args[0].from, "lzo", 3) == 0) { 429a6fa6faeSLi Zefan compress_type = "lzo"; 430a6fa6faeSLi Zefan info->compress_type = BTRFS_COMPRESS_LZO; 431282dd7d7SMarcos Paulo de Souza info->compress_level = 0; 432063849eaSArnd Hannemann btrfs_set_opt(info->mount_opt, COMPRESS); 433bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, NODATACOW); 434bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, NODATASUM); 4352b0ce2c2SMitch Harder btrfs_set_fs_incompat(info, COMPRESS_LZO); 436b7c47bbbSTsutomu Itoh no_compress = 0; 4373f93aef5SDennis Zhou } else if (strncmp(args[0].from, "zstd", 4) == 0) { 4385c1aab1dSNick Terrell compress_type = "zstd"; 4395c1aab1dSNick Terrell info->compress_type = BTRFS_COMPRESS_ZSTD; 4403f93aef5SDennis Zhou info->compress_level = 4413f93aef5SDennis Zhou btrfs_compress_str2level( 4423f93aef5SDennis Zhou BTRFS_COMPRESS_ZSTD, 4433f93aef5SDennis Zhou args[0].from + 4); 4445c1aab1dSNick Terrell btrfs_set_opt(info->mount_opt, COMPRESS); 4455c1aab1dSNick Terrell btrfs_clear_opt(info->mount_opt, NODATACOW); 4465c1aab1dSNick Terrell btrfs_clear_opt(info->mount_opt, NODATASUM); 4475c1aab1dSNick Terrell btrfs_set_fs_incompat(info, COMPRESS_ZSTD); 4485c1aab1dSNick Terrell no_compress = 0; 449063849eaSArnd Hannemann } else if (strncmp(args[0].from, "no", 2) == 0) { 450063849eaSArnd Hannemann compress_type = "no"; 45127942c99SDavid Sterba info->compress_level = 0; 45227942c99SDavid Sterba info->compress_type = 0; 453063849eaSArnd Hannemann btrfs_clear_opt(info->mount_opt, COMPRESS); 454063849eaSArnd Hannemann btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS); 455063849eaSArnd Hannemann compress_force = false; 456b7c47bbbSTsutomu Itoh no_compress++; 457261507a0SLi Zefan } else { 458e3a4167cSDavid Sterba btrfs_err(info, "unrecognized compression value %s", 459e3a4167cSDavid Sterba args[0].from); 460261507a0SLi Zefan ret = -EINVAL; 461261507a0SLi Zefan goto out; 462261507a0SLi Zefan } 463261507a0SLi Zefan 464261507a0SLi Zefan if (compress_force) { 465b7c47bbbSTsutomu Itoh btrfs_set_opt(info->mount_opt, FORCE_COMPRESS); 466143f3636SDavid Sterba } else { 4674027e0f4SWang Shilong /* 4684027e0f4SWang Shilong * If we remount from compress-force=xxx to 4694027e0f4SWang Shilong * compress=xxx, we need clear FORCE_COMPRESS 4704027e0f4SWang Shilong * flag, otherwise, there is no way for users 4714027e0f4SWang Shilong * to disable forcible compression separately. 4724027e0f4SWang Shilong */ 4734027e0f4SWang Shilong btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS); 474a7e252afSMiao Xie } 47527942c99SDavid Sterba if (no_compress == 1) { 47627942c99SDavid Sterba btrfs_info(info, "use no compression"); 47727942c99SDavid Sterba } else if ((info->compress_type != saved_compress_type) || 47827942c99SDavid Sterba (compress_force != saved_compress_force) || 47927942c99SDavid Sterba (info->compress_level != saved_compress_level)) { 480f51d2b59SDavid Sterba btrfs_info(info, "%s %s compression, level %d", 481b7c47bbbSTsutomu Itoh (compress_force) ? "force" : "use", 482f51d2b59SDavid Sterba compress_type, info->compress_level); 483b7c47bbbSTsutomu Itoh } 484b7c47bbbSTsutomu Itoh compress_force = false; 485a555f810SChris Mason break; 486e18e4809SChris Mason case Opt_ssd: 4873cdde224SJeff Mahoney btrfs_set_and_info(info, SSD, 488583b7231SHans van Kranenburg "enabling ssd optimizations"); 489951e7966SAdam Borowski btrfs_clear_opt(info->mount_opt, NOSSD); 490e18e4809SChris Mason break; 491451d7585SChris Mason case Opt_ssd_spread: 492583b7231SHans van Kranenburg btrfs_set_and_info(info, SSD, 493583b7231SHans van Kranenburg "enabling ssd optimizations"); 4943cdde224SJeff Mahoney btrfs_set_and_info(info, SSD_SPREAD, 495583b7231SHans van Kranenburg "using spread ssd allocation scheme"); 496951e7966SAdam Borowski btrfs_clear_opt(info->mount_opt, NOSSD); 497451d7585SChris Mason break; 4983b30c22fSChris Mason case Opt_nossd: 499583b7231SHans van Kranenburg btrfs_set_opt(info->mount_opt, NOSSD); 500583b7231SHans van Kranenburg btrfs_clear_and_info(info, SSD, 501583b7231SHans van Kranenburg "not using ssd optimizations"); 502c730ae0cSMarcos Paulo de Souza fallthrough; 50362b8e077SHoward McLauchlan case Opt_nossd_spread: 504583b7231SHans van Kranenburg btrfs_clear_and_info(info, SSD_SPREAD, 505583b7231SHans van Kranenburg "not using spread ssd allocation scheme"); 5063b30c22fSChris Mason break; 507842bef58SQu Wenruo case Opt_barrier: 5083cdde224SJeff Mahoney btrfs_clear_and_info(info, NOBARRIER, 50907802534SQu Wenruo "turning on barriers"); 510842bef58SQu Wenruo break; 51121ad10cfSChris Mason case Opt_nobarrier: 5123cdde224SJeff Mahoney btrfs_set_and_info(info, NOBARRIER, 51307802534SQu Wenruo "turning off barriers"); 51421ad10cfSChris Mason break; 5154543df7eSChris Mason case Opt_thread_pool: 5162c334e87SWang Shilong ret = match_int(&args[0], &intarg); 5172c334e87SWang Shilong if (ret) { 518e3a4167cSDavid Sterba btrfs_err(info, "unrecognized thread_pool value %s", 519e3a4167cSDavid Sterba args[0].from); 5202c334e87SWang Shilong goto out; 521f7b885beSAnand Jain } else if (intarg == 0) { 522e3a4167cSDavid Sterba btrfs_err(info, "invalid value 0 for thread_pool"); 5232c334e87SWang Shilong ret = -EINVAL; 5242c334e87SWang Shilong goto out; 5252c334e87SWang Shilong } 526f7b885beSAnand Jain info->thread_pool_size = intarg; 5274543df7eSChris Mason break; 5286f568d35SChris Mason case Opt_max_inline: 529edf24abeSChristoph Hellwig num = match_strdup(&args[0]); 5306f568d35SChris Mason if (num) { 53191748467SAkinobu Mita info->max_inline = memparse(num, NULL); 5326f568d35SChris Mason kfree(num); 5336f568d35SChris Mason 53415ada040SChris Mason if (info->max_inline) { 535feb5f965SMitch Harder info->max_inline = min_t(u64, 53615ada040SChris Mason info->max_inline, 5370b246afaSJeff Mahoney info->sectorsize); 53815ada040SChris Mason } 5390b246afaSJeff Mahoney btrfs_info(info, "max_inline at %llu", 540c1c9ff7cSGeert Uytterhoeven info->max_inline); 5412c334e87SWang Shilong } else { 5422c334e87SWang Shilong ret = -ENOMEM; 5432c334e87SWang Shilong goto out; 5446f568d35SChris Mason } 5456f568d35SChris Mason break; 546bd0330adSQu Wenruo case Opt_acl: 54745ff35d6SGuangliang Zhao #ifdef CONFIG_BTRFS_FS_POSIX_ACL 5481751e8a6SLinus Torvalds info->sb->s_flags |= SB_POSIXACL; 549bd0330adSQu Wenruo break; 55045ff35d6SGuangliang Zhao #else 5510b246afaSJeff Mahoney btrfs_err(info, "support for ACL not compiled in!"); 55245ff35d6SGuangliang Zhao ret = -EINVAL; 55345ff35d6SGuangliang Zhao goto out; 55445ff35d6SGuangliang Zhao #endif 55533268eafSJosef Bacik case Opt_noacl: 5561751e8a6SLinus Torvalds info->sb->s_flags &= ~SB_POSIXACL; 55733268eafSJosef Bacik break; 5583a5e1404SSage Weil case Opt_notreelog: 5593cdde224SJeff Mahoney btrfs_set_and_info(info, NOTREELOG, 56007802534SQu Wenruo "disabling tree log"); 5613a5e1404SSage Weil break; 562a88998f2SQu Wenruo case Opt_treelog: 5633cdde224SJeff Mahoney btrfs_clear_and_info(info, NOTREELOG, 56407802534SQu Wenruo "enabling tree log"); 565a88998f2SQu Wenruo break; 566fed8f166SQu Wenruo case Opt_norecovery: 56796da0919SQu Wenruo case Opt_nologreplay: 56874ef0018SQu Wenruo btrfs_warn(info, 56974ef0018SQu Wenruo "'nologreplay' is deprecated, use 'rescue=nologreplay' instead"); 5703cdde224SJeff Mahoney btrfs_set_and_info(info, NOLOGREPLAY, 57196da0919SQu Wenruo "disabling log replay at mount time"); 57296da0919SQu Wenruo break; 573dccae999SSage Weil case Opt_flushoncommit: 5743cdde224SJeff Mahoney btrfs_set_and_info(info, FLUSHONCOMMIT, 57507802534SQu Wenruo "turning on flush-on-commit"); 576dccae999SSage Weil break; 5772c9ee856SQu Wenruo case Opt_noflushoncommit: 5783cdde224SJeff Mahoney btrfs_clear_and_info(info, FLUSHONCOMMIT, 57907802534SQu Wenruo "turning off flush-on-commit"); 5802c9ee856SQu Wenruo break; 58197e728d4SJosef Bacik case Opt_ratio: 5822c334e87SWang Shilong ret = match_int(&args[0], &intarg); 583e3a4167cSDavid Sterba if (ret) { 584e3a4167cSDavid Sterba btrfs_err(info, "unrecognized metadata_ratio value %s", 585e3a4167cSDavid Sterba args[0].from); 5862c334e87SWang Shilong goto out; 587e3a4167cSDavid Sterba } 58897e728d4SJosef Bacik info->metadata_ratio = intarg; 589764cb8b4SAnand Jain btrfs_info(info, "metadata ratio %u", 59097e728d4SJosef Bacik info->metadata_ratio); 59197e728d4SJosef Bacik break; 592e244a0aeSChristoph Hellwig case Opt_discard: 593b0643e59SDennis Zhou case Opt_discard_mode: 594b0643e59SDennis Zhou if (token == Opt_discard || 595b0643e59SDennis Zhou strcmp(args[0].from, "sync") == 0) { 596b0643e59SDennis Zhou btrfs_clear_opt(info->mount_opt, DISCARD_ASYNC); 59746b27f50SDennis Zhou btrfs_set_and_info(info, DISCARD_SYNC, 59846b27f50SDennis Zhou "turning on sync discard"); 599b0643e59SDennis Zhou } else if (strcmp(args[0].from, "async") == 0) { 600b0643e59SDennis Zhou btrfs_clear_opt(info->mount_opt, DISCARD_SYNC); 601b0643e59SDennis Zhou btrfs_set_and_info(info, DISCARD_ASYNC, 602b0643e59SDennis Zhou "turning on async discard"); 603b0643e59SDennis Zhou } else { 604e3a4167cSDavid Sterba btrfs_err(info, "unrecognized discard mode value %s", 605e3a4167cSDavid Sterba args[0].from); 606b0643e59SDennis Zhou ret = -EINVAL; 607b0643e59SDennis Zhou goto out; 608b0643e59SDennis Zhou } 60963a7cb13SDavid Sterba btrfs_clear_opt(info->mount_opt, NODISCARD); 610e244a0aeSChristoph Hellwig break; 611e07a2adeSQu Wenruo case Opt_nodiscard: 61246b27f50SDennis Zhou btrfs_clear_and_info(info, DISCARD_SYNC, 61307802534SQu Wenruo "turning off discard"); 614b0643e59SDennis Zhou btrfs_clear_and_info(info, DISCARD_ASYNC, 615b0643e59SDennis Zhou "turning off async discard"); 61663a7cb13SDavid Sterba btrfs_set_opt(info->mount_opt, NODISCARD); 617e07a2adeSQu Wenruo break; 6180af3d00bSJosef Bacik case Opt_space_cache: 61970f6d82eSOmar Sandoval case Opt_space_cache_version: 62063cd070dSJosef Bacik /* 62163cd070dSJosef Bacik * We already set FREE_SPACE_TREE above because we have 62263cd070dSJosef Bacik * compat_ro(FREE_SPACE_TREE) set, and we aren't going 62363cd070dSJosef Bacik * to allow v1 to be set for extent tree v2, simply 62463cd070dSJosef Bacik * ignore this setting if we're extent tree v2. 62563cd070dSJosef Bacik */ 62663cd070dSJosef Bacik if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) 62763cd070dSJosef Bacik break; 62870f6d82eSOmar Sandoval if (token == Opt_space_cache || 62970f6d82eSOmar Sandoval strcmp(args[0].from, "v1") == 0) { 6300b246afaSJeff Mahoney btrfs_clear_opt(info->mount_opt, 63170f6d82eSOmar Sandoval FREE_SPACE_TREE); 6323cdde224SJeff Mahoney btrfs_set_and_info(info, SPACE_CACHE, 63307802534SQu Wenruo "enabling disk space caching"); 63470f6d82eSOmar Sandoval } else if (strcmp(args[0].from, "v2") == 0) { 6350b246afaSJeff Mahoney btrfs_clear_opt(info->mount_opt, 63670f6d82eSOmar Sandoval SPACE_CACHE); 6370b246afaSJeff Mahoney btrfs_set_and_info(info, FREE_SPACE_TREE, 63870f6d82eSOmar Sandoval "enabling free space tree"); 63970f6d82eSOmar Sandoval } else { 640e3a4167cSDavid Sterba btrfs_err(info, "unrecognized space_cache value %s", 641e3a4167cSDavid Sterba args[0].from); 64270f6d82eSOmar Sandoval ret = -EINVAL; 64370f6d82eSOmar Sandoval goto out; 64470f6d82eSOmar Sandoval } 6450de90876SJosef Bacik break; 646f420ee1eSStefan Behrens case Opt_rescan_uuid_tree: 647f420ee1eSStefan Behrens btrfs_set_opt(info->mount_opt, RESCAN_UUID_TREE); 648f420ee1eSStefan Behrens break; 64973bc1876SJosef Bacik case Opt_no_space_cache: 65063cd070dSJosef Bacik /* 65163cd070dSJosef Bacik * We cannot operate without the free space tree with 65263cd070dSJosef Bacik * extent tree v2, ignore this option. 65363cd070dSJosef Bacik */ 65463cd070dSJosef Bacik if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) 65563cd070dSJosef Bacik break; 6563cdde224SJeff Mahoney if (btrfs_test_opt(info, SPACE_CACHE)) { 6570b246afaSJeff Mahoney btrfs_clear_and_info(info, SPACE_CACHE, 65807802534SQu Wenruo "disabling disk space caching"); 65970f6d82eSOmar Sandoval } 6603cdde224SJeff Mahoney if (btrfs_test_opt(info, FREE_SPACE_TREE)) { 6610b246afaSJeff Mahoney btrfs_clear_and_info(info, FREE_SPACE_TREE, 66270f6d82eSOmar Sandoval "disabling free space tree"); 66370f6d82eSOmar Sandoval } 66473bc1876SJosef Bacik break; 6654b9465cbSChris Mason case Opt_inode_cache: 6663818aea2SQu Wenruo case Opt_noinode_cache: 6675297199aSNikolay Borisov btrfs_warn(info, 6685297199aSNikolay Borisov "the 'inode_cache' option is deprecated and has no effect since 5.11"); 6694b9465cbSChris Mason break; 67088c2ba3bSJosef Bacik case Opt_clear_cache: 67163cd070dSJosef Bacik /* 67263cd070dSJosef Bacik * We cannot clear the free space tree with extent tree 67363cd070dSJosef Bacik * v2, ignore this option. 67463cd070dSJosef Bacik */ 67563cd070dSJosef Bacik if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) 67663cd070dSJosef Bacik break; 6773cdde224SJeff Mahoney btrfs_set_and_info(info, CLEAR_CACHE, 67807802534SQu Wenruo "force clearing of disk cache"); 6790af3d00bSJosef Bacik break; 6804260f7c7SSage Weil case Opt_user_subvol_rm_allowed: 6814260f7c7SSage Weil btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED); 6824260f7c7SSage Weil break; 68391435650SChris Mason case Opt_enospc_debug: 68491435650SChris Mason btrfs_set_opt(info->mount_opt, ENOSPC_DEBUG); 68591435650SChris Mason break; 68653036293SQu Wenruo case Opt_noenospc_debug: 68753036293SQu Wenruo btrfs_clear_opt(info->mount_opt, ENOSPC_DEBUG); 68853036293SQu Wenruo break; 6894cb5300bSChris Mason case Opt_defrag: 6903cdde224SJeff Mahoney btrfs_set_and_info(info, AUTO_DEFRAG, 69107802534SQu Wenruo "enabling auto defrag"); 6924cb5300bSChris Mason break; 693fc0ca9afSQu Wenruo case Opt_nodefrag: 6943cdde224SJeff Mahoney btrfs_clear_and_info(info, AUTO_DEFRAG, 69507802534SQu Wenruo "disabling auto defrag"); 696fc0ca9afSQu Wenruo break; 697af31f5e5SChris Mason case Opt_recovery: 6988dcddfa0SQu Wenruo case Opt_usebackuproot: 69974ef0018SQu Wenruo btrfs_warn(info, 70074ef0018SQu Wenruo "'%s' is deprecated, use 'rescue=usebackuproot' instead", 70174ef0018SQu Wenruo token == Opt_recovery ? "recovery" : 70274ef0018SQu Wenruo "usebackuproot"); 7030b246afaSJeff Mahoney btrfs_info(info, 7048dcddfa0SQu Wenruo "trying to use backup root at mount time"); 7058dcddfa0SQu Wenruo btrfs_set_opt(info->mount_opt, USEBACKUPROOT); 706af31f5e5SChris Mason break; 7079555c6c1SIlya Dryomov case Opt_skip_balance: 7089555c6c1SIlya Dryomov btrfs_set_opt(info->mount_opt, SKIP_BALANCE); 7099555c6c1SIlya Dryomov break; 71021adbd5cSStefan Behrens #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY 71121adbd5cSStefan Behrens case Opt_check_integrity_including_extent_data: 7120b246afaSJeff Mahoney btrfs_info(info, 713efe120a0SFrank Holton "enabling check integrity including extent data"); 714cbeaae4fSDavid Sterba btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY_DATA); 71521adbd5cSStefan Behrens btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY); 71621adbd5cSStefan Behrens break; 71721adbd5cSStefan Behrens case Opt_check_integrity: 7180b246afaSJeff Mahoney btrfs_info(info, "enabling check integrity"); 71921adbd5cSStefan Behrens btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY); 72021adbd5cSStefan Behrens break; 72121adbd5cSStefan Behrens case Opt_check_integrity_print_mask: 7222c334e87SWang Shilong ret = match_int(&args[0], &intarg); 723e3a4167cSDavid Sterba if (ret) { 724e3a4167cSDavid Sterba btrfs_err(info, 725e3a4167cSDavid Sterba "unrecognized check_integrity_print_mask value %s", 726e3a4167cSDavid Sterba args[0].from); 7272c334e87SWang Shilong goto out; 728e3a4167cSDavid Sterba } 72921adbd5cSStefan Behrens info->check_integrity_print_mask = intarg; 73002453bdeSAnand Jain btrfs_info(info, "check_integrity_print_mask 0x%x", 73121adbd5cSStefan Behrens info->check_integrity_print_mask); 73221adbd5cSStefan Behrens break; 73321adbd5cSStefan Behrens #else 73421adbd5cSStefan Behrens case Opt_check_integrity_including_extent_data: 73521adbd5cSStefan Behrens case Opt_check_integrity: 73621adbd5cSStefan Behrens case Opt_check_integrity_print_mask: 7370b246afaSJeff Mahoney btrfs_err(info, 738efe120a0SFrank Holton "support for check_integrity* not compiled in!"); 73921adbd5cSStefan Behrens ret = -EINVAL; 74021adbd5cSStefan Behrens goto out; 74121adbd5cSStefan Behrens #endif 7428c342930SJeff Mahoney case Opt_fatal_errors: 743e3a4167cSDavid Sterba if (strcmp(args[0].from, "panic") == 0) { 7448c342930SJeff Mahoney btrfs_set_opt(info->mount_opt, 7458c342930SJeff Mahoney PANIC_ON_FATAL_ERROR); 746e3a4167cSDavid Sterba } else if (strcmp(args[0].from, "bug") == 0) { 7478c342930SJeff Mahoney btrfs_clear_opt(info->mount_opt, 7488c342930SJeff Mahoney PANIC_ON_FATAL_ERROR); 749e3a4167cSDavid Sterba } else { 750e3a4167cSDavid Sterba btrfs_err(info, "unrecognized fatal_errors value %s", 751e3a4167cSDavid Sterba args[0].from); 7528c342930SJeff Mahoney ret = -EINVAL; 7538c342930SJeff Mahoney goto out; 7548c342930SJeff Mahoney } 7558c342930SJeff Mahoney break; 7568b87dc17SDavid Sterba case Opt_commit_interval: 7578b87dc17SDavid Sterba intarg = 0; 7588b87dc17SDavid Sterba ret = match_int(&args[0], &intarg); 759e3a4167cSDavid Sterba if (ret) { 760e3a4167cSDavid Sterba btrfs_err(info, "unrecognized commit_interval value %s", 761e3a4167cSDavid Sterba args[0].from); 762e3a4167cSDavid Sterba ret = -EINVAL; 7638b87dc17SDavid Sterba goto out; 764e3a4167cSDavid Sterba } 765d3740608SAnand Jain if (intarg == 0) { 766d3740608SAnand Jain btrfs_info(info, 767d3740608SAnand Jain "using default commit interval %us", 768d3740608SAnand Jain BTRFS_DEFAULT_COMMIT_INTERVAL); 769d3740608SAnand Jain intarg = BTRFS_DEFAULT_COMMIT_INTERVAL; 770d3740608SAnand Jain } else if (intarg > 300) { 771d3740608SAnand Jain btrfs_warn(info, "excessive commit interval %d", 7728b87dc17SDavid Sterba intarg); 7738b87dc17SDavid Sterba } 7748b87dc17SDavid Sterba info->commit_interval = intarg; 7758b87dc17SDavid Sterba break; 77674ef0018SQu Wenruo case Opt_rescue: 77774ef0018SQu Wenruo ret = parse_rescue_options(info, args[0].from); 778e3a4167cSDavid Sterba if (ret < 0) { 779e3a4167cSDavid Sterba btrfs_err(info, "unrecognized rescue value %s", 780e3a4167cSDavid Sterba args[0].from); 78174ef0018SQu Wenruo goto out; 782e3a4167cSDavid Sterba } 78374ef0018SQu Wenruo break; 784d0bd4560SJosef Bacik #ifdef CONFIG_BTRFS_DEBUG 785d0bd4560SJosef Bacik case Opt_fragment_all: 7860b246afaSJeff Mahoney btrfs_info(info, "fragmenting all space"); 787d0bd4560SJosef Bacik btrfs_set_opt(info->mount_opt, FRAGMENT_DATA); 788d0bd4560SJosef Bacik btrfs_set_opt(info->mount_opt, FRAGMENT_METADATA); 789d0bd4560SJosef Bacik break; 790d0bd4560SJosef Bacik case Opt_fragment_metadata: 7910b246afaSJeff Mahoney btrfs_info(info, "fragmenting metadata"); 792d0bd4560SJosef Bacik btrfs_set_opt(info->mount_opt, 793d0bd4560SJosef Bacik FRAGMENT_METADATA); 794d0bd4560SJosef Bacik break; 795d0bd4560SJosef Bacik case Opt_fragment_data: 7960b246afaSJeff Mahoney btrfs_info(info, "fragmenting data"); 797d0bd4560SJosef Bacik btrfs_set_opt(info->mount_opt, FRAGMENT_DATA); 798d0bd4560SJosef Bacik break; 799d0bd4560SJosef Bacik #endif 800fb592373SJosef Bacik #ifdef CONFIG_BTRFS_FS_REF_VERIFY 801fb592373SJosef Bacik case Opt_ref_verify: 802fb592373SJosef Bacik btrfs_info(info, "doing ref verification"); 803fb592373SJosef Bacik btrfs_set_opt(info->mount_opt, REF_VERIFY); 804fb592373SJosef Bacik break; 805fb592373SJosef Bacik #endif 806a7a3f7caSSage Weil case Opt_err: 8077e8f19e5SDavid Sterba btrfs_err(info, "unrecognized mount option '%s'", p); 808a7a3f7caSSage Weil ret = -EINVAL; 809a7a3f7caSSage Weil goto out; 81095e05289SChris Mason default: 811be20aa9dSChris Mason break; 81295e05289SChris Mason } 81395e05289SChris Mason } 81496da0919SQu Wenruo check: 815d70bf748SJosef Bacik /* We're read-only, don't have to check. */ 816d70bf748SJosef Bacik if (new_flags & SB_RDONLY) 817d70bf748SJosef Bacik goto out; 818d70bf748SJosef Bacik 81942437a63SJosef Bacik if (check_ro_option(info, BTRFS_MOUNT_NOLOGREPLAY, "nologreplay") || 820882dbe0cSJosef Bacik check_ro_option(info, BTRFS_MOUNT_IGNOREBADROOTS, "ignorebadroots") || 821882dbe0cSJosef Bacik check_ro_option(info, BTRFS_MOUNT_IGNOREDATACSUMS, "ignoredatacsums")) 82296da0919SQu Wenruo ret = -EINVAL; 823a7a3f7caSSage Weil out: 8240b246afaSJeff Mahoney if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE) && 8253cdde224SJeff Mahoney !btrfs_test_opt(info, FREE_SPACE_TREE) && 8263cdde224SJeff Mahoney !btrfs_test_opt(info, CLEAR_CACHE)) { 8270b246afaSJeff Mahoney btrfs_err(info, "cannot disable free space tree"); 82870f6d82eSOmar Sandoval ret = -EINVAL; 82970f6d82eSOmar Sandoval 83070f6d82eSOmar Sandoval } 8315d1ab66cSNaohiro Aota if (!ret) 8325d1ab66cSNaohiro Aota ret = btrfs_check_mountopts_zoned(info); 833dbecac26SMaciej S. Szmigiero if (!ret && !remounting) { 834dbecac26SMaciej S. Szmigiero if (btrfs_test_opt(info, SPACE_CACHE)) 8350b246afaSJeff Mahoney btrfs_info(info, "disk space caching is enabled"); 836dbecac26SMaciej S. Szmigiero if (btrfs_test_opt(info, FREE_SPACE_TREE)) 8370b246afaSJeff Mahoney btrfs_info(info, "using free space tree"); 838dbecac26SMaciej S. Szmigiero } 839a7a3f7caSSage Weil return ret; 840edf24abeSChristoph Hellwig } 841edf24abeSChristoph Hellwig 842edf24abeSChristoph Hellwig /* 843edf24abeSChristoph Hellwig * Parse mount options that are required early in the mount process. 844edf24abeSChristoph Hellwig * 845edf24abeSChristoph Hellwig * All other options will be parsed on much later in the mount process and 846edf24abeSChristoph Hellwig * only when we need to allocate a new super block. 847edf24abeSChristoph Hellwig */ 848fa59f27cSAnand Jain static int btrfs_parse_device_options(const char *options, fmode_t flags, 849d64dcbd1SGu Jinxiang void *holder) 850edf24abeSChristoph Hellwig { 851edf24abeSChristoph Hellwig substring_t args[MAX_OPT_ARGS]; 85283c8c9bdSJeff Liu char *device_name, *opts, *orig, *p; 85336350e95SGu Jinxiang struct btrfs_device *device = NULL; 854d7407606SMisono, Tomohiro int error = 0; 855d7407606SMisono, Tomohiro 8565139cff5SDavid Sterba lockdep_assert_held(&uuid_mutex); 8575139cff5SDavid Sterba 858d7407606SMisono, Tomohiro if (!options) 859d7407606SMisono, Tomohiro return 0; 860d7407606SMisono, Tomohiro 861d7407606SMisono, Tomohiro /* 862d7407606SMisono, Tomohiro * strsep changes the string, duplicate it because btrfs_parse_options 863d7407606SMisono, Tomohiro * gets called later 864d7407606SMisono, Tomohiro */ 865d7407606SMisono, Tomohiro opts = kstrdup(options, GFP_KERNEL); 866d7407606SMisono, Tomohiro if (!opts) 867d7407606SMisono, Tomohiro return -ENOMEM; 868d7407606SMisono, Tomohiro orig = opts; 869d7407606SMisono, Tomohiro 870d7407606SMisono, Tomohiro while ((p = strsep(&opts, ",")) != NULL) { 871d7407606SMisono, Tomohiro int token; 872d7407606SMisono, Tomohiro 873d7407606SMisono, Tomohiro if (!*p) 874d7407606SMisono, Tomohiro continue; 875d7407606SMisono, Tomohiro 876d7407606SMisono, Tomohiro token = match_token(p, tokens, args); 877d7407606SMisono, Tomohiro if (token == Opt_device) { 878d7407606SMisono, Tomohiro device_name = match_strdup(&args[0]); 879d7407606SMisono, Tomohiro if (!device_name) { 880d7407606SMisono, Tomohiro error = -ENOMEM; 881d7407606SMisono, Tomohiro goto out; 882d7407606SMisono, Tomohiro } 88336350e95SGu Jinxiang device = btrfs_scan_one_device(device_name, flags, 88436350e95SGu Jinxiang holder); 885d7407606SMisono, Tomohiro kfree(device_name); 88636350e95SGu Jinxiang if (IS_ERR(device)) { 88736350e95SGu Jinxiang error = PTR_ERR(device); 888d7407606SMisono, Tomohiro goto out; 889d7407606SMisono, Tomohiro } 890d7407606SMisono, Tomohiro } 89136350e95SGu Jinxiang } 892d7407606SMisono, Tomohiro 893d7407606SMisono, Tomohiro out: 894d7407606SMisono, Tomohiro kfree(orig); 895d7407606SMisono, Tomohiro return error; 896d7407606SMisono, Tomohiro } 897d7407606SMisono, Tomohiro 898d7407606SMisono, Tomohiro /* 899d7407606SMisono, Tomohiro * Parse mount options that are related to subvolume id 900d7407606SMisono, Tomohiro * 901d7407606SMisono, Tomohiro * The value is later passed to mount_subvol() 902d7407606SMisono, Tomohiro */ 90393b9bcdfSGu Jinxiang static int btrfs_parse_subvol_options(const char *options, char **subvol_name, 90493b9bcdfSGu Jinxiang u64 *subvol_objectid) 905d7407606SMisono, Tomohiro { 906d7407606SMisono, Tomohiro substring_t args[MAX_OPT_ARGS]; 907d7407606SMisono, Tomohiro char *opts, *orig, *p; 908edf24abeSChristoph Hellwig int error = 0; 909ccb0e7d1SAnand Jain u64 subvolid; 910edf24abeSChristoph Hellwig 911edf24abeSChristoph Hellwig if (!options) 912830c4adbSJosef Bacik return 0; 913edf24abeSChristoph Hellwig 914edf24abeSChristoph Hellwig /* 915d7407606SMisono, Tomohiro * strsep changes the string, duplicate it because 916fa59f27cSAnand Jain * btrfs_parse_device_options gets called later 917edf24abeSChristoph Hellwig */ 918edf24abeSChristoph Hellwig opts = kstrdup(options, GFP_KERNEL); 919edf24abeSChristoph Hellwig if (!opts) 920edf24abeSChristoph Hellwig return -ENOMEM; 9213f3d0bc0STero Roponen orig = opts; 922edf24abeSChristoph Hellwig 923edf24abeSChristoph Hellwig while ((p = strsep(&opts, ",")) != NULL) { 924edf24abeSChristoph Hellwig int token; 925edf24abeSChristoph Hellwig if (!*p) 926edf24abeSChristoph Hellwig continue; 927edf24abeSChristoph Hellwig 928edf24abeSChristoph Hellwig token = match_token(p, tokens, args); 929edf24abeSChristoph Hellwig switch (token) { 930edf24abeSChristoph Hellwig case Opt_subvol: 931a90e8b6fSIlya Dryomov kfree(*subvol_name); 932edf24abeSChristoph Hellwig *subvol_name = match_strdup(&args[0]); 9332c334e87SWang Shilong if (!*subvol_name) { 9342c334e87SWang Shilong error = -ENOMEM; 9352c334e87SWang Shilong goto out; 9362c334e87SWang Shilong } 937edf24abeSChristoph Hellwig break; 93873f73415SJosef Bacik case Opt_subvolid: 939ccb0e7d1SAnand Jain error = match_u64(&args[0], &subvolid); 940ccb0e7d1SAnand Jain if (error) 9412c334e87SWang Shilong goto out; 942ccb0e7d1SAnand Jain 943ccb0e7d1SAnand Jain /* we want the original fs_tree */ 944ccb0e7d1SAnand Jain if (subvolid == 0) 945ccb0e7d1SAnand Jain subvolid = BTRFS_FS_TREE_OBJECTID; 946ccb0e7d1SAnand Jain 947ccb0e7d1SAnand Jain *subvol_objectid = subvolid; 94873f73415SJosef Bacik break; 949edf24abeSChristoph Hellwig default: 950edf24abeSChristoph Hellwig break; 951edf24abeSChristoph Hellwig } 952edf24abeSChristoph Hellwig } 953edf24abeSChristoph Hellwig 954edf24abeSChristoph Hellwig out: 955830c4adbSJosef Bacik kfree(orig); 956edf24abeSChristoph Hellwig return error; 95795e05289SChris Mason } 95895e05289SChris Mason 959c0c907a4SMarcos Paulo de Souza char *btrfs_get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info, 96073f73415SJosef Bacik u64 subvol_objectid) 96173f73415SJosef Bacik { 962815745cfSAl Viro struct btrfs_root *root = fs_info->tree_root; 9635168489aSJosef Bacik struct btrfs_root *fs_root = NULL; 96405dbe683SOmar Sandoval struct btrfs_root_ref *root_ref; 96505dbe683SOmar Sandoval struct btrfs_inode_ref *inode_ref; 96605dbe683SOmar Sandoval struct btrfs_key key; 96705dbe683SOmar Sandoval struct btrfs_path *path = NULL; 96805dbe683SOmar Sandoval char *name = NULL, *ptr; 96905dbe683SOmar Sandoval u64 dirid; 97005dbe683SOmar Sandoval int len; 97105dbe683SOmar Sandoval int ret; 97205dbe683SOmar Sandoval 97305dbe683SOmar Sandoval path = btrfs_alloc_path(); 97405dbe683SOmar Sandoval if (!path) { 97505dbe683SOmar Sandoval ret = -ENOMEM; 97605dbe683SOmar Sandoval goto err; 97705dbe683SOmar Sandoval } 97805dbe683SOmar Sandoval 9793ec83621SDavid Sterba name = kmalloc(PATH_MAX, GFP_KERNEL); 98005dbe683SOmar Sandoval if (!name) { 98105dbe683SOmar Sandoval ret = -ENOMEM; 98205dbe683SOmar Sandoval goto err; 98305dbe683SOmar Sandoval } 98405dbe683SOmar Sandoval ptr = name + PATH_MAX - 1; 98505dbe683SOmar Sandoval ptr[0] = '\0'; 98605dbe683SOmar Sandoval 98705dbe683SOmar Sandoval /* 98805dbe683SOmar Sandoval * Walk up the subvolume trees in the tree of tree roots by root 98905dbe683SOmar Sandoval * backrefs until we hit the top-level subvolume. 99005dbe683SOmar Sandoval */ 99105dbe683SOmar Sandoval while (subvol_objectid != BTRFS_FS_TREE_OBJECTID) { 99205dbe683SOmar Sandoval key.objectid = subvol_objectid; 99305dbe683SOmar Sandoval key.type = BTRFS_ROOT_BACKREF_KEY; 99405dbe683SOmar Sandoval key.offset = (u64)-1; 99505dbe683SOmar Sandoval 9960ff40a91SMarcos Paulo de Souza ret = btrfs_search_backwards(root, &key, path); 99705dbe683SOmar Sandoval if (ret < 0) { 99805dbe683SOmar Sandoval goto err; 99905dbe683SOmar Sandoval } else if (ret > 0) { 100005dbe683SOmar Sandoval ret = -ENOENT; 100105dbe683SOmar Sandoval goto err; 100205dbe683SOmar Sandoval } 100305dbe683SOmar Sandoval 100405dbe683SOmar Sandoval subvol_objectid = key.offset; 100505dbe683SOmar Sandoval 100605dbe683SOmar Sandoval root_ref = btrfs_item_ptr(path->nodes[0], path->slots[0], 100705dbe683SOmar Sandoval struct btrfs_root_ref); 100805dbe683SOmar Sandoval len = btrfs_root_ref_name_len(path->nodes[0], root_ref); 100905dbe683SOmar Sandoval ptr -= len + 1; 101005dbe683SOmar Sandoval if (ptr < name) { 101105dbe683SOmar Sandoval ret = -ENAMETOOLONG; 101205dbe683SOmar Sandoval goto err; 101305dbe683SOmar Sandoval } 101405dbe683SOmar Sandoval read_extent_buffer(path->nodes[0], ptr + 1, 101505dbe683SOmar Sandoval (unsigned long)(root_ref + 1), len); 101605dbe683SOmar Sandoval ptr[0] = '/'; 101705dbe683SOmar Sandoval dirid = btrfs_root_ref_dirid(path->nodes[0], root_ref); 101805dbe683SOmar Sandoval btrfs_release_path(path); 101905dbe683SOmar Sandoval 102056e9357aSDavid Sterba fs_root = btrfs_get_fs_root(fs_info, subvol_objectid, true); 102105dbe683SOmar Sandoval if (IS_ERR(fs_root)) { 102205dbe683SOmar Sandoval ret = PTR_ERR(fs_root); 10235168489aSJosef Bacik fs_root = NULL; 10245168489aSJosef Bacik goto err; 10255168489aSJosef Bacik } 102605dbe683SOmar Sandoval 102705dbe683SOmar Sandoval /* 102805dbe683SOmar Sandoval * Walk up the filesystem tree by inode refs until we hit the 102905dbe683SOmar Sandoval * root directory. 103005dbe683SOmar Sandoval */ 103105dbe683SOmar Sandoval while (dirid != BTRFS_FIRST_FREE_OBJECTID) { 103205dbe683SOmar Sandoval key.objectid = dirid; 103305dbe683SOmar Sandoval key.type = BTRFS_INODE_REF_KEY; 103405dbe683SOmar Sandoval key.offset = (u64)-1; 103505dbe683SOmar Sandoval 10360ff40a91SMarcos Paulo de Souza ret = btrfs_search_backwards(fs_root, &key, path); 103705dbe683SOmar Sandoval if (ret < 0) { 103805dbe683SOmar Sandoval goto err; 103905dbe683SOmar Sandoval } else if (ret > 0) { 104005dbe683SOmar Sandoval ret = -ENOENT; 104105dbe683SOmar Sandoval goto err; 104205dbe683SOmar Sandoval } 104305dbe683SOmar Sandoval 104405dbe683SOmar Sandoval dirid = key.offset; 104505dbe683SOmar Sandoval 104605dbe683SOmar Sandoval inode_ref = btrfs_item_ptr(path->nodes[0], 104705dbe683SOmar Sandoval path->slots[0], 104805dbe683SOmar Sandoval struct btrfs_inode_ref); 104905dbe683SOmar Sandoval len = btrfs_inode_ref_name_len(path->nodes[0], 105005dbe683SOmar Sandoval inode_ref); 105105dbe683SOmar Sandoval ptr -= len + 1; 105205dbe683SOmar Sandoval if (ptr < name) { 105305dbe683SOmar Sandoval ret = -ENAMETOOLONG; 105405dbe683SOmar Sandoval goto err; 105505dbe683SOmar Sandoval } 105605dbe683SOmar Sandoval read_extent_buffer(path->nodes[0], ptr + 1, 105705dbe683SOmar Sandoval (unsigned long)(inode_ref + 1), len); 105805dbe683SOmar Sandoval ptr[0] = '/'; 105905dbe683SOmar Sandoval btrfs_release_path(path); 106005dbe683SOmar Sandoval } 106100246528SJosef Bacik btrfs_put_root(fs_root); 10625168489aSJosef Bacik fs_root = NULL; 106305dbe683SOmar Sandoval } 106405dbe683SOmar Sandoval 106505dbe683SOmar Sandoval btrfs_free_path(path); 106605dbe683SOmar Sandoval if (ptr == name + PATH_MAX - 1) { 106705dbe683SOmar Sandoval name[0] = '/'; 106805dbe683SOmar Sandoval name[1] = '\0'; 106905dbe683SOmar Sandoval } else { 107005dbe683SOmar Sandoval memmove(name, ptr, name + PATH_MAX - ptr); 107105dbe683SOmar Sandoval } 107205dbe683SOmar Sandoval return name; 107305dbe683SOmar Sandoval 107405dbe683SOmar Sandoval err: 107500246528SJosef Bacik btrfs_put_root(fs_root); 107605dbe683SOmar Sandoval btrfs_free_path(path); 107705dbe683SOmar Sandoval kfree(name); 107805dbe683SOmar Sandoval return ERR_PTR(ret); 107905dbe683SOmar Sandoval } 108005dbe683SOmar Sandoval 108105dbe683SOmar Sandoval static int get_default_subvol_objectid(struct btrfs_fs_info *fs_info, u64 *objectid) 108205dbe683SOmar Sandoval { 108305dbe683SOmar Sandoval struct btrfs_root *root = fs_info->tree_root; 108473f73415SJosef Bacik struct btrfs_dir_item *di; 108573f73415SJosef Bacik struct btrfs_path *path; 108673f73415SJosef Bacik struct btrfs_key location; 10876db75318SSweet Tea Dorminy struct fscrypt_str name = FSTR_INIT("default", 7); 108873f73415SJosef Bacik u64 dir_id; 108973f73415SJosef Bacik 109073f73415SJosef Bacik path = btrfs_alloc_path(); 109173f73415SJosef Bacik if (!path) 109205dbe683SOmar Sandoval return -ENOMEM; 109373f73415SJosef Bacik 109473f73415SJosef Bacik /* 109573f73415SJosef Bacik * Find the "default" dir item which points to the root item that we 109673f73415SJosef Bacik * will mount by default if we haven't been given a specific subvolume 109773f73415SJosef Bacik * to mount. 109873f73415SJosef Bacik */ 1099815745cfSAl Viro dir_id = btrfs_super_root_dir(fs_info->super_copy); 1100e43eec81SSweet Tea Dorminy di = btrfs_lookup_dir_item(NULL, root, path, dir_id, &name, 0); 1101b0839166SJulia Lawall if (IS_ERR(di)) { 1102b0839166SJulia Lawall btrfs_free_path(path); 110305dbe683SOmar Sandoval return PTR_ERR(di); 1104b0839166SJulia Lawall } 110573f73415SJosef Bacik if (!di) { 110673f73415SJosef Bacik /* 110773f73415SJosef Bacik * Ok the default dir item isn't there. This is weird since 110873f73415SJosef Bacik * it's always been there, but don't freak out, just try and 110905dbe683SOmar Sandoval * mount the top-level subvolume. 111073f73415SJosef Bacik */ 111173f73415SJosef Bacik btrfs_free_path(path); 111205dbe683SOmar Sandoval *objectid = BTRFS_FS_TREE_OBJECTID; 111305dbe683SOmar Sandoval return 0; 111473f73415SJosef Bacik } 111573f73415SJosef Bacik 111673f73415SJosef Bacik btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location); 111773f73415SJosef Bacik btrfs_free_path(path); 111805dbe683SOmar Sandoval *objectid = location.objectid; 111905dbe683SOmar Sandoval return 0; 112073f73415SJosef Bacik } 112173f73415SJosef Bacik 11228a4b83ccSChris Mason static int btrfs_fill_super(struct super_block *sb, 11238a4b83ccSChris Mason struct btrfs_fs_devices *fs_devices, 112456e033a7SDavid Sterba void *data) 11252e635a27SChris Mason { 11262e635a27SChris Mason struct inode *inode; 1127815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(sb); 112839279cc3SChris Mason int err; 11292e635a27SChris Mason 11302e635a27SChris Mason sb->s_maxbytes = MAX_LFS_FILESIZE; 11312e635a27SChris Mason sb->s_magic = BTRFS_SUPER_MAGIC; 1132e20d96d6SChris Mason sb->s_op = &btrfs_super_ops; 1133af53d29aSAl Viro sb->s_d_op = &btrfs_dentry_operations; 1134be6e8dc0SBalaji Rao sb->s_export_op = &btrfs_export_ops; 113514605409SBoris Burkov #ifdef CONFIG_FS_VERITY 113614605409SBoris Burkov sb->s_vop = &btrfs_verityops; 113714605409SBoris Burkov #endif 11385103e947SJosef Bacik sb->s_xattr = btrfs_xattr_handlers; 11392e635a27SChris Mason sb->s_time_gran = 1; 11400eda294dSChris Mason #ifdef CONFIG_BTRFS_FS_POSIX_ACL 11411751e8a6SLinus Torvalds sb->s_flags |= SB_POSIXACL; 114249cf6f45SChris Ball #endif 1143357fdad0SMatthew Garrett sb->s_flags |= SB_I_VERSION; 1144da2f0f74SChris Mason sb->s_iflags |= SB_I_CGROUPWB; 11459e11ceeeSJan Kara 11469e11ceeeSJan Kara err = super_setup_bdi(sb); 11479e11ceeeSJan Kara if (err) { 11489e11ceeeSJan Kara btrfs_err(fs_info, "super_setup_bdi failed"); 11499e11ceeeSJan Kara return err; 11509e11ceeeSJan Kara } 11519e11ceeeSJan Kara 1152ad2b2c80SAl Viro err = open_ctree(sb, fs_devices, (char *)data); 1153ad2b2c80SAl Viro if (err) { 1154ab8d0fc4SJeff Mahoney btrfs_err(fs_info, "open_ctree failed"); 1155ad2b2c80SAl Viro return err; 1156e20d96d6SChris Mason } 1157b888db2bSChris Mason 11580202e83fSDavid Sterba inode = btrfs_iget(sb, BTRFS_FIRST_FREE_OBJECTID, fs_info->fs_root); 11595d4f98a2SYan Zheng if (IS_ERR(inode)) { 11605d4f98a2SYan Zheng err = PTR_ERR(inode); 116113b98989SJosef Bacik btrfs_handle_fs_error(fs_info, err, NULL); 116239279cc3SChris Mason goto fail_close; 116339279cc3SChris Mason } 11642e635a27SChris Mason 116548fde701SAl Viro sb->s_root = d_make_root(inode); 116648fde701SAl Viro if (!sb->s_root) { 116739279cc3SChris Mason err = -ENOMEM; 116839279cc3SChris Mason goto fail_close; 11692e635a27SChris Mason } 117058176a96SJosef Bacik 11711751e8a6SLinus Torvalds sb->s_flags |= SB_ACTIVE; 11722e635a27SChris Mason return 0; 11732e635a27SChris Mason 117439279cc3SChris Mason fail_close: 11756bccf3abSJeff Mahoney close_ctree(fs_info); 1176d5719762SChris Mason return err; 1177d5719762SChris Mason } 1178d5719762SChris Mason 11796bf13c0cSSage Weil int btrfs_sync_fs(struct super_block *sb, int wait) 1180d5719762SChris Mason { 1181d5719762SChris Mason struct btrfs_trans_handle *trans; 1182815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(sb); 1183815745cfSAl Viro struct btrfs_root *root = fs_info->tree_root; 1184df2ce34cSChris Mason 1185bc074524SJeff Mahoney trace_btrfs_sync_fs(fs_info, wait); 11861abe9b8aSliubo 1187d561c025SChris Mason if (!wait) { 1188815745cfSAl Viro filemap_flush(fs_info->btree_inode->i_mapping); 1189df2ce34cSChris Mason return 0; 1190d561c025SChris Mason } 1191771ed689SChris Mason 11926374e57aSChris Mason btrfs_wait_ordered_roots(fs_info, U64_MAX, 0, (u64)-1); 1193771ed689SChris Mason 1194d4edf39bSMiao Xie trans = btrfs_attach_transaction_barrier(root); 119560376ce4SJosef Bacik if (IS_ERR(trans)) { 1196354aa0fbSMiao Xie /* no transaction, don't bother */ 11976b5fe46dSDavid Sterba if (PTR_ERR(trans) == -ENOENT) { 11986b5fe46dSDavid Sterba /* 11996b5fe46dSDavid Sterba * Exit unless we have some pending changes 12006b5fe46dSDavid Sterba * that need to go through commit 12016b5fe46dSDavid Sterba */ 1202c52cc7b7SJosef Bacik if (!test_bit(BTRFS_FS_NEED_TRANS_COMMIT, 1203c52cc7b7SJosef Bacik &fs_info->flags)) 1204bd7de2c9SJosef Bacik return 0; 1205a53f4f8eSQu Wenruo /* 1206a53f4f8eSQu Wenruo * A non-blocking test if the fs is frozen. We must not 1207a53f4f8eSQu Wenruo * start a new transaction here otherwise a deadlock 1208a53f4f8eSQu Wenruo * happens. The pending operations are delayed to the 1209a53f4f8eSQu Wenruo * next commit after thawing. 1210a53f4f8eSQu Wenruo */ 1211a7e3c5f2SRakesh Pandit if (sb_start_write_trylock(sb)) 1212a7e3c5f2SRakesh Pandit sb_end_write(sb); 1213a53f4f8eSQu Wenruo else 1214a53f4f8eSQu Wenruo return 0; 12156b5fe46dSDavid Sterba trans = btrfs_start_transaction(root, 0); 121660376ce4SJosef Bacik } 121798bd5c54SDavid Sterba if (IS_ERR(trans)) 121898bd5c54SDavid Sterba return PTR_ERR(trans); 12196b5fe46dSDavid Sterba } 12203a45bb20SJeff Mahoney return btrfs_commit_transaction(trans); 1221d5719762SChris Mason } 1222d5719762SChris Mason 1223ab0b4a3eSJosef Bacik static void print_rescue_option(struct seq_file *seq, const char *s, bool *printed) 1224ab0b4a3eSJosef Bacik { 1225ab0b4a3eSJosef Bacik seq_printf(seq, "%s%s", (*printed) ? ":" : ",rescue=", s); 1226ab0b4a3eSJosef Bacik *printed = true; 1227ab0b4a3eSJosef Bacik } 1228ab0b4a3eSJosef Bacik 122934c80b1dSAl Viro static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) 1230a9572a15SEric Paris { 1231815745cfSAl Viro struct btrfs_fs_info *info = btrfs_sb(dentry->d_sb); 12320f628c63SDavid Sterba const char *compress_type; 12333ef3959bSJosef Bacik const char *subvol_name; 1234ab0b4a3eSJosef Bacik bool printed = false; 1235a9572a15SEric Paris 12363cdde224SJeff Mahoney if (btrfs_test_opt(info, DEGRADED)) 1237a9572a15SEric Paris seq_puts(seq, ",degraded"); 12383cdde224SJeff Mahoney if (btrfs_test_opt(info, NODATASUM)) 1239a9572a15SEric Paris seq_puts(seq, ",nodatasum"); 12403cdde224SJeff Mahoney if (btrfs_test_opt(info, NODATACOW)) 1241a9572a15SEric Paris seq_puts(seq, ",nodatacow"); 12423cdde224SJeff Mahoney if (btrfs_test_opt(info, NOBARRIER)) 1243a9572a15SEric Paris seq_puts(seq, ",nobarrier"); 124495ac567aSFilipe David Borba Manana if (info->max_inline != BTRFS_DEFAULT_MAX_INLINE) 1245c1c9ff7cSGeert Uytterhoeven seq_printf(seq, ",max_inline=%llu", info->max_inline); 1246a9572a15SEric Paris if (info->thread_pool_size != min_t(unsigned long, 1247a9572a15SEric Paris num_online_cpus() + 2, 8)) 1248f7b885beSAnand Jain seq_printf(seq, ",thread_pool=%u", info->thread_pool_size); 12493cdde224SJeff Mahoney if (btrfs_test_opt(info, COMPRESS)) { 12500f628c63SDavid Sterba compress_type = btrfs_compress_type2str(info->compress_type); 12513cdde224SJeff Mahoney if (btrfs_test_opt(info, FORCE_COMPRESS)) 1252200da64eSTsutomu Itoh seq_printf(seq, ",compress-force=%s", compress_type); 1253200da64eSTsutomu Itoh else 1254200da64eSTsutomu Itoh seq_printf(seq, ",compress=%s", compress_type); 1255f51d2b59SDavid Sterba if (info->compress_level) 1256fa4d885aSAdam Borowski seq_printf(seq, ":%d", info->compress_level); 1257200da64eSTsutomu Itoh } 12583cdde224SJeff Mahoney if (btrfs_test_opt(info, NOSSD)) 1259c289811cSChris Mason seq_puts(seq, ",nossd"); 12603cdde224SJeff Mahoney if (btrfs_test_opt(info, SSD_SPREAD)) 1261451d7585SChris Mason seq_puts(seq, ",ssd_spread"); 12623cdde224SJeff Mahoney else if (btrfs_test_opt(info, SSD)) 1263a9572a15SEric Paris seq_puts(seq, ",ssd"); 12643cdde224SJeff Mahoney if (btrfs_test_opt(info, NOTREELOG)) 12656b65c5c6SSage Weil seq_puts(seq, ",notreelog"); 12663cdde224SJeff Mahoney if (btrfs_test_opt(info, NOLOGREPLAY)) 1267ab0b4a3eSJosef Bacik print_rescue_option(seq, "nologreplay", &printed); 126868319c18SJosef Bacik if (btrfs_test_opt(info, USEBACKUPROOT)) 126968319c18SJosef Bacik print_rescue_option(seq, "usebackuproot", &printed); 127042437a63SJosef Bacik if (btrfs_test_opt(info, IGNOREBADROOTS)) 127142437a63SJosef Bacik print_rescue_option(seq, "ignorebadroots", &printed); 1272882dbe0cSJosef Bacik if (btrfs_test_opt(info, IGNOREDATACSUMS)) 1273882dbe0cSJosef Bacik print_rescue_option(seq, "ignoredatacsums", &printed); 12743cdde224SJeff Mahoney if (btrfs_test_opt(info, FLUSHONCOMMIT)) 12756b65c5c6SSage Weil seq_puts(seq, ",flushoncommit"); 127646b27f50SDennis Zhou if (btrfs_test_opt(info, DISCARD_SYNC)) 127720a5239aSMatthew Wilcox seq_puts(seq, ",discard"); 1278b0643e59SDennis Zhou if (btrfs_test_opt(info, DISCARD_ASYNC)) 1279b0643e59SDennis Zhou seq_puts(seq, ",discard=async"); 12801751e8a6SLinus Torvalds if (!(info->sb->s_flags & SB_POSIXACL)) 1281a9572a15SEric Paris seq_puts(seq, ",noacl"); 128204c41559SBoris Burkov if (btrfs_free_space_cache_v1_active(info)) 1283200da64eSTsutomu Itoh seq_puts(seq, ",space_cache"); 128404c41559SBoris Burkov else if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE)) 128570f6d82eSOmar Sandoval seq_puts(seq, ",space_cache=v2"); 128673bc1876SJosef Bacik else 12878965593eSDavid Sterba seq_puts(seq, ",nospace_cache"); 12883cdde224SJeff Mahoney if (btrfs_test_opt(info, RESCAN_UUID_TREE)) 1289f420ee1eSStefan Behrens seq_puts(seq, ",rescan_uuid_tree"); 12903cdde224SJeff Mahoney if (btrfs_test_opt(info, CLEAR_CACHE)) 1291200da64eSTsutomu Itoh seq_puts(seq, ",clear_cache"); 12923cdde224SJeff Mahoney if (btrfs_test_opt(info, USER_SUBVOL_RM_ALLOWED)) 1293200da64eSTsutomu Itoh seq_puts(seq, ",user_subvol_rm_allowed"); 12943cdde224SJeff Mahoney if (btrfs_test_opt(info, ENOSPC_DEBUG)) 12950942caa3SDavid Sterba seq_puts(seq, ",enospc_debug"); 12963cdde224SJeff Mahoney if (btrfs_test_opt(info, AUTO_DEFRAG)) 12970942caa3SDavid Sterba seq_puts(seq, ",autodefrag"); 12983cdde224SJeff Mahoney if (btrfs_test_opt(info, SKIP_BALANCE)) 12999555c6c1SIlya Dryomov seq_puts(seq, ",skip_balance"); 13008507d216SWang Shilong #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY 1301cbeaae4fSDavid Sterba if (btrfs_test_opt(info, CHECK_INTEGRITY_DATA)) 13028507d216SWang Shilong seq_puts(seq, ",check_int_data"); 13033cdde224SJeff Mahoney else if (btrfs_test_opt(info, CHECK_INTEGRITY)) 13048507d216SWang Shilong seq_puts(seq, ",check_int"); 13058507d216SWang Shilong if (info->check_integrity_print_mask) 13068507d216SWang Shilong seq_printf(seq, ",check_int_print_mask=%d", 13078507d216SWang Shilong info->check_integrity_print_mask); 13088507d216SWang Shilong #endif 13098507d216SWang Shilong if (info->metadata_ratio) 1310764cb8b4SAnand Jain seq_printf(seq, ",metadata_ratio=%u", info->metadata_ratio); 13113cdde224SJeff Mahoney if (btrfs_test_opt(info, PANIC_ON_FATAL_ERROR)) 13128c342930SJeff Mahoney seq_puts(seq, ",fatal_errors=panic"); 13138b87dc17SDavid Sterba if (info->commit_interval != BTRFS_DEFAULT_COMMIT_INTERVAL) 1314d3740608SAnand Jain seq_printf(seq, ",commit=%u", info->commit_interval); 1315d0bd4560SJosef Bacik #ifdef CONFIG_BTRFS_DEBUG 13163cdde224SJeff Mahoney if (btrfs_test_opt(info, FRAGMENT_DATA)) 1317d0bd4560SJosef Bacik seq_puts(seq, ",fragment=data"); 13183cdde224SJeff Mahoney if (btrfs_test_opt(info, FRAGMENT_METADATA)) 1319d0bd4560SJosef Bacik seq_puts(seq, ",fragment=metadata"); 1320d0bd4560SJosef Bacik #endif 1321fb592373SJosef Bacik if (btrfs_test_opt(info, REF_VERIFY)) 1322fb592373SJosef Bacik seq_puts(seq, ",ref_verify"); 1323c8d3fe02SOmar Sandoval seq_printf(seq, ",subvolid=%llu", 1324c8d3fe02SOmar Sandoval BTRFS_I(d_inode(dentry))->root->root_key.objectid); 13253ef3959bSJosef Bacik subvol_name = btrfs_get_subvol_name_from_objectid(info, 13263ef3959bSJosef Bacik BTRFS_I(d_inode(dentry))->root->root_key.objectid); 13273ef3959bSJosef Bacik if (!IS_ERR(subvol_name)) { 1328c8d3fe02SOmar Sandoval seq_puts(seq, ",subvol="); 13293ef3959bSJosef Bacik seq_escape(seq, subvol_name, " \t\n\\"); 13303ef3959bSJosef Bacik kfree(subvol_name); 13313ef3959bSJosef Bacik } 1332a9572a15SEric Paris return 0; 1333a9572a15SEric Paris } 1334a9572a15SEric Paris 1335a061fc8dSChris Mason static int btrfs_test_super(struct super_block *s, void *data) 13362e635a27SChris Mason { 1337815745cfSAl Viro struct btrfs_fs_info *p = data; 1338815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(s); 13394b82d6e4SYan 1340815745cfSAl Viro return fs_info->fs_devices == p->fs_devices; 13414b82d6e4SYan } 13424b82d6e4SYan 1343450ba0eaSJosef Bacik static int btrfs_set_super(struct super_block *s, void *data) 1344450ba0eaSJosef Bacik { 13456de1d09dSAl Viro int err = set_anon_super(s, data); 13466de1d09dSAl Viro if (!err) 1347450ba0eaSJosef Bacik s->s_fs_info = data; 13486de1d09dSAl Viro return err; 1349450ba0eaSJosef Bacik } 1350450ba0eaSJosef Bacik 1351830c4adbSJosef Bacik /* 1352f9d9ef62SDavid Sterba * subvolumes are identified by ino 256 1353f9d9ef62SDavid Sterba */ 1354f9d9ef62SDavid Sterba static inline int is_subvolume_inode(struct inode *inode) 1355f9d9ef62SDavid Sterba { 1356f9d9ef62SDavid Sterba if (inode && inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) 1357f9d9ef62SDavid Sterba return 1; 1358f9d9ef62SDavid Sterba return 0; 1359f9d9ef62SDavid Sterba } 1360f9d9ef62SDavid Sterba 1361bb289b7bSOmar Sandoval static struct dentry *mount_subvol(const char *subvol_name, u64 subvol_objectid, 1362ae0bc863SAnand Jain struct vfsmount *mnt) 1363830c4adbSJosef Bacik { 1364830c4adbSJosef Bacik struct dentry *root; 1365fa330659SOmar Sandoval int ret; 1366830c4adbSJosef Bacik 136705dbe683SOmar Sandoval if (!subvol_name) { 136805dbe683SOmar Sandoval if (!subvol_objectid) { 136905dbe683SOmar Sandoval ret = get_default_subvol_objectid(btrfs_sb(mnt->mnt_sb), 137005dbe683SOmar Sandoval &subvol_objectid); 137105dbe683SOmar Sandoval if (ret) { 137205dbe683SOmar Sandoval root = ERR_PTR(ret); 137305dbe683SOmar Sandoval goto out; 137405dbe683SOmar Sandoval } 137505dbe683SOmar Sandoval } 1376c0c907a4SMarcos Paulo de Souza subvol_name = btrfs_get_subvol_name_from_objectid( 1377c0c907a4SMarcos Paulo de Souza btrfs_sb(mnt->mnt_sb), subvol_objectid); 137805dbe683SOmar Sandoval if (IS_ERR(subvol_name)) { 137905dbe683SOmar Sandoval root = ERR_CAST(subvol_name); 138005dbe683SOmar Sandoval subvol_name = NULL; 138105dbe683SOmar Sandoval goto out; 138205dbe683SOmar Sandoval } 138305dbe683SOmar Sandoval 138405dbe683SOmar Sandoval } 138505dbe683SOmar Sandoval 1386ea441d11SAl Viro root = mount_subtree(mnt, subvol_name); 1387fa330659SOmar Sandoval /* mount_subtree() drops our reference on the vfsmount. */ 1388fa330659SOmar Sandoval mnt = NULL; 1389830c4adbSJosef Bacik 1390bb289b7bSOmar Sandoval if (!IS_ERR(root)) { 1391ea441d11SAl Viro struct super_block *s = root->d_sb; 1392ab8d0fc4SJeff Mahoney struct btrfs_fs_info *fs_info = btrfs_sb(s); 1393bb289b7bSOmar Sandoval struct inode *root_inode = d_inode(root); 1394bb289b7bSOmar Sandoval u64 root_objectid = BTRFS_I(root_inode)->root->root_key.objectid; 1395bb289b7bSOmar Sandoval 1396bb289b7bSOmar Sandoval ret = 0; 1397bb289b7bSOmar Sandoval if (!is_subvolume_inode(root_inode)) { 1398ab8d0fc4SJeff Mahoney btrfs_err(fs_info, "'%s' is not a valid subvolume", 1399bb289b7bSOmar Sandoval subvol_name); 1400bb289b7bSOmar Sandoval ret = -EINVAL; 1401bb289b7bSOmar Sandoval } 1402bb289b7bSOmar Sandoval if (subvol_objectid && root_objectid != subvol_objectid) { 140305dbe683SOmar Sandoval /* 140405dbe683SOmar Sandoval * This will also catch a race condition where a 140505dbe683SOmar Sandoval * subvolume which was passed by ID is renamed and 140605dbe683SOmar Sandoval * another subvolume is renamed over the old location. 140705dbe683SOmar Sandoval */ 1408ab8d0fc4SJeff Mahoney btrfs_err(fs_info, 1409ab8d0fc4SJeff Mahoney "subvol '%s' does not match subvolid %llu", 1410bb289b7bSOmar Sandoval subvol_name, subvol_objectid); 1411bb289b7bSOmar Sandoval ret = -EINVAL; 1412bb289b7bSOmar Sandoval } 1413bb289b7bSOmar Sandoval if (ret) { 1414ea441d11SAl Viro dput(root); 1415bb289b7bSOmar Sandoval root = ERR_PTR(ret); 1416ea441d11SAl Viro deactivate_locked_super(s); 1417bb289b7bSOmar Sandoval } 1418f9d9ef62SDavid Sterba } 1419f9d9ef62SDavid Sterba 1420fa330659SOmar Sandoval out: 1421fa330659SOmar Sandoval mntput(mnt); 1422fa330659SOmar Sandoval kfree(subvol_name); 1423830c4adbSJosef Bacik return root; 1424830c4adbSJosef Bacik } 1425450ba0eaSJosef Bacik 1426312c89fbSMisono, Tomohiro /* 1427312c89fbSMisono, Tomohiro * Find a superblock for the given device / mount point. 1428312c89fbSMisono, Tomohiro * 1429312c89fbSMisono, Tomohiro * Note: This is based on mount_bdev from fs/super.c with a few additions 1430312c89fbSMisono, Tomohiro * for multiple device setup. Make sure to keep it in sync. 1431312c89fbSMisono, Tomohiro */ 143272fa39f5SMisono, Tomohiro static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, 143372fa39f5SMisono, Tomohiro int flags, const char *device_name, void *data) 143472fa39f5SMisono, Tomohiro { 143572fa39f5SMisono, Tomohiro struct block_device *bdev = NULL; 143672fa39f5SMisono, Tomohiro struct super_block *s; 143736350e95SGu Jinxiang struct btrfs_device *device = NULL; 143872fa39f5SMisono, Tomohiro struct btrfs_fs_devices *fs_devices = NULL; 143972fa39f5SMisono, Tomohiro struct btrfs_fs_info *fs_info = NULL; 1440204cc0ccSAl Viro void *new_sec_opts = NULL; 144172fa39f5SMisono, Tomohiro fmode_t mode = FMODE_READ; 144272fa39f5SMisono, Tomohiro int error = 0; 144372fa39f5SMisono, Tomohiro 144472fa39f5SMisono, Tomohiro if (!(flags & SB_RDONLY)) 144572fa39f5SMisono, Tomohiro mode |= FMODE_WRITE; 144672fa39f5SMisono, Tomohiro 144772fa39f5SMisono, Tomohiro if (data) { 1448a65001e8SAl Viro error = security_sb_eat_lsm_opts(data, &new_sec_opts); 144972fa39f5SMisono, Tomohiro if (error) 145072fa39f5SMisono, Tomohiro return ERR_PTR(error); 145172fa39f5SMisono, Tomohiro } 145272fa39f5SMisono, Tomohiro 145372fa39f5SMisono, Tomohiro /* 145472fa39f5SMisono, Tomohiro * Setup a dummy root and fs_info for test/set super. This is because 145572fa39f5SMisono, Tomohiro * we don't actually fill this stuff out until open_ctree, but we need 14568260edbaSJosef Bacik * then open_ctree will properly initialize the file system specific 14578260edbaSJosef Bacik * settings later. btrfs_init_fs_info initializes the static elements 14588260edbaSJosef Bacik * of the fs_info (locks and such) to make cleanup easier if we find a 14598260edbaSJosef Bacik * superblock with our given fs_devices later on at sget() time. 146072fa39f5SMisono, Tomohiro */ 1461a8fd1f71SJeff Mahoney fs_info = kvzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL); 146272fa39f5SMisono, Tomohiro if (!fs_info) { 146372fa39f5SMisono, Tomohiro error = -ENOMEM; 146472fa39f5SMisono, Tomohiro goto error_sec_opts; 146572fa39f5SMisono, Tomohiro } 14668260edbaSJosef Bacik btrfs_init_fs_info(fs_info); 146772fa39f5SMisono, Tomohiro 146872fa39f5SMisono, Tomohiro fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); 146972fa39f5SMisono, Tomohiro fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); 147072fa39f5SMisono, Tomohiro if (!fs_info->super_copy || !fs_info->super_for_commit) { 147172fa39f5SMisono, Tomohiro error = -ENOMEM; 147272fa39f5SMisono, Tomohiro goto error_fs_info; 147372fa39f5SMisono, Tomohiro } 147472fa39f5SMisono, Tomohiro 1475f5194e34SDavid Sterba mutex_lock(&uuid_mutex); 1476fa59f27cSAnand Jain error = btrfs_parse_device_options(data, mode, fs_type); 147781ffd56bSDavid Sterba if (error) { 1478399f7f4cSDavid Sterba mutex_unlock(&uuid_mutex); 1479399f7f4cSDavid Sterba goto error_fs_info; 148081ffd56bSDavid Sterba } 1481399f7f4cSDavid Sterba 148236350e95SGu Jinxiang device = btrfs_scan_one_device(device_name, mode, fs_type); 148336350e95SGu Jinxiang if (IS_ERR(device)) { 1484399f7f4cSDavid Sterba mutex_unlock(&uuid_mutex); 148536350e95SGu Jinxiang error = PTR_ERR(device); 1486399f7f4cSDavid Sterba goto error_fs_info; 148781ffd56bSDavid Sterba } 1488399f7f4cSDavid Sterba 148936350e95SGu Jinxiang fs_devices = device->fs_devices; 1490399f7f4cSDavid Sterba fs_info->fs_devices = fs_devices; 1491399f7f4cSDavid Sterba 149272fa39f5SMisono, Tomohiro error = btrfs_open_devices(fs_devices, mode, fs_type); 1493f5194e34SDavid Sterba mutex_unlock(&uuid_mutex); 149472fa39f5SMisono, Tomohiro if (error) 149572fa39f5SMisono, Tomohiro goto error_fs_info; 149672fa39f5SMisono, Tomohiro 149772fa39f5SMisono, Tomohiro if (!(flags & SB_RDONLY) && fs_devices->rw_devices == 0) { 149872fa39f5SMisono, Tomohiro error = -EACCES; 149972fa39f5SMisono, Tomohiro goto error_close_devices; 150072fa39f5SMisono, Tomohiro } 150172fa39f5SMisono, Tomohiro 1502d24fa5c1SAnand Jain bdev = fs_devices->latest_dev->bdev; 150372fa39f5SMisono, Tomohiro s = sget(fs_type, btrfs_test_super, btrfs_set_super, flags | SB_NOSEC, 150472fa39f5SMisono, Tomohiro fs_info); 150572fa39f5SMisono, Tomohiro if (IS_ERR(s)) { 150672fa39f5SMisono, Tomohiro error = PTR_ERR(s); 150772fa39f5SMisono, Tomohiro goto error_close_devices; 150872fa39f5SMisono, Tomohiro } 150972fa39f5SMisono, Tomohiro 151072fa39f5SMisono, Tomohiro if (s->s_root) { 151172fa39f5SMisono, Tomohiro btrfs_close_devices(fs_devices); 15120d4b0463SJosef Bacik btrfs_free_fs_info(fs_info); 151372fa39f5SMisono, Tomohiro if ((flags ^ s->s_flags) & SB_RDONLY) 151472fa39f5SMisono, Tomohiro error = -EBUSY; 151572fa39f5SMisono, Tomohiro } else { 151672fa39f5SMisono, Tomohiro snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev); 1517e33c267aSRoman Gushchin shrinker_debugfs_rename(&s->s_shrink, "sb-%s:%s", fs_type->name, 1518e33c267aSRoman Gushchin s->s_id); 151972fa39f5SMisono, Tomohiro btrfs_sb(s)->bdev_holder = fs_type; 152072fa39f5SMisono, Tomohiro error = btrfs_fill_super(s, fs_devices, data); 152172fa39f5SMisono, Tomohiro } 1522a65001e8SAl Viro if (!error) 1523204cc0ccSAl Viro error = security_sb_set_mnt_opts(s, new_sec_opts, 0, NULL); 1524a65001e8SAl Viro security_free_mnt_opts(&new_sec_opts); 152572fa39f5SMisono, Tomohiro if (error) { 152672fa39f5SMisono, Tomohiro deactivate_locked_super(s); 1527a65001e8SAl Viro return ERR_PTR(error); 152872fa39f5SMisono, Tomohiro } 152972fa39f5SMisono, Tomohiro 153072fa39f5SMisono, Tomohiro return dget(s->s_root); 153172fa39f5SMisono, Tomohiro 153272fa39f5SMisono, Tomohiro error_close_devices: 153372fa39f5SMisono, Tomohiro btrfs_close_devices(fs_devices); 153472fa39f5SMisono, Tomohiro error_fs_info: 15350d4b0463SJosef Bacik btrfs_free_fs_info(fs_info); 153672fa39f5SMisono, Tomohiro error_sec_opts: 153772fa39f5SMisono, Tomohiro security_free_mnt_opts(&new_sec_opts); 153872fa39f5SMisono, Tomohiro return ERR_PTR(error); 153972fa39f5SMisono, Tomohiro } 1540312c89fbSMisono, Tomohiro 1541edf24abeSChristoph Hellwig /* 1542312c89fbSMisono, Tomohiro * Mount function which is called by VFS layer. 1543edf24abeSChristoph Hellwig * 1544312c89fbSMisono, Tomohiro * In order to allow mounting a subvolume directly, btrfs uses mount_subtree() 1545312c89fbSMisono, Tomohiro * which needs vfsmount* of device's root (/). This means device's root has to 1546312c89fbSMisono, Tomohiro * be mounted internally in any case. 1547312c89fbSMisono, Tomohiro * 1548312c89fbSMisono, Tomohiro * Operation flow: 1549312c89fbSMisono, Tomohiro * 1. Parse subvol id related options for later use in mount_subvol(). 1550312c89fbSMisono, Tomohiro * 1551312c89fbSMisono, Tomohiro * 2. Mount device's root (/) by calling vfs_kern_mount(). 1552312c89fbSMisono, Tomohiro * 1553312c89fbSMisono, Tomohiro * NOTE: vfs_kern_mount() is used by VFS to call btrfs_mount() in the 1554312c89fbSMisono, Tomohiro * first place. In order to avoid calling btrfs_mount() again, we use 1555312c89fbSMisono, Tomohiro * different file_system_type which is not registered to VFS by 1556312c89fbSMisono, Tomohiro * register_filesystem() (btrfs_root_fs_type). As a result, 1557312c89fbSMisono, Tomohiro * btrfs_mount_root() is called. The return value will be used by 1558312c89fbSMisono, Tomohiro * mount_subtree() in mount_subvol(). 1559312c89fbSMisono, Tomohiro * 1560312c89fbSMisono, Tomohiro * 3. Call mount_subvol() to get the dentry of subvolume. Since there is 1561312c89fbSMisono, Tomohiro * "btrfs subvolume set-default", mount_subvol() is called always. 1562edf24abeSChristoph Hellwig */ 1563061dbc6bSAl Viro static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, 1564306e16ceSDavid Sterba const char *device_name, void *data) 15654b82d6e4SYan { 1566312c89fbSMisono, Tomohiro struct vfsmount *mnt_root; 1567312c89fbSMisono, Tomohiro struct dentry *root; 156873f73415SJosef Bacik char *subvol_name = NULL; 156973f73415SJosef Bacik u64 subvol_objectid = 0; 15704b82d6e4SYan int error = 0; 15714b82d6e4SYan 157293b9bcdfSGu Jinxiang error = btrfs_parse_subvol_options(data, &subvol_name, 157393b9bcdfSGu Jinxiang &subvol_objectid); 1574f23c8af8SIlya Dryomov if (error) { 1575f23c8af8SIlya Dryomov kfree(subvol_name); 1576061dbc6bSAl Viro return ERR_PTR(error); 1577f23c8af8SIlya Dryomov } 1578edf24abeSChristoph Hellwig 1579312c89fbSMisono, Tomohiro /* mount device's root (/) */ 1580312c89fbSMisono, Tomohiro mnt_root = vfs_kern_mount(&btrfs_root_fs_type, flags, device_name, data); 1581312c89fbSMisono, Tomohiro if (PTR_ERR_OR_ZERO(mnt_root) == -EBUSY) { 1582312c89fbSMisono, Tomohiro if (flags & SB_RDONLY) { 1583312c89fbSMisono, Tomohiro mnt_root = vfs_kern_mount(&btrfs_root_fs_type, 1584312c89fbSMisono, Tomohiro flags & ~SB_RDONLY, device_name, data); 15854b82d6e4SYan } else { 1586312c89fbSMisono, Tomohiro mnt_root = vfs_kern_mount(&btrfs_root_fs_type, 1587312c89fbSMisono, Tomohiro flags | SB_RDONLY, device_name, data); 1588312c89fbSMisono, Tomohiro if (IS_ERR(mnt_root)) { 1589312c89fbSMisono, Tomohiro root = ERR_CAST(mnt_root); 1590532b618bSEric W. Biederman kfree(subvol_name); 1591312c89fbSMisono, Tomohiro goto out; 1592f667aef6SQu Wenruo } 1593f667aef6SQu Wenruo 1594312c89fbSMisono, Tomohiro down_write(&mnt_root->mnt_sb->s_umount); 1595312c89fbSMisono, Tomohiro error = btrfs_remount(mnt_root->mnt_sb, &flags, NULL); 1596312c89fbSMisono, Tomohiro up_write(&mnt_root->mnt_sb->s_umount); 1597312c89fbSMisono, Tomohiro if (error < 0) { 1598312c89fbSMisono, Tomohiro root = ERR_PTR(error); 1599312c89fbSMisono, Tomohiro mntput(mnt_root); 1600532b618bSEric W. Biederman kfree(subvol_name); 1601312c89fbSMisono, Tomohiro goto out; 1602312c89fbSMisono, Tomohiro } 1603312c89fbSMisono, Tomohiro } 1604312c89fbSMisono, Tomohiro } 1605312c89fbSMisono, Tomohiro if (IS_ERR(mnt_root)) { 1606312c89fbSMisono, Tomohiro root = ERR_CAST(mnt_root); 1607532b618bSEric W. Biederman kfree(subvol_name); 1608312c89fbSMisono, Tomohiro goto out; 1609f667aef6SQu Wenruo } 16104b82d6e4SYan 1611312c89fbSMisono, Tomohiro /* mount_subvol() will free subvol_name and mnt_root */ 1612ae0bc863SAnand Jain root = mount_subvol(subvol_name, subvol_objectid, mnt_root); 16134b82d6e4SYan 1614312c89fbSMisono, Tomohiro out: 1615312c89fbSMisono, Tomohiro return root; 16164b82d6e4SYan } 16172e635a27SChris Mason 16180d2450abSSergei Trofimovich static void btrfs_resize_thread_pool(struct btrfs_fs_info *fs_info, 1619f7b885beSAnand Jain u32 new_pool_size, u32 old_pool_size) 16200d2450abSSergei Trofimovich { 16210d2450abSSergei Trofimovich if (new_pool_size == old_pool_size) 16220d2450abSSergei Trofimovich return; 16230d2450abSSergei Trofimovich 16240d2450abSSergei Trofimovich fs_info->thread_pool_size = new_pool_size; 16250d2450abSSergei Trofimovich 1626efe120a0SFrank Holton btrfs_info(fs_info, "resize thread pool %d -> %d", 16270d2450abSSergei Trofimovich old_pool_size, new_pool_size); 16280d2450abSSergei Trofimovich 16295cdc7ad3SQu Wenruo btrfs_workqueue_set_max(fs_info->workers, new_pool_size); 1630a31b4a43SChristoph Hellwig btrfs_workqueue_set_max(fs_info->hipri_workers, new_pool_size); 1631afe3d242SQu Wenruo btrfs_workqueue_set_max(fs_info->delalloc_workers, new_pool_size); 1632e66f0bb1SQu Wenruo btrfs_workqueue_set_max(fs_info->caching_workers, new_pool_size); 163340fac647SChristoph Hellwig workqueue_set_max_active(fs_info->endio_workers, new_pool_size); 163440fac647SChristoph Hellwig workqueue_set_max_active(fs_info->endio_meta_workers, new_pool_size); 1635fccb5d86SQu Wenruo btrfs_workqueue_set_max(fs_info->endio_write_workers, new_pool_size); 1636fccb5d86SQu Wenruo btrfs_workqueue_set_max(fs_info->endio_freespace_worker, new_pool_size); 16375b3bc44eSQu Wenruo btrfs_workqueue_set_max(fs_info->delayed_workers, new_pool_size); 16380d2450abSSergei Trofimovich } 16390d2450abSSergei Trofimovich 1640f42a34b2SMiao Xie static inline void btrfs_remount_begin(struct btrfs_fs_info *fs_info, 1641f42a34b2SMiao Xie unsigned long old_opts, int flags) 1642f42a34b2SMiao Xie { 1643dc81cdc5SMiao Xie if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) && 1644dc81cdc5SMiao Xie (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) || 16451751e8a6SLinus Torvalds (flags & SB_RDONLY))) { 1646dc81cdc5SMiao Xie /* wait for any defraggers to finish */ 1647dc81cdc5SMiao Xie wait_event(fs_info->transaction_wait, 1648dc81cdc5SMiao Xie (atomic_read(&fs_info->defrag_running) == 0)); 16491751e8a6SLinus Torvalds if (flags & SB_RDONLY) 1650dc81cdc5SMiao Xie sync_filesystem(fs_info->sb); 1651dc81cdc5SMiao Xie } 1652dc81cdc5SMiao Xie } 1653dc81cdc5SMiao Xie 1654dc81cdc5SMiao Xie static inline void btrfs_remount_cleanup(struct btrfs_fs_info *fs_info, 1655dc81cdc5SMiao Xie unsigned long old_opts) 1656dc81cdc5SMiao Xie { 165794846229SBoris Burkov const bool cache_opt = btrfs_test_opt(fs_info, SPACE_CACHE); 165894846229SBoris Burkov 1659dc81cdc5SMiao Xie /* 1660180e4d47SLuis de Bethencourt * We need to cleanup all defragable inodes if the autodefragment is 1661180e4d47SLuis de Bethencourt * close or the filesystem is read only. 1662dc81cdc5SMiao Xie */ 1663dc81cdc5SMiao Xie if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) && 1664bc98a42cSDavid Howells (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) || sb_rdonly(fs_info->sb))) { 1665dc81cdc5SMiao Xie btrfs_cleanup_defrag_inodes(fs_info); 1666dc81cdc5SMiao Xie } 1667dc81cdc5SMiao Xie 1668b0643e59SDennis Zhou /* If we toggled discard async */ 1669b0643e59SDennis Zhou if (!btrfs_raw_test_opt(old_opts, DISCARD_ASYNC) && 1670b0643e59SDennis Zhou btrfs_test_opt(fs_info, DISCARD_ASYNC)) 1671b0643e59SDennis Zhou btrfs_discard_resume(fs_info); 1672b0643e59SDennis Zhou else if (btrfs_raw_test_opt(old_opts, DISCARD_ASYNC) && 1673b0643e59SDennis Zhou !btrfs_test_opt(fs_info, DISCARD_ASYNC)) 1674b0643e59SDennis Zhou btrfs_discard_cleanup(fs_info); 167594846229SBoris Burkov 167694846229SBoris Burkov /* If we toggled space cache */ 167794846229SBoris Burkov if (cache_opt != btrfs_free_space_cache_v1_active(fs_info)) 167894846229SBoris Burkov btrfs_set_free_space_cache_v1_active(fs_info, cache_opt); 1679dc81cdc5SMiao Xie } 1680dc81cdc5SMiao Xie 1681c146afadSYan Zheng static int btrfs_remount(struct super_block *sb, int *flags, char *data) 1682c146afadSYan Zheng { 1683815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(sb); 168449b25e05SJeff Mahoney unsigned old_flags = sb->s_flags; 168549b25e05SJeff Mahoney unsigned long old_opts = fs_info->mount_opt; 168649b25e05SJeff Mahoney unsigned long old_compress_type = fs_info->compress_type; 168749b25e05SJeff Mahoney u64 old_max_inline = fs_info->max_inline; 1688f7b885beSAnand Jain u32 old_thread_pool_size = fs_info->thread_pool_size; 1689d612ac59SAnand Jain u32 old_metadata_ratio = fs_info->metadata_ratio; 1690c146afadSYan Zheng int ret; 1691c146afadSYan Zheng 169202b9984dSTheodore Ts'o sync_filesystem(sb); 169388c4703fSJohannes Thumshirn set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); 1694dc81cdc5SMiao Xie 1695f667aef6SQu Wenruo if (data) { 1696204cc0ccSAl Viro void *new_sec_opts = NULL; 1697f667aef6SQu Wenruo 1698a65001e8SAl Viro ret = security_sb_eat_lsm_opts(data, &new_sec_opts); 1699a65001e8SAl Viro if (!ret) 1700204cc0ccSAl Viro ret = security_sb_remount(sb, new_sec_opts); 1701a65001e8SAl Viro security_free_mnt_opts(&new_sec_opts); 1702f667aef6SQu Wenruo if (ret) 1703f667aef6SQu Wenruo goto restore; 1704f667aef6SQu Wenruo } 1705f667aef6SQu Wenruo 17062ff7e61eSJeff Mahoney ret = btrfs_parse_options(fs_info, data, *flags); 1707891f41cbSChengguang Xu if (ret) 170849b25e05SJeff Mahoney goto restore; 1709b288052eSChris Mason 17102ba48b20SQu Wenruo ret = btrfs_check_features(fs_info, !(*flags & SB_RDONLY)); 1711d7f67ac9SQu Wenruo if (ret < 0) 17120591f040SQu Wenruo goto restore; 1713d7f67ac9SQu Wenruo 1714f42a34b2SMiao Xie btrfs_remount_begin(fs_info, old_opts, *flags); 17150d2450abSSergei Trofimovich btrfs_resize_thread_pool(fs_info, 17160d2450abSSergei Trofimovich fs_info->thread_pool_size, old_thread_pool_size); 17170d2450abSSergei Trofimovich 1718c55a4319SBoris Burkov if ((bool)btrfs_test_opt(fs_info, FREE_SPACE_TREE) != 1719c55a4319SBoris Burkov (bool)btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) && 17202838d255SBoris Burkov (!sb_rdonly(sb) || (*flags & SB_RDONLY))) { 17212838d255SBoris Burkov btrfs_warn(fs_info, 17222838d255SBoris Burkov "remount supports changing free space tree only from ro to rw"); 17232838d255SBoris Burkov /* Make sure free space cache options match the state on disk */ 17242838d255SBoris Burkov if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) { 17252838d255SBoris Burkov btrfs_set_opt(fs_info->mount_opt, FREE_SPACE_TREE); 17262838d255SBoris Burkov btrfs_clear_opt(fs_info->mount_opt, SPACE_CACHE); 17272838d255SBoris Burkov } 17282838d255SBoris Burkov if (btrfs_free_space_cache_v1_active(fs_info)) { 17292838d255SBoris Burkov btrfs_clear_opt(fs_info->mount_opt, FREE_SPACE_TREE); 17302838d255SBoris Burkov btrfs_set_opt(fs_info->mount_opt, SPACE_CACHE); 17312838d255SBoris Burkov } 17322838d255SBoris Burkov } 17332838d255SBoris Burkov 17341751e8a6SLinus Torvalds if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb)) 1735dc81cdc5SMiao Xie goto out; 1736c146afadSYan Zheng 17371751e8a6SLinus Torvalds if (*flags & SB_RDONLY) { 17388dabb742SStefan Behrens /* 17398dabb742SStefan Behrens * this also happens on 'umount -rf' or on shutdown, when 17408dabb742SStefan Behrens * the filesystem is busy. 17418dabb742SStefan Behrens */ 174221c7e756SMiao Xie cancel_work_sync(&fs_info->async_reclaim_work); 174357056740SJosef Bacik cancel_work_sync(&fs_info->async_data_reclaim_work); 1744361c093dSStefan Behrens 1745b0643e59SDennis Zhou btrfs_discard_cleanup(fs_info); 1746b0643e59SDennis Zhou 1747361c093dSStefan Behrens /* wait for the uuid_scan task to finish */ 1748361c093dSStefan Behrens down(&fs_info->uuid_tree_rescan_sem); 1749361c093dSStefan Behrens /* avoid complains from lockdep et al. */ 1750361c093dSStefan Behrens up(&fs_info->uuid_tree_rescan_sem); 1751361c093dSStefan Behrens 1752a0a1db70SFilipe Manana btrfs_set_sb_rdonly(sb); 1753c146afadSYan Zheng 1754e44163e1SJeff Mahoney /* 17551751e8a6SLinus Torvalds * Setting SB_RDONLY will put the cleaner thread to 1756e44163e1SJeff Mahoney * sleep at the next loop if it's already active. 1757e44163e1SJeff Mahoney * If it's already asleep, we'll leave unused block 1758e44163e1SJeff Mahoney * groups on disk until we're mounted read-write again 1759e44163e1SJeff Mahoney * unless we clean them up here. 1760e44163e1SJeff Mahoney */ 1761e44163e1SJeff Mahoney btrfs_delete_unused_bgs(fs_info); 1762e44163e1SJeff Mahoney 1763a0a1db70SFilipe Manana /* 1764a0a1db70SFilipe Manana * The cleaner task could be already running before we set the 1765a0a1db70SFilipe Manana * flag BTRFS_FS_STATE_RO (and SB_RDONLY in the superblock). 1766a0a1db70SFilipe Manana * We must make sure that after we finish the remount, i.e. after 1767a0a1db70SFilipe Manana * we call btrfs_commit_super(), the cleaner can no longer start 1768a0a1db70SFilipe Manana * a transaction - either because it was dropping a dead root, 1769a0a1db70SFilipe Manana * running delayed iputs or deleting an unused block group (the 1770a0a1db70SFilipe Manana * cleaner picked a block group from the list of unused block 1771a0a1db70SFilipe Manana * groups before we were able to in the previous call to 1772a0a1db70SFilipe Manana * btrfs_delete_unused_bgs()). 1773a0a1db70SFilipe Manana */ 1774a0a1db70SFilipe Manana wait_on_bit(&fs_info->flags, BTRFS_FS_CLEANER_RUNNING, 1775a0a1db70SFilipe Manana TASK_UNINTERRUPTIBLE); 1776a0a1db70SFilipe Manana 1777a8cc263eSFilipe Manana /* 1778a8cc263eSFilipe Manana * We've set the superblock to RO mode, so we might have made 1779a8cc263eSFilipe Manana * the cleaner task sleep without running all pending delayed 1780a8cc263eSFilipe Manana * iputs. Go through all the delayed iputs here, so that if an 1781a8cc263eSFilipe Manana * unmount happens without remounting RW we don't end up at 1782a8cc263eSFilipe Manana * finishing close_ctree() with a non-empty list of delayed 1783a8cc263eSFilipe Manana * iputs. 1784a8cc263eSFilipe Manana */ 1785a8cc263eSFilipe Manana btrfs_run_delayed_iputs(fs_info); 1786a8cc263eSFilipe Manana 17878dabb742SStefan Behrens btrfs_dev_replace_suspend_for_unmount(fs_info); 17888dabb742SStefan Behrens btrfs_scrub_cancel(fs_info); 1789061594efSMiao Xie btrfs_pause_balance(fs_info); 17908dabb742SStefan Behrens 1791cb13eea3SFilipe Manana /* 1792cb13eea3SFilipe Manana * Pause the qgroup rescan worker if it is running. We don't want 1793cb13eea3SFilipe Manana * it to be still running after we are in RO mode, as after that, 1794cb13eea3SFilipe Manana * by the time we unmount, it might have left a transaction open, 1795cb13eea3SFilipe Manana * so we would leak the transaction and/or crash. 1796cb13eea3SFilipe Manana */ 1797cb13eea3SFilipe Manana btrfs_qgroup_wait_for_completion(fs_info, false); 1798cb13eea3SFilipe Manana 17996bccf3abSJeff Mahoney ret = btrfs_commit_super(fs_info); 180049b25e05SJeff Mahoney if (ret) 180149b25e05SJeff Mahoney goto restore; 1802c146afadSYan Zheng } else { 180384961539SJosef Bacik if (BTRFS_FS_ERROR(fs_info)) { 18046ef3de9cSDavid Sterba btrfs_err(fs_info, 1805efe120a0SFrank Holton "Remounting read-write after error is not allowed"); 18066ef3de9cSDavid Sterba ret = -EINVAL; 18076ef3de9cSDavid Sterba goto restore; 18086ef3de9cSDavid Sterba } 18098a3db184SSergei Trofimovich if (fs_info->fs_devices->rw_devices == 0) { 181049b25e05SJeff Mahoney ret = -EACCES; 181149b25e05SJeff Mahoney goto restore; 18128a3db184SSergei Trofimovich } 18132b82032cSYan Zheng 18146528b99dSAnand Jain if (!btrfs_check_rw_degradable(fs_info, NULL)) { 1815efe120a0SFrank Holton btrfs_warn(fs_info, 181652042d8eSAndrea Gelmini "too many missing devices, writable remount is not allowed"); 1817292fd7fcSStefan Behrens ret = -EACCES; 1818292fd7fcSStefan Behrens goto restore; 1819292fd7fcSStefan Behrens } 1820292fd7fcSStefan Behrens 18218a3db184SSergei Trofimovich if (btrfs_super_log_root(fs_info->super_copy) != 0) { 182210a3a3edSDavid Sterba btrfs_warn(fs_info, 182310a3a3edSDavid Sterba "mount required to replay tree-log, cannot remount read-write"); 182449b25e05SJeff Mahoney ret = -EINVAL; 182549b25e05SJeff Mahoney goto restore; 18268a3db184SSergei Trofimovich } 1827c146afadSYan Zheng 182844c0ca21SBoris Burkov /* 182944c0ca21SBoris Burkov * NOTE: when remounting with a change that does writes, don't 183044c0ca21SBoris Burkov * put it anywhere above this point, as we are not sure to be 183144c0ca21SBoris Burkov * safe to write until we pass the above checks. 183244c0ca21SBoris Burkov */ 183344c0ca21SBoris Burkov ret = btrfs_start_pre_rw_mount(fs_info); 183449b25e05SJeff Mahoney if (ret) 183549b25e05SJeff Mahoney goto restore; 1836c146afadSYan Zheng 1837a0a1db70SFilipe Manana btrfs_clear_sb_rdonly(sb); 183890c711abSZygo Blaxell 1839afcdd129SJosef Bacik set_bit(BTRFS_FS_OPEN, &fs_info->flags); 1840c146afadSYan Zheng } 1841dc81cdc5SMiao Xie out: 1842faa00889SJosef Bacik /* 1843faa00889SJosef Bacik * We need to set SB_I_VERSION here otherwise it'll get cleared by VFS, 1844faa00889SJosef Bacik * since the absence of the flag means it can be toggled off by remount. 1845faa00889SJosef Bacik */ 1846faa00889SJosef Bacik *flags |= SB_I_VERSION; 1847faa00889SJosef Bacik 18482c6a92b0SJustin Maggard wake_up_process(fs_info->transaction_kthread); 1849dc81cdc5SMiao Xie btrfs_remount_cleanup(fs_info, old_opts); 18508cd29088SBoris Burkov btrfs_clear_oneshot_options(fs_info); 185188c4703fSJohannes Thumshirn clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); 185288c4703fSJohannes Thumshirn 1853c146afadSYan Zheng return 0; 185449b25e05SJeff Mahoney 185549b25e05SJeff Mahoney restore: 18561751e8a6SLinus Torvalds /* We've hit an error - don't reset SB_RDONLY */ 1857bc98a42cSDavid Howells if (sb_rdonly(sb)) 18581751e8a6SLinus Torvalds old_flags |= SB_RDONLY; 1859a0a1db70SFilipe Manana if (!(old_flags & SB_RDONLY)) 1860a0a1db70SFilipe Manana clear_bit(BTRFS_FS_STATE_RO, &fs_info->fs_state); 186149b25e05SJeff Mahoney sb->s_flags = old_flags; 186249b25e05SJeff Mahoney fs_info->mount_opt = old_opts; 186349b25e05SJeff Mahoney fs_info->compress_type = old_compress_type; 186449b25e05SJeff Mahoney fs_info->max_inline = old_max_inline; 18650d2450abSSergei Trofimovich btrfs_resize_thread_pool(fs_info, 18660d2450abSSergei Trofimovich old_thread_pool_size, fs_info->thread_pool_size); 186749b25e05SJeff Mahoney fs_info->metadata_ratio = old_metadata_ratio; 1868dc81cdc5SMiao Xie btrfs_remount_cleanup(fs_info, old_opts); 186988c4703fSJohannes Thumshirn clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); 187088c4703fSJohannes Thumshirn 187149b25e05SJeff Mahoney return ret; 1872c146afadSYan Zheng } 1873c146afadSYan Zheng 1874bcd53741SArne Jansen /* Used to sort the devices by max_avail(descending sort) */ 1875214cc184SDavid Sterba static int btrfs_cmp_device_free_bytes(const void *a, const void *b) 1876bcd53741SArne Jansen { 1877214cc184SDavid Sterba const struct btrfs_device_info *dev_info1 = a; 1878214cc184SDavid Sterba const struct btrfs_device_info *dev_info2 = b; 1879214cc184SDavid Sterba 1880214cc184SDavid Sterba if (dev_info1->max_avail > dev_info2->max_avail) 1881bcd53741SArne Jansen return -1; 1882214cc184SDavid Sterba else if (dev_info1->max_avail < dev_info2->max_avail) 1883bcd53741SArne Jansen return 1; 1884bcd53741SArne Jansen return 0; 1885bcd53741SArne Jansen } 1886bcd53741SArne Jansen 1887bcd53741SArne Jansen /* 1888bcd53741SArne Jansen * sort the devices by max_avail, in which max free extent size of each device 1889bcd53741SArne Jansen * is stored.(Descending Sort) 1890bcd53741SArne Jansen */ 1891bcd53741SArne Jansen static inline void btrfs_descending_sort_devices( 1892bcd53741SArne Jansen struct btrfs_device_info *devices, 1893bcd53741SArne Jansen size_t nr_devices) 1894bcd53741SArne Jansen { 1895bcd53741SArne Jansen sort(devices, nr_devices, sizeof(struct btrfs_device_info), 1896bcd53741SArne Jansen btrfs_cmp_device_free_bytes, NULL); 1897bcd53741SArne Jansen } 1898bcd53741SArne Jansen 18996d07bcecSMiao Xie /* 19006d07bcecSMiao Xie * The helper to calc the free space on the devices that can be used to store 19016d07bcecSMiao Xie * file data. 19026d07bcecSMiao Xie */ 19037e17916bSArnd Bergmann static inline int btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info, 19046bccf3abSJeff Mahoney u64 *free_bytes) 19056d07bcecSMiao Xie { 19066d07bcecSMiao Xie struct btrfs_device_info *devices_info; 19076d07bcecSMiao Xie struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; 19086d07bcecSMiao Xie struct btrfs_device *device; 19096d07bcecSMiao Xie u64 type; 19106d07bcecSMiao Xie u64 avail_space; 19116d07bcecSMiao Xie u64 min_stripe_size; 1912559ca6eaSNikolay Borisov int num_stripes = 1; 19136d07bcecSMiao Xie int i = 0, nr_devices; 19144f080f57SDavid Sterba const struct btrfs_raid_attr *rattr; 19156d07bcecSMiao Xie 19167e33fd99SJosef Bacik /* 191701327610SNicholas D Steeves * We aren't under the device list lock, so this is racy-ish, but good 19187e33fd99SJosef Bacik * enough for our purposes. 19197e33fd99SJosef Bacik */ 1920b772a86eSLi Zefan nr_devices = fs_info->fs_devices->open_devices; 19217e33fd99SJosef Bacik if (!nr_devices) { 19227e33fd99SJosef Bacik smp_mb(); 19237e33fd99SJosef Bacik nr_devices = fs_info->fs_devices->open_devices; 19247e33fd99SJosef Bacik ASSERT(nr_devices); 19257e33fd99SJosef Bacik if (!nr_devices) { 19267e33fd99SJosef Bacik *free_bytes = 0; 19277e33fd99SJosef Bacik return 0; 19287e33fd99SJosef Bacik } 19297e33fd99SJosef Bacik } 19306d07bcecSMiao Xie 1931d9b0d9baSDulshani Gunawardhana devices_info = kmalloc_array(nr_devices, sizeof(*devices_info), 19326a44517dSDavid Sterba GFP_KERNEL); 19336d07bcecSMiao Xie if (!devices_info) 19346d07bcecSMiao Xie return -ENOMEM; 19356d07bcecSMiao Xie 193601327610SNicholas D Steeves /* calc min stripe number for data space allocation */ 19371b86826dSJeff Mahoney type = btrfs_data_alloc_profile(fs_info); 19384f080f57SDavid Sterba rattr = &btrfs_raid_array[btrfs_bg_flags_to_raid_index(type)]; 19394f080f57SDavid Sterba 1940e1ea2beeSDavid Sterba if (type & BTRFS_BLOCK_GROUP_RAID0) 194139fb26c3SMiao Xie num_stripes = nr_devices; 1942d09cb9e1SDavid Sterba else if (type & BTRFS_BLOCK_GROUP_RAID1_MASK) 1943d09cb9e1SDavid Sterba num_stripes = rattr->ncopies; 1944e1ea2beeSDavid Sterba else if (type & BTRFS_BLOCK_GROUP_RAID10) 194539fb26c3SMiao Xie num_stripes = 4; 19466d07bcecSMiao Xie 19474f080f57SDavid Sterba /* Adjust for more than 1 stripe per device */ 19484f080f57SDavid Sterba min_stripe_size = rattr->dev_stripes * BTRFS_STRIPE_LEN; 19496d07bcecSMiao Xie 19507e33fd99SJosef Bacik rcu_read_lock(); 19517e33fd99SJosef Bacik list_for_each_entry_rcu(device, &fs_devices->devices, dev_list) { 1952e12c9621SAnand Jain if (!test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, 1953e12c9621SAnand Jain &device->dev_state) || 1954401e29c1SAnand Jain !device->bdev || 1955401e29c1SAnand Jain test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state)) 19566d07bcecSMiao Xie continue; 19576d07bcecSMiao Xie 19587e33fd99SJosef Bacik if (i >= nr_devices) 19597e33fd99SJosef Bacik break; 19607e33fd99SJosef Bacik 19616d07bcecSMiao Xie avail_space = device->total_bytes - device->bytes_used; 19626d07bcecSMiao Xie 19636d07bcecSMiao Xie /* align with stripe_len */ 1964559ca6eaSNikolay Borisov avail_space = rounddown(avail_space, BTRFS_STRIPE_LEN); 19656d07bcecSMiao Xie 19666d07bcecSMiao Xie /* 196737f85ec3SQu Wenruo * Ensure we have at least min_stripe_size on top of the 196837f85ec3SQu Wenruo * reserved space on the device. 19696d07bcecSMiao Xie */ 197037f85ec3SQu Wenruo if (avail_space <= BTRFS_DEVICE_RANGE_RESERVED + min_stripe_size) 19716d07bcecSMiao Xie continue; 19726d07bcecSMiao Xie 197337f85ec3SQu Wenruo avail_space -= BTRFS_DEVICE_RANGE_RESERVED; 1974559ca6eaSNikolay Borisov 19756d07bcecSMiao Xie devices_info[i].dev = device; 19766d07bcecSMiao Xie devices_info[i].max_avail = avail_space; 19776d07bcecSMiao Xie 19786d07bcecSMiao Xie i++; 19796d07bcecSMiao Xie } 19807e33fd99SJosef Bacik rcu_read_unlock(); 19816d07bcecSMiao Xie 19826d07bcecSMiao Xie nr_devices = i; 19836d07bcecSMiao Xie 19846d07bcecSMiao Xie btrfs_descending_sort_devices(devices_info, nr_devices); 19856d07bcecSMiao Xie 19866d07bcecSMiao Xie i = nr_devices - 1; 19876d07bcecSMiao Xie avail_space = 0; 1988559ca6eaSNikolay Borisov while (nr_devices >= rattr->devs_min) { 1989559ca6eaSNikolay Borisov num_stripes = min(num_stripes, nr_devices); 199039fb26c3SMiao Xie 19916d07bcecSMiao Xie if (devices_info[i].max_avail >= min_stripe_size) { 19926d07bcecSMiao Xie int j; 19936d07bcecSMiao Xie u64 alloc_size; 19946d07bcecSMiao Xie 199539fb26c3SMiao Xie avail_space += devices_info[i].max_avail * num_stripes; 19966d07bcecSMiao Xie alloc_size = devices_info[i].max_avail; 199739fb26c3SMiao Xie for (j = i + 1 - num_stripes; j <= i; j++) 19986d07bcecSMiao Xie devices_info[j].max_avail -= alloc_size; 19996d07bcecSMiao Xie } 20006d07bcecSMiao Xie i--; 20016d07bcecSMiao Xie nr_devices--; 20026d07bcecSMiao Xie } 20036d07bcecSMiao Xie 20046d07bcecSMiao Xie kfree(devices_info); 20056d07bcecSMiao Xie *free_bytes = avail_space; 20066d07bcecSMiao Xie return 0; 20076d07bcecSMiao Xie } 20086d07bcecSMiao Xie 2009ba7b6e62SDavid Sterba /* 2010ba7b6e62SDavid Sterba * Calculate numbers for 'df', pessimistic in case of mixed raid profiles. 2011ba7b6e62SDavid Sterba * 2012ba7b6e62SDavid Sterba * If there's a redundant raid level at DATA block groups, use the respective 2013ba7b6e62SDavid Sterba * multiplier to scale the sizes. 2014ba7b6e62SDavid Sterba * 2015ba7b6e62SDavid Sterba * Unused device space usage is based on simulating the chunk allocator 20160d0c71b3SDavid Sterba * algorithm that respects the device sizes and order of allocations. This is 20170d0c71b3SDavid Sterba * a close approximation of the actual use but there are other factors that may 20180d0c71b3SDavid Sterba * change the result (like a new metadata chunk). 2019ba7b6e62SDavid Sterba * 2020ca8a51b3SDavid Sterba * If metadata is exhausted, f_bavail will be 0. 2021ba7b6e62SDavid Sterba */ 20228fd17795SChris Mason static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) 20238fd17795SChris Mason { 2024815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(dentry->d_sb); 2025815745cfSAl Viro struct btrfs_super_block *disk_super = fs_info->super_copy; 2026bd4d1088SJosef Bacik struct btrfs_space_info *found; 2027bd4d1088SJosef Bacik u64 total_used = 0; 20286d07bcecSMiao Xie u64 total_free_data = 0; 2029ca8a51b3SDavid Sterba u64 total_free_meta = 0; 2030265fdfa6SDavid Sterba u32 bits = fs_info->sectorsize_bits; 2031de37aa51SNikolay Borisov __be32 *fsid = (__be32 *)fs_info->fs_devices->fsid; 2032ba7b6e62SDavid Sterba unsigned factor = 1; 2033ba7b6e62SDavid Sterba struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; 20346d07bcecSMiao Xie int ret; 2035ca8a51b3SDavid Sterba u64 thresh = 0; 2036ae02d1bdSLuis de Bethencourt int mixed = 0; 20378fd17795SChris Mason 203872804905SJosef Bacik list_for_each_entry(found, &fs_info->space_info, list) { 20396d07bcecSMiao Xie if (found->flags & BTRFS_BLOCK_GROUP_DATA) { 2040ba7b6e62SDavid Sterba int i; 2041ba7b6e62SDavid Sterba 20426d07bcecSMiao Xie total_free_data += found->disk_total - found->disk_used; 20436d07bcecSMiao Xie total_free_data -= 20446d07bcecSMiao Xie btrfs_account_ro_block_groups_free_space(found); 2045ba7b6e62SDavid Sterba 2046ba7b6e62SDavid Sterba for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) { 204746df06b8SDavid Sterba if (!list_empty(&found->block_groups[i])) 204846df06b8SDavid Sterba factor = btrfs_bg_type_to_factor( 204946df06b8SDavid Sterba btrfs_raid_array[i].bg_flag); 2050ba7b6e62SDavid Sterba } 20516d07bcecSMiao Xie } 2052ae02d1bdSLuis de Bethencourt 2053ae02d1bdSLuis de Bethencourt /* 205467da05b3SColin Ian King * Metadata in mixed block group profiles are accounted in data 2055ae02d1bdSLuis de Bethencourt */ 2056ae02d1bdSLuis de Bethencourt if (!mixed && found->flags & BTRFS_BLOCK_GROUP_METADATA) { 2057ae02d1bdSLuis de Bethencourt if (found->flags & BTRFS_BLOCK_GROUP_DATA) 2058ae02d1bdSLuis de Bethencourt mixed = 1; 2059ae02d1bdSLuis de Bethencourt else 2060ae02d1bdSLuis de Bethencourt total_free_meta += found->disk_total - 2061ae02d1bdSLuis de Bethencourt found->disk_used; 2062ae02d1bdSLuis de Bethencourt } 20636d07bcecSMiao Xie 2064b742bb82SYan, Zheng total_used += found->disk_used; 206589a55897SJosef Bacik } 2066ba7b6e62SDavid Sterba 2067ba7b6e62SDavid Sterba buf->f_blocks = div_u64(btrfs_super_total_bytes(disk_super), factor); 2068ba7b6e62SDavid Sterba buf->f_blocks >>= bits; 2069ba7b6e62SDavid Sterba buf->f_bfree = buf->f_blocks - (div_u64(total_used, factor) >> bits); 2070ba7b6e62SDavid Sterba 2071ba7b6e62SDavid Sterba /* Account global block reserve as used, it's in logical size already */ 2072ba7b6e62SDavid Sterba spin_lock(&block_rsv->lock); 207341b34accSLuis de Bethencourt /* Mixed block groups accounting is not byte-accurate, avoid overflow */ 207441b34accSLuis de Bethencourt if (buf->f_bfree >= block_rsv->size >> bits) 2075ba7b6e62SDavid Sterba buf->f_bfree -= block_rsv->size >> bits; 207641b34accSLuis de Bethencourt else 207741b34accSLuis de Bethencourt buf->f_bfree = 0; 2078ba7b6e62SDavid Sterba spin_unlock(&block_rsv->lock); 2079ba7b6e62SDavid Sterba 20800d95c1beSDavid Sterba buf->f_bavail = div_u64(total_free_data, factor); 20816bccf3abSJeff Mahoney ret = btrfs_calc_avail_data_space(fs_info, &total_free_data); 20827e33fd99SJosef Bacik if (ret) 20836d07bcecSMiao Xie return ret; 2084ba7b6e62SDavid Sterba buf->f_bavail += div_u64(total_free_data, factor); 20856d07bcecSMiao Xie buf->f_bavail = buf->f_bavail >> bits; 2086d397712bSChris Mason 2087ca8a51b3SDavid Sterba /* 2088ca8a51b3SDavid Sterba * We calculate the remaining metadata space minus global reserve. If 2089ca8a51b3SDavid Sterba * this is (supposedly) smaller than zero, there's no space. But this 2090ca8a51b3SDavid Sterba * does not hold in practice, the exhausted state happens where's still 2091ca8a51b3SDavid Sterba * some positive delta. So we apply some guesswork and compare the 2092ca8a51b3SDavid Sterba * delta to a 4M threshold. (Practically observed delta was ~2M.) 2093ca8a51b3SDavid Sterba * 2094ca8a51b3SDavid Sterba * We probably cannot calculate the exact threshold value because this 2095ca8a51b3SDavid Sterba * depends on the internal reservations requested by various 2096ca8a51b3SDavid Sterba * operations, so some operations that consume a few metadata will 2097ca8a51b3SDavid Sterba * succeed even if the Avail is zero. But this is better than the other 2098ca8a51b3SDavid Sterba * way around. 2099ca8a51b3SDavid Sterba */ 2100d4417e22SNikolay Borisov thresh = SZ_4M; 2101ca8a51b3SDavid Sterba 2102d55966c4SJosef Bacik /* 2103d55966c4SJosef Bacik * We only want to claim there's no available space if we can no longer 2104d55966c4SJosef Bacik * allocate chunks for our metadata profile and our global reserve will 2105d55966c4SJosef Bacik * not fit in the free metadata space. If we aren't ->full then we 2106d55966c4SJosef Bacik * still can allocate chunks and thus are fine using the currently 2107d55966c4SJosef Bacik * calculated f_bavail. 2108d55966c4SJosef Bacik */ 2109d55966c4SJosef Bacik if (!mixed && block_rsv->space_info->full && 2110d55966c4SJosef Bacik total_free_meta - thresh < block_rsv->size) 2111ca8a51b3SDavid Sterba buf->f_bavail = 0; 2112ca8a51b3SDavid Sterba 2113ba7b6e62SDavid Sterba buf->f_type = BTRFS_SUPER_MAGIC; 2114ba7b6e62SDavid Sterba buf->f_bsize = dentry->d_sb->s_blocksize; 2115ba7b6e62SDavid Sterba buf->f_namelen = BTRFS_NAME_LEN; 2116ba7b6e62SDavid Sterba 21179d03632eSDavid Woodhouse /* We treat it as constant endianness (it doesn't matter _which_) 21189d03632eSDavid Woodhouse because we want the fsid to come out the same whether mounted 21199d03632eSDavid Woodhouse on a big-endian or little-endian host */ 21209d03632eSDavid Woodhouse buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]); 21219d03632eSDavid Woodhouse buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]); 212232d48fa1SDavid Woodhouse /* Mask in the root object ID too, to disambiguate subvols */ 21234fd786e6SMisono Tomohiro buf->f_fsid.val[0] ^= 21244fd786e6SMisono Tomohiro BTRFS_I(d_inode(dentry))->root->root_key.objectid >> 32; 21254fd786e6SMisono Tomohiro buf->f_fsid.val[1] ^= 21264fd786e6SMisono Tomohiro BTRFS_I(d_inode(dentry))->root->root_key.objectid; 212732d48fa1SDavid Woodhouse 21288fd17795SChris Mason return 0; 21298fd17795SChris Mason } 2130b5133862SChris Mason 2131aea52e19SAl Viro static void btrfs_kill_super(struct super_block *sb) 2132aea52e19SAl Viro { 2133815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(sb); 2134aea52e19SAl Viro kill_anon_super(sb); 21350d4b0463SJosef Bacik btrfs_free_fs_info(fs_info); 2136aea52e19SAl Viro } 2137aea52e19SAl Viro 21382e635a27SChris Mason static struct file_system_type btrfs_fs_type = { 21392e635a27SChris Mason .owner = THIS_MODULE, 21402e635a27SChris Mason .name = "btrfs", 2141061dbc6bSAl Viro .mount = btrfs_mount, 2142aea52e19SAl Viro .kill_sb = btrfs_kill_super, 2143f667aef6SQu Wenruo .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA, 21442e635a27SChris Mason }; 214572fa39f5SMisono, Tomohiro 214672fa39f5SMisono, Tomohiro static struct file_system_type btrfs_root_fs_type = { 214772fa39f5SMisono, Tomohiro .owner = THIS_MODULE, 214872fa39f5SMisono, Tomohiro .name = "btrfs", 214972fa39f5SMisono, Tomohiro .mount = btrfs_mount_root, 215072fa39f5SMisono, Tomohiro .kill_sb = btrfs_kill_super, 21515b9b26f5SChristian Brauner .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA | FS_ALLOW_IDMAP, 215272fa39f5SMisono, Tomohiro }; 215372fa39f5SMisono, Tomohiro 21547f78e035SEric W. Biederman MODULE_ALIAS_FS("btrfs"); 2155a9218f6bSChris Mason 2156d8620958STom Van Braeckel static int btrfs_control_open(struct inode *inode, struct file *file) 2157d8620958STom Van Braeckel { 2158d8620958STom Van Braeckel /* 2159d8620958STom Van Braeckel * The control file's private_data is used to hold the 2160d8620958STom Van Braeckel * transaction when it is started and is used to keep 2161d8620958STom Van Braeckel * track of whether a transaction is already in progress. 2162d8620958STom Van Braeckel */ 2163d8620958STom Van Braeckel file->private_data = NULL; 2164d8620958STom Van Braeckel return 0; 2165d8620958STom Van Braeckel } 2166d8620958STom Van Braeckel 2167d352ac68SChris Mason /* 2168cfe953c8SSu Yue * Used by /dev/btrfs-control for devices ioctls. 2169d352ac68SChris Mason */ 21708a4b83ccSChris Mason static long btrfs_control_ioctl(struct file *file, unsigned int cmd, 21718a4b83ccSChris Mason unsigned long arg) 21728a4b83ccSChris Mason { 21738a4b83ccSChris Mason struct btrfs_ioctl_vol_args *vol; 217436350e95SGu Jinxiang struct btrfs_device *device = NULL; 217516cab91aSAnand Jain dev_t devt = 0; 2176c071fcfdSChris Mason int ret = -ENOTTY; 21778a4b83ccSChris Mason 2178e441d54dSChris Mason if (!capable(CAP_SYS_ADMIN)) 2179e441d54dSChris Mason return -EPERM; 2180e441d54dSChris Mason 2181dae7b665SLi Zefan vol = memdup_user((void __user *)arg, sizeof(*vol)); 2182dae7b665SLi Zefan if (IS_ERR(vol)) 2183dae7b665SLi Zefan return PTR_ERR(vol); 2184f505754fSFilipe Manana vol->name[BTRFS_PATH_NAME_MAX] = '\0'; 2185c071fcfdSChris Mason 21868a4b83ccSChris Mason switch (cmd) { 21878a4b83ccSChris Mason case BTRFS_IOC_SCAN_DEV: 2188899f9307SDavid Sterba mutex_lock(&uuid_mutex); 218936350e95SGu Jinxiang device = btrfs_scan_one_device(vol->name, FMODE_READ, 219036350e95SGu Jinxiang &btrfs_root_fs_type); 219136350e95SGu Jinxiang ret = PTR_ERR_OR_ZERO(device); 2192899f9307SDavid Sterba mutex_unlock(&uuid_mutex); 21938a4b83ccSChris Mason break; 2194228a73abSAnand Jain case BTRFS_IOC_FORGET_DEV: 219516cab91aSAnand Jain if (vol->name[0] != 0) { 219616cab91aSAnand Jain ret = lookup_bdev(vol->name, &devt); 219716cab91aSAnand Jain if (ret) 219816cab91aSAnand Jain break; 219916cab91aSAnand Jain } 220016cab91aSAnand Jain ret = btrfs_forget_devices(devt); 2201228a73abSAnand Jain break; 220202db0844SJosef Bacik case BTRFS_IOC_DEVICES_READY: 2203899f9307SDavid Sterba mutex_lock(&uuid_mutex); 220436350e95SGu Jinxiang device = btrfs_scan_one_device(vol->name, FMODE_READ, 220536350e95SGu Jinxiang &btrfs_root_fs_type); 220636350e95SGu Jinxiang if (IS_ERR(device)) { 2207899f9307SDavid Sterba mutex_unlock(&uuid_mutex); 220836350e95SGu Jinxiang ret = PTR_ERR(device); 220902db0844SJosef Bacik break; 2210899f9307SDavid Sterba } 221136350e95SGu Jinxiang ret = !(device->fs_devices->num_devices == 221236350e95SGu Jinxiang device->fs_devices->total_devices); 2213899f9307SDavid Sterba mutex_unlock(&uuid_mutex); 221402db0844SJosef Bacik break; 2215c5868f83SDavid Sterba case BTRFS_IOC_GET_SUPPORTED_FEATURES: 2216d5131b65SDavid Sterba ret = btrfs_ioctl_get_supported_features((void __user*)arg); 2217c5868f83SDavid Sterba break; 22188a4b83ccSChris Mason } 2219dae7b665SLi Zefan 22208a4b83ccSChris Mason kfree(vol); 2221f819d837SLinda Knippers return ret; 22228a4b83ccSChris Mason } 22238a4b83ccSChris Mason 22240176260fSLinus Torvalds static int btrfs_freeze(struct super_block *sb) 2225ed0dab6bSYan { 2226354aa0fbSMiao Xie struct btrfs_trans_handle *trans; 22270b246afaSJeff Mahoney struct btrfs_fs_info *fs_info = btrfs_sb(sb); 22280b246afaSJeff Mahoney struct btrfs_root *root = fs_info->tree_root; 2229354aa0fbSMiao Xie 2230fac03c8dSDavid Sterba set_bit(BTRFS_FS_FROZEN, &fs_info->flags); 22319e7cc91aSWang Xiaoguang /* 22329e7cc91aSWang Xiaoguang * We don't need a barrier here, we'll wait for any transaction that 22339e7cc91aSWang Xiaoguang * could be in progress on other threads (and do delayed iputs that 22349e7cc91aSWang Xiaoguang * we want to avoid on a frozen filesystem), or do the commit 22359e7cc91aSWang Xiaoguang * ourselves. 22369e7cc91aSWang Xiaoguang */ 2237d4edf39bSMiao Xie trans = btrfs_attach_transaction_barrier(root); 2238354aa0fbSMiao Xie if (IS_ERR(trans)) { 2239354aa0fbSMiao Xie /* no transaction, don't bother */ 2240354aa0fbSMiao Xie if (PTR_ERR(trans) == -ENOENT) 22410176260fSLinus Torvalds return 0; 2242354aa0fbSMiao Xie return PTR_ERR(trans); 2243354aa0fbSMiao Xie } 22443a45bb20SJeff Mahoney return btrfs_commit_transaction(trans); 2245ed0dab6bSYan } 2246ed0dab6bSYan 2247a05d3c91SQu Wenruo static int check_dev_super(struct btrfs_device *dev) 2248a05d3c91SQu Wenruo { 2249a05d3c91SQu Wenruo struct btrfs_fs_info *fs_info = dev->fs_info; 2250a05d3c91SQu Wenruo struct btrfs_super_block *sb; 22513d17adeaSQu Wenruo u16 csum_type; 2252a05d3c91SQu Wenruo int ret = 0; 2253a05d3c91SQu Wenruo 2254a05d3c91SQu Wenruo /* This should be called with fs still frozen. */ 2255a05d3c91SQu Wenruo ASSERT(test_bit(BTRFS_FS_FROZEN, &fs_info->flags)); 2256a05d3c91SQu Wenruo 2257a05d3c91SQu Wenruo /* Missing dev, no need to check. */ 2258a05d3c91SQu Wenruo if (!dev->bdev) 2259a05d3c91SQu Wenruo return 0; 2260a05d3c91SQu Wenruo 2261a05d3c91SQu Wenruo /* Only need to check the primary super block. */ 2262a05d3c91SQu Wenruo sb = btrfs_read_dev_one_super(dev->bdev, 0, true); 2263a05d3c91SQu Wenruo if (IS_ERR(sb)) 2264a05d3c91SQu Wenruo return PTR_ERR(sb); 2265a05d3c91SQu Wenruo 22663d17adeaSQu Wenruo /* Verify the checksum. */ 22673d17adeaSQu Wenruo csum_type = btrfs_super_csum_type(sb); 22683d17adeaSQu Wenruo if (csum_type != btrfs_super_csum_type(fs_info->super_copy)) { 22693d17adeaSQu Wenruo btrfs_err(fs_info, "csum type changed, has %u expect %u", 22703d17adeaSQu Wenruo csum_type, btrfs_super_csum_type(fs_info->super_copy)); 22713d17adeaSQu Wenruo ret = -EUCLEAN; 22723d17adeaSQu Wenruo goto out; 22733d17adeaSQu Wenruo } 22743d17adeaSQu Wenruo 22753d17adeaSQu Wenruo if (btrfs_check_super_csum(fs_info, sb)) { 22763d17adeaSQu Wenruo btrfs_err(fs_info, "csum for on-disk super block no longer matches"); 22773d17adeaSQu Wenruo ret = -EUCLEAN; 22783d17adeaSQu Wenruo goto out; 22793d17adeaSQu Wenruo } 22803d17adeaSQu Wenruo 2281a05d3c91SQu Wenruo /* Btrfs_validate_super() includes fsid check against super->fsid. */ 2282a05d3c91SQu Wenruo ret = btrfs_validate_super(fs_info, sb, 0); 2283a05d3c91SQu Wenruo if (ret < 0) 2284a05d3c91SQu Wenruo goto out; 2285a05d3c91SQu Wenruo 2286a05d3c91SQu Wenruo if (btrfs_super_generation(sb) != fs_info->last_trans_committed) { 2287a05d3c91SQu Wenruo btrfs_err(fs_info, "transid mismatch, has %llu expect %llu", 2288a05d3c91SQu Wenruo btrfs_super_generation(sb), 2289a05d3c91SQu Wenruo fs_info->last_trans_committed); 2290a05d3c91SQu Wenruo ret = -EUCLEAN; 2291a05d3c91SQu Wenruo goto out; 2292a05d3c91SQu Wenruo } 2293a05d3c91SQu Wenruo out: 2294a05d3c91SQu Wenruo btrfs_release_disk_super(sb); 2295a05d3c91SQu Wenruo return ret; 2296a05d3c91SQu Wenruo } 2297a05d3c91SQu Wenruo 22989e7cc91aSWang Xiaoguang static int btrfs_unfreeze(struct super_block *sb) 22999e7cc91aSWang Xiaoguang { 2300fac03c8dSDavid Sterba struct btrfs_fs_info *fs_info = btrfs_sb(sb); 2301a05d3c91SQu Wenruo struct btrfs_device *device; 2302a05d3c91SQu Wenruo int ret = 0; 2303fac03c8dSDavid Sterba 2304a05d3c91SQu Wenruo /* 2305a05d3c91SQu Wenruo * Make sure the fs is not changed by accident (like hibernation then 2306a05d3c91SQu Wenruo * modified by other OS). 2307a05d3c91SQu Wenruo * If we found anything wrong, we mark the fs error immediately. 2308a05d3c91SQu Wenruo * 2309a05d3c91SQu Wenruo * And since the fs is frozen, no one can modify the fs yet, thus 2310a05d3c91SQu Wenruo * we don't need to hold device_list_mutex. 2311a05d3c91SQu Wenruo */ 2312a05d3c91SQu Wenruo list_for_each_entry(device, &fs_info->fs_devices->devices, dev_list) { 2313a05d3c91SQu Wenruo ret = check_dev_super(device); 2314a05d3c91SQu Wenruo if (ret < 0) { 2315a05d3c91SQu Wenruo btrfs_handle_fs_error(fs_info, ret, 2316a05d3c91SQu Wenruo "super block on devid %llu got modified unexpectedly", 2317a05d3c91SQu Wenruo device->devid); 2318a05d3c91SQu Wenruo break; 2319a05d3c91SQu Wenruo } 2320a05d3c91SQu Wenruo } 2321fac03c8dSDavid Sterba clear_bit(BTRFS_FS_FROZEN, &fs_info->flags); 2322a05d3c91SQu Wenruo 2323a05d3c91SQu Wenruo /* 2324a05d3c91SQu Wenruo * We still return 0, to allow VFS layer to unfreeze the fs even the 2325a05d3c91SQu Wenruo * above checks failed. Since the fs is either fine or read-only, we're 2326a05d3c91SQu Wenruo * safe to continue, without causing further damage. 2327a05d3c91SQu Wenruo */ 23289e7cc91aSWang Xiaoguang return 0; 23299e7cc91aSWang Xiaoguang } 23309e7cc91aSWang Xiaoguang 23319c5085c1SJosef Bacik static int btrfs_show_devname(struct seq_file *m, struct dentry *root) 23329c5085c1SJosef Bacik { 23339c5085c1SJosef Bacik struct btrfs_fs_info *fs_info = btrfs_sb(root->d_sb); 23349c5085c1SJosef Bacik 233588c14590SDavid Sterba /* 23366605fd2fSAnand Jain * There should be always a valid pointer in latest_dev, it may be stale 23376605fd2fSAnand Jain * for a short moment in case it's being deleted but still valid until 23386605fd2fSAnand Jain * the end of RCU grace period. 233988c14590SDavid Sterba */ 234088c14590SDavid Sterba rcu_read_lock(); 2341cb3e217bSQu Wenruo seq_escape(m, btrfs_dev_name(fs_info->fs_devices->latest_dev), " \t\n\\"); 234288c14590SDavid Sterba rcu_read_unlock(); 23436605fd2fSAnand Jain 23449c5085c1SJosef Bacik return 0; 23459c5085c1SJosef Bacik } 23469c5085c1SJosef Bacik 2347b87221deSAlexey Dobriyan static const struct super_operations btrfs_super_ops = { 234876dda93cSYan, Zheng .drop_inode = btrfs_drop_inode, 2349bd555975SAl Viro .evict_inode = btrfs_evict_inode, 2350e20d96d6SChris Mason .put_super = btrfs_put_super, 2351d5719762SChris Mason .sync_fs = btrfs_sync_fs, 2352a9572a15SEric Paris .show_options = btrfs_show_options, 23539c5085c1SJosef Bacik .show_devname = btrfs_show_devname, 23542c90e5d6SChris Mason .alloc_inode = btrfs_alloc_inode, 23552c90e5d6SChris Mason .destroy_inode = btrfs_destroy_inode, 235626602cabSAl Viro .free_inode = btrfs_free_inode, 23578fd17795SChris Mason .statfs = btrfs_statfs, 2358c146afadSYan Zheng .remount_fs = btrfs_remount, 23590176260fSLinus Torvalds .freeze_fs = btrfs_freeze, 23609e7cc91aSWang Xiaoguang .unfreeze_fs = btrfs_unfreeze, 2361e20d96d6SChris Mason }; 2362a9218f6bSChris Mason 2363a9218f6bSChris Mason static const struct file_operations btrfs_ctl_fops = { 2364d8620958STom Van Braeckel .open = btrfs_control_open, 2365a9218f6bSChris Mason .unlocked_ioctl = btrfs_control_ioctl, 23661832f2d8SArnd Bergmann .compat_ioctl = compat_ptr_ioctl, 2367a9218f6bSChris Mason .owner = THIS_MODULE, 23686038f373SArnd Bergmann .llseek = noop_llseek, 2369a9218f6bSChris Mason }; 2370a9218f6bSChris Mason 2371a9218f6bSChris Mason static struct miscdevice btrfs_misc = { 2372578454ffSKay Sievers .minor = BTRFS_MINOR, 2373a9218f6bSChris Mason .name = "btrfs-control", 2374a9218f6bSChris Mason .fops = &btrfs_ctl_fops 2375a9218f6bSChris Mason }; 2376a9218f6bSChris Mason 2377578454ffSKay Sievers MODULE_ALIAS_MISCDEV(BTRFS_MINOR); 2378578454ffSKay Sievers MODULE_ALIAS("devname:btrfs-control"); 2379578454ffSKay Sievers 2380f5c29bd9SLiu Bo static int __init btrfs_interface_init(void) 2381a9218f6bSChris Mason { 2382a9218f6bSChris Mason return misc_register(&btrfs_misc); 2383a9218f6bSChris Mason } 2384a9218f6bSChris Mason 2385e67c718bSDavid Sterba static __cold void btrfs_interface_exit(void) 2386a9218f6bSChris Mason { 2387f368ed60SGreg Kroah-Hartman misc_deregister(&btrfs_misc); 2388a9218f6bSChris Mason } 2389a9218f6bSChris Mason 23905565b8e0SQu Wenruo static int __init btrfs_print_mod_info(void) 239185965600SDavid Sterba { 2392edf57cbfSBart Van Assche static const char options[] = "" 239385965600SDavid Sterba #ifdef CONFIG_BTRFS_DEBUG 239485965600SDavid Sterba ", debug=on" 239585965600SDavid Sterba #endif 239679556c3dSStefan Behrens #ifdef CONFIG_BTRFS_ASSERT 239779556c3dSStefan Behrens ", assert=on" 239879556c3dSStefan Behrens #endif 239985965600SDavid Sterba #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY 240085965600SDavid Sterba ", integrity-checker=on" 240185965600SDavid Sterba #endif 2402fb592373SJosef Bacik #ifdef CONFIG_BTRFS_FS_REF_VERIFY 2403fb592373SJosef Bacik ", ref-verify=on" 2404fb592373SJosef Bacik #endif 24055b316468SNaohiro Aota #ifdef CONFIG_BLK_DEV_ZONED 24065b316468SNaohiro Aota ", zoned=yes" 24075b316468SNaohiro Aota #else 24085b316468SNaohiro Aota ", zoned=no" 24095b316468SNaohiro Aota #endif 2410ea3dc7d2SDavid Sterba #ifdef CONFIG_FS_VERITY 2411ea3dc7d2SDavid Sterba ", fsverity=yes" 2412ea3dc7d2SDavid Sterba #else 2413ea3dc7d2SDavid Sterba ", fsverity=no" 2414ea3dc7d2SDavid Sterba #endif 2415edf57cbfSBart Van Assche ; 2416*6e7a367eSChristoph Hellwig pr_info("Btrfs loaded%s\n", options); 24175565b8e0SQu Wenruo return 0; 24185565b8e0SQu Wenruo } 24195565b8e0SQu Wenruo 24205565b8e0SQu Wenruo static int register_btrfs(void) 24215565b8e0SQu Wenruo { 24225565b8e0SQu Wenruo return register_filesystem(&btrfs_fs_type); 24235565b8e0SQu Wenruo } 24245565b8e0SQu Wenruo 24255565b8e0SQu Wenruo static void unregister_btrfs(void) 24265565b8e0SQu Wenruo { 24275565b8e0SQu Wenruo unregister_filesystem(&btrfs_fs_type); 24285565b8e0SQu Wenruo } 24295565b8e0SQu Wenruo 24305565b8e0SQu Wenruo /* Helper structure for long init/exit functions. */ 24315565b8e0SQu Wenruo struct init_sequence { 24325565b8e0SQu Wenruo int (*init_func)(void); 24335565b8e0SQu Wenruo /* Can be NULL if the init_func doesn't need cleanup. */ 24345565b8e0SQu Wenruo void (*exit_func)(void); 24355565b8e0SQu Wenruo }; 24365565b8e0SQu Wenruo 24375565b8e0SQu Wenruo static const struct init_sequence mod_init_seq[] = { 24385565b8e0SQu Wenruo { 24395565b8e0SQu Wenruo .init_func = btrfs_props_init, 24405565b8e0SQu Wenruo .exit_func = NULL, 24415565b8e0SQu Wenruo }, { 24425565b8e0SQu Wenruo .init_func = btrfs_init_sysfs, 24435565b8e0SQu Wenruo .exit_func = btrfs_exit_sysfs, 24445565b8e0SQu Wenruo }, { 24455565b8e0SQu Wenruo .init_func = btrfs_init_compress, 24465565b8e0SQu Wenruo .exit_func = btrfs_exit_compress, 24475565b8e0SQu Wenruo }, { 24485565b8e0SQu Wenruo .init_func = btrfs_init_cachep, 24495565b8e0SQu Wenruo .exit_func = btrfs_destroy_cachep, 24505565b8e0SQu Wenruo }, { 24515565b8e0SQu Wenruo .init_func = btrfs_transaction_init, 24525565b8e0SQu Wenruo .exit_func = btrfs_transaction_exit, 24535565b8e0SQu Wenruo }, { 24545565b8e0SQu Wenruo .init_func = btrfs_ctree_init, 24555565b8e0SQu Wenruo .exit_func = btrfs_ctree_exit, 24565565b8e0SQu Wenruo }, { 24575565b8e0SQu Wenruo .init_func = btrfs_free_space_init, 24585565b8e0SQu Wenruo .exit_func = btrfs_free_space_exit, 24595565b8e0SQu Wenruo }, { 24605565b8e0SQu Wenruo .init_func = extent_state_init_cachep, 24615565b8e0SQu Wenruo .exit_func = extent_state_free_cachep, 24625565b8e0SQu Wenruo }, { 24635565b8e0SQu Wenruo .init_func = extent_buffer_init_cachep, 24645565b8e0SQu Wenruo .exit_func = extent_buffer_free_cachep, 24655565b8e0SQu Wenruo }, { 24665565b8e0SQu Wenruo .init_func = btrfs_bioset_init, 24675565b8e0SQu Wenruo .exit_func = btrfs_bioset_exit, 24685565b8e0SQu Wenruo }, { 24695565b8e0SQu Wenruo .init_func = extent_map_init, 24705565b8e0SQu Wenruo .exit_func = extent_map_exit, 24715565b8e0SQu Wenruo }, { 24725565b8e0SQu Wenruo .init_func = ordered_data_init, 24735565b8e0SQu Wenruo .exit_func = ordered_data_exit, 24745565b8e0SQu Wenruo }, { 24755565b8e0SQu Wenruo .init_func = btrfs_delayed_inode_init, 24765565b8e0SQu Wenruo .exit_func = btrfs_delayed_inode_exit, 24775565b8e0SQu Wenruo }, { 24785565b8e0SQu Wenruo .init_func = btrfs_auto_defrag_init, 24795565b8e0SQu Wenruo .exit_func = btrfs_auto_defrag_exit, 24805565b8e0SQu Wenruo }, { 24815565b8e0SQu Wenruo .init_func = btrfs_delayed_ref_init, 24825565b8e0SQu Wenruo .exit_func = btrfs_delayed_ref_exit, 24835565b8e0SQu Wenruo }, { 24845565b8e0SQu Wenruo .init_func = btrfs_prelim_ref_init, 24855565b8e0SQu Wenruo .exit_func = btrfs_prelim_ref_exit, 24865565b8e0SQu Wenruo }, { 24875565b8e0SQu Wenruo .init_func = btrfs_interface_init, 24885565b8e0SQu Wenruo .exit_func = btrfs_interface_exit, 24895565b8e0SQu Wenruo }, { 24905565b8e0SQu Wenruo .init_func = btrfs_print_mod_info, 24915565b8e0SQu Wenruo .exit_func = NULL, 24925565b8e0SQu Wenruo }, { 24935565b8e0SQu Wenruo .init_func = btrfs_run_sanity_tests, 24945565b8e0SQu Wenruo .exit_func = NULL, 24955565b8e0SQu Wenruo }, { 24965565b8e0SQu Wenruo .init_func = register_btrfs, 24975565b8e0SQu Wenruo .exit_func = unregister_btrfs, 24985565b8e0SQu Wenruo } 24995565b8e0SQu Wenruo }; 25005565b8e0SQu Wenruo 25015565b8e0SQu Wenruo static bool mod_init_result[ARRAY_SIZE(mod_init_seq)]; 25025565b8e0SQu Wenruo 250382c0efd3SAnand Jain static __always_inline void btrfs_exit_btrfs_fs(void) 25045565b8e0SQu Wenruo { 25055565b8e0SQu Wenruo int i; 25065565b8e0SQu Wenruo 25075565b8e0SQu Wenruo for (i = ARRAY_SIZE(mod_init_seq) - 1; i >= 0; i--) { 25085565b8e0SQu Wenruo if (!mod_init_result[i]) 25095565b8e0SQu Wenruo continue; 25105565b8e0SQu Wenruo if (mod_init_seq[i].exit_func) 25115565b8e0SQu Wenruo mod_init_seq[i].exit_func(); 25125565b8e0SQu Wenruo mod_init_result[i] = false; 25135565b8e0SQu Wenruo } 251485965600SDavid Sterba } 251585965600SDavid Sterba 251682c0efd3SAnand Jain static void __exit exit_btrfs_fs(void) 251782c0efd3SAnand Jain { 251882c0efd3SAnand Jain btrfs_exit_btrfs_fs(); 2519c68f7290SFilipe Manana btrfs_cleanup_fs_uuids(); 252082c0efd3SAnand Jain } 252182c0efd3SAnand Jain 25222e635a27SChris Mason static int __init init_btrfs_fs(void) 25232e635a27SChris Mason { 25245565b8e0SQu Wenruo int ret; 25255565b8e0SQu Wenruo int i; 252658176a96SJosef Bacik 25275565b8e0SQu Wenruo for (i = 0; i < ARRAY_SIZE(mod_init_seq); i++) { 25285565b8e0SQu Wenruo ASSERT(!mod_init_result[i]); 25295565b8e0SQu Wenruo ret = mod_init_seq[i].init_func(); 253082c0efd3SAnand Jain if (ret < 0) { 253182c0efd3SAnand Jain btrfs_exit_btrfs_fs(); 253282c0efd3SAnand Jain return ret; 253382c0efd3SAnand Jain } 25345565b8e0SQu Wenruo mod_init_result[i] = true; 25355565b8e0SQu Wenruo } 25362f4cbe64SWyatt Banks return 0; 25372e635a27SChris Mason } 25382e635a27SChris Mason 253960efa5ebSFilipe David Borba Manana late_initcall(init_btrfs_fs); 25402e635a27SChris Mason module_exit(exit_btrfs_fs) 25412e635a27SChris Mason 25422e635a27SChris Mason MODULE_LICENSE("GPL"); 2543d5178578SJohannes Thumshirn MODULE_SOFTDEP("pre: crc32c"); 25443951e7f0SJohannes Thumshirn MODULE_SOFTDEP("pre: xxhash64"); 25453831bf00SJohannes Thumshirn MODULE_SOFTDEP("pre: sha256"); 2546352ae07bSDavid Sterba MODULE_SOFTDEP("pre: blake2b-256"); 2547