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" 611abe9b8aSliubo #define CREATE_TRACE_POINTS 621abe9b8aSliubo #include <trace/events/btrfs.h> 631abe9b8aSliubo 64b87221deSAlexey Dobriyan static const struct super_operations btrfs_super_ops; 6572fa39f5SMisono, Tomohiro 6672fa39f5SMisono, Tomohiro /* 6772fa39f5SMisono, Tomohiro * Types for mounting the default subvolume and a subvolume explicitly 6872fa39f5SMisono, Tomohiro * requested by subvol=/path. That way the callchain is straightforward and we 6972fa39f5SMisono, Tomohiro * don't have to play tricks with the mount options and recursive calls to 7072fa39f5SMisono, Tomohiro * btrfs_mount. 71312c89fbSMisono, Tomohiro * 72312c89fbSMisono, Tomohiro * The new btrfs_root_fs_type also servers as a tag for the bdev_holder. 7372fa39f5SMisono, Tomohiro */ 74830c4adbSJosef Bacik static struct file_system_type btrfs_fs_type; 7572fa39f5SMisono, Tomohiro static struct file_system_type btrfs_root_fs_type; 76e20d96d6SChris Mason 770723a047SHarald Hoyer static int btrfs_remount(struct super_block *sb, int *flags, char *data); 780723a047SHarald Hoyer 79e20d96d6SChris Mason static void btrfs_put_super(struct super_block *sb) 80e20d96d6SChris Mason { 816bccf3abSJeff Mahoney close_ctree(btrfs_sb(sb)); 82e20d96d6SChris Mason } 832e635a27SChris Mason 8495e05289SChris Mason enum { 85416a7202SDavid Sterba Opt_acl, Opt_noacl, 86416a7202SDavid Sterba Opt_clear_cache, 87416a7202SDavid Sterba Opt_commit_interval, 88416a7202SDavid Sterba Opt_compress, 89416a7202SDavid Sterba Opt_compress_force, 90416a7202SDavid Sterba Opt_compress_force_type, 91416a7202SDavid Sterba Opt_compress_type, 92416a7202SDavid Sterba Opt_degraded, 93416a7202SDavid Sterba Opt_device, 94416a7202SDavid Sterba Opt_fatal_errors, 95416a7202SDavid Sterba Opt_flushoncommit, Opt_noflushoncommit, 96416a7202SDavid Sterba Opt_max_inline, 97416a7202SDavid Sterba Opt_barrier, Opt_nobarrier, 98416a7202SDavid Sterba Opt_datacow, Opt_nodatacow, 99416a7202SDavid Sterba Opt_datasum, Opt_nodatasum, 100416a7202SDavid Sterba Opt_defrag, Opt_nodefrag, 101416a7202SDavid Sterba Opt_discard, Opt_nodiscard, 102b0643e59SDennis Zhou Opt_discard_mode, 103416a7202SDavid Sterba Opt_norecovery, 104416a7202SDavid Sterba Opt_ratio, 105416a7202SDavid Sterba Opt_rescan_uuid_tree, 106416a7202SDavid Sterba Opt_skip_balance, 107416a7202SDavid Sterba Opt_space_cache, Opt_no_space_cache, 108416a7202SDavid Sterba Opt_space_cache_version, 109416a7202SDavid Sterba Opt_ssd, Opt_nossd, 110416a7202SDavid Sterba Opt_ssd_spread, Opt_nossd_spread, 111416a7202SDavid Sterba Opt_subvol, 11237becec9SOmar Sandoval Opt_subvol_empty, 113416a7202SDavid Sterba Opt_subvolid, 114416a7202SDavid Sterba Opt_thread_pool, 115416a7202SDavid Sterba Opt_treelog, Opt_notreelog, 116416a7202SDavid Sterba Opt_user_subvol_rm_allowed, 117416a7202SDavid Sterba 11874ef0018SQu Wenruo /* Rescue options */ 11974ef0018SQu Wenruo Opt_rescue, 12074ef0018SQu Wenruo Opt_usebackuproot, 12174ef0018SQu Wenruo Opt_nologreplay, 12242437a63SJosef Bacik Opt_ignorebadroots, 123882dbe0cSJosef Bacik Opt_ignoredatacsums, 1249037d3cbSJosef Bacik Opt_rescue_all, 12574ef0018SQu Wenruo 126416a7202SDavid Sterba /* Deprecated options */ 127416a7202SDavid Sterba Opt_recovery, 1285297199aSNikolay Borisov Opt_inode_cache, Opt_noinode_cache, 129416a7202SDavid Sterba 130416a7202SDavid Sterba /* Debugging options */ 131416a7202SDavid Sterba Opt_check_integrity, 13270f6d82eSOmar Sandoval Opt_check_integrity_including_extent_data, 133416a7202SDavid Sterba Opt_check_integrity_print_mask, 134416a7202SDavid Sterba Opt_enospc_debug, Opt_noenospc_debug, 135d0bd4560SJosef Bacik #ifdef CONFIG_BTRFS_DEBUG 136d0bd4560SJosef Bacik Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all, 137d0bd4560SJosef Bacik #endif 138fb592373SJosef Bacik #ifdef CONFIG_BTRFS_FS_REF_VERIFY 139fb592373SJosef Bacik Opt_ref_verify, 140fb592373SJosef Bacik #endif 1419555c6c1SIlya Dryomov Opt_err, 14295e05289SChris Mason }; 14395e05289SChris Mason 1444d4ab6d6SDavid Sterba static const match_table_t tokens = { 145416a7202SDavid Sterba {Opt_acl, "acl"}, 146416a7202SDavid Sterba {Opt_noacl, "noacl"}, 147416a7202SDavid Sterba {Opt_clear_cache, "clear_cache"}, 148416a7202SDavid Sterba {Opt_commit_interval, "commit=%u"}, 149c8b97818SChris Mason {Opt_compress, "compress"}, 150261507a0SLi Zefan {Opt_compress_type, "compress=%s"}, 151a555f810SChris Mason {Opt_compress_force, "compress-force"}, 152261507a0SLi Zefan {Opt_compress_force_type, "compress-force=%s"}, 153416a7202SDavid Sterba {Opt_degraded, "degraded"}, 154416a7202SDavid Sterba {Opt_device, "device=%s"}, 155416a7202SDavid Sterba {Opt_fatal_errors, "fatal_errors=%s"}, 156dccae999SSage Weil {Opt_flushoncommit, "flushoncommit"}, 1572c9ee856SQu Wenruo {Opt_noflushoncommit, "noflushoncommit"}, 1584b9465cbSChris Mason {Opt_inode_cache, "inode_cache"}, 1593818aea2SQu Wenruo {Opt_noinode_cache, "noinode_cache"}, 160416a7202SDavid Sterba {Opt_max_inline, "max_inline=%s"}, 161416a7202SDavid Sterba {Opt_barrier, "barrier"}, 162416a7202SDavid Sterba {Opt_nobarrier, "nobarrier"}, 163416a7202SDavid Sterba {Opt_datacow, "datacow"}, 164416a7202SDavid Sterba {Opt_nodatacow, "nodatacow"}, 165416a7202SDavid Sterba {Opt_datasum, "datasum"}, 166416a7202SDavid Sterba {Opt_nodatasum, "nodatasum"}, 167416a7202SDavid Sterba {Opt_defrag, "autodefrag"}, 168416a7202SDavid Sterba {Opt_nodefrag, "noautodefrag"}, 169416a7202SDavid Sterba {Opt_discard, "discard"}, 170b0643e59SDennis Zhou {Opt_discard_mode, "discard=%s"}, 171416a7202SDavid Sterba {Opt_nodiscard, "nodiscard"}, 172416a7202SDavid Sterba {Opt_norecovery, "norecovery"}, 173416a7202SDavid Sterba {Opt_ratio, "metadata_ratio=%u"}, 174416a7202SDavid Sterba {Opt_rescan_uuid_tree, "rescan_uuid_tree"}, 1759555c6c1SIlya Dryomov {Opt_skip_balance, "skip_balance"}, 176416a7202SDavid Sterba {Opt_space_cache, "space_cache"}, 177416a7202SDavid Sterba {Opt_no_space_cache, "nospace_cache"}, 178416a7202SDavid Sterba {Opt_space_cache_version, "space_cache=%s"}, 179416a7202SDavid Sterba {Opt_ssd, "ssd"}, 180416a7202SDavid Sterba {Opt_nossd, "nossd"}, 181416a7202SDavid Sterba {Opt_ssd_spread, "ssd_spread"}, 182416a7202SDavid Sterba {Opt_nossd_spread, "nossd_spread"}, 183416a7202SDavid Sterba {Opt_subvol, "subvol=%s"}, 18437becec9SOmar Sandoval {Opt_subvol_empty, "subvol="}, 185416a7202SDavid Sterba {Opt_subvolid, "subvolid=%s"}, 186416a7202SDavid Sterba {Opt_thread_pool, "thread_pool=%u"}, 187416a7202SDavid Sterba {Opt_treelog, "treelog"}, 188416a7202SDavid Sterba {Opt_notreelog, "notreelog"}, 189416a7202SDavid Sterba {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, 190416a7202SDavid Sterba 19174ef0018SQu Wenruo /* Rescue options */ 19274ef0018SQu Wenruo {Opt_rescue, "rescue=%s"}, 19374ef0018SQu Wenruo /* Deprecated, with alias rescue=nologreplay */ 19474ef0018SQu Wenruo {Opt_nologreplay, "nologreplay"}, 19574ef0018SQu Wenruo /* Deprecated, with alias rescue=usebackuproot */ 19674ef0018SQu Wenruo {Opt_usebackuproot, "usebackuproot"}, 19774ef0018SQu Wenruo 198416a7202SDavid Sterba /* Deprecated options */ 199416a7202SDavid Sterba {Opt_recovery, "recovery"}, 200416a7202SDavid Sterba 201416a7202SDavid Sterba /* Debugging options */ 20221adbd5cSStefan Behrens {Opt_check_integrity, "check_int"}, 20321adbd5cSStefan Behrens {Opt_check_integrity_including_extent_data, "check_int_data"}, 20402453bdeSAnand Jain {Opt_check_integrity_print_mask, "check_int_print_mask=%u"}, 205416a7202SDavid Sterba {Opt_enospc_debug, "enospc_debug"}, 206416a7202SDavid Sterba {Opt_noenospc_debug, "noenospc_debug"}, 207d0bd4560SJosef Bacik #ifdef CONFIG_BTRFS_DEBUG 208d0bd4560SJosef Bacik {Opt_fragment_data, "fragment=data"}, 209d0bd4560SJosef Bacik {Opt_fragment_metadata, "fragment=metadata"}, 210d0bd4560SJosef Bacik {Opt_fragment_all, "fragment=all"}, 211d0bd4560SJosef Bacik #endif 212fb592373SJosef Bacik #ifdef CONFIG_BTRFS_FS_REF_VERIFY 213fb592373SJosef Bacik {Opt_ref_verify, "ref_verify"}, 214fb592373SJosef Bacik #endif 21533268eafSJosef Bacik {Opt_err, NULL}, 21695e05289SChris Mason }; 21795e05289SChris Mason 21874ef0018SQu Wenruo static const match_table_t rescue_tokens = { 21974ef0018SQu Wenruo {Opt_usebackuproot, "usebackuproot"}, 22074ef0018SQu Wenruo {Opt_nologreplay, "nologreplay"}, 22142437a63SJosef Bacik {Opt_ignorebadroots, "ignorebadroots"}, 22242437a63SJosef Bacik {Opt_ignorebadroots, "ibadroots"}, 223882dbe0cSJosef Bacik {Opt_ignoredatacsums, "ignoredatacsums"}, 224882dbe0cSJosef Bacik {Opt_ignoredatacsums, "idatacsums"}, 2259037d3cbSJosef Bacik {Opt_rescue_all, "all"}, 22674ef0018SQu Wenruo {Opt_err, NULL}, 22774ef0018SQu Wenruo }; 22874ef0018SQu Wenruo 229d70bf748SJosef Bacik static bool check_ro_option(struct btrfs_fs_info *fs_info, unsigned long opt, 230d70bf748SJosef Bacik const char *opt_name) 231d70bf748SJosef Bacik { 232d70bf748SJosef Bacik if (fs_info->mount_opt & opt) { 233d70bf748SJosef Bacik btrfs_err(fs_info, "%s must be used with ro mount option", 234d70bf748SJosef Bacik opt_name); 235d70bf748SJosef Bacik return true; 236d70bf748SJosef Bacik } 237d70bf748SJosef Bacik return false; 238d70bf748SJosef Bacik } 239d70bf748SJosef Bacik 24074ef0018SQu Wenruo static int parse_rescue_options(struct btrfs_fs_info *info, const char *options) 24174ef0018SQu Wenruo { 24274ef0018SQu Wenruo char *opts; 24374ef0018SQu Wenruo char *orig; 24474ef0018SQu Wenruo char *p; 24574ef0018SQu Wenruo substring_t args[MAX_OPT_ARGS]; 24674ef0018SQu Wenruo int ret = 0; 24774ef0018SQu Wenruo 24874ef0018SQu Wenruo opts = kstrdup(options, GFP_KERNEL); 24974ef0018SQu Wenruo if (!opts) 25074ef0018SQu Wenruo return -ENOMEM; 25174ef0018SQu Wenruo orig = opts; 25274ef0018SQu Wenruo 25374ef0018SQu Wenruo while ((p = strsep(&opts, ":")) != NULL) { 25474ef0018SQu Wenruo int token; 25574ef0018SQu Wenruo 25674ef0018SQu Wenruo if (!*p) 25774ef0018SQu Wenruo continue; 25874ef0018SQu Wenruo token = match_token(p, rescue_tokens, args); 25974ef0018SQu Wenruo switch (token){ 26074ef0018SQu Wenruo case Opt_usebackuproot: 26174ef0018SQu Wenruo btrfs_info(info, 26274ef0018SQu Wenruo "trying to use backup root at mount time"); 26374ef0018SQu Wenruo btrfs_set_opt(info->mount_opt, USEBACKUPROOT); 26474ef0018SQu Wenruo break; 26574ef0018SQu Wenruo case Opt_nologreplay: 26674ef0018SQu Wenruo btrfs_set_and_info(info, NOLOGREPLAY, 26774ef0018SQu Wenruo "disabling log replay at mount time"); 26874ef0018SQu Wenruo break; 26942437a63SJosef Bacik case Opt_ignorebadroots: 27042437a63SJosef Bacik btrfs_set_and_info(info, IGNOREBADROOTS, 27142437a63SJosef Bacik "ignoring bad roots"); 27242437a63SJosef Bacik break; 273882dbe0cSJosef Bacik case Opt_ignoredatacsums: 274882dbe0cSJosef Bacik btrfs_set_and_info(info, IGNOREDATACSUMS, 275882dbe0cSJosef Bacik "ignoring data csums"); 276882dbe0cSJosef Bacik break; 2779037d3cbSJosef Bacik case Opt_rescue_all: 2789037d3cbSJosef Bacik btrfs_info(info, "enabling all of the rescue options"); 2799037d3cbSJosef Bacik btrfs_set_and_info(info, IGNOREDATACSUMS, 2809037d3cbSJosef Bacik "ignoring data csums"); 2819037d3cbSJosef Bacik btrfs_set_and_info(info, IGNOREBADROOTS, 2829037d3cbSJosef Bacik "ignoring bad roots"); 2839037d3cbSJosef Bacik btrfs_set_and_info(info, NOLOGREPLAY, 2849037d3cbSJosef Bacik "disabling log replay at mount time"); 2859037d3cbSJosef Bacik break; 28674ef0018SQu Wenruo case Opt_err: 28774ef0018SQu Wenruo btrfs_info(info, "unrecognized rescue option '%s'", p); 28874ef0018SQu Wenruo ret = -EINVAL; 28974ef0018SQu Wenruo goto out; 29074ef0018SQu Wenruo default: 29174ef0018SQu Wenruo break; 29274ef0018SQu Wenruo } 29374ef0018SQu Wenruo 29474ef0018SQu Wenruo } 29574ef0018SQu Wenruo out: 29674ef0018SQu Wenruo kfree(orig); 29774ef0018SQu Wenruo return ret; 29874ef0018SQu Wenruo } 29974ef0018SQu Wenruo 300edf24abeSChristoph Hellwig /* 301edf24abeSChristoph Hellwig * Regular mount options parser. Everything that is needed only when 302edf24abeSChristoph Hellwig * reading in a new superblock is parsed here. 30349b25e05SJeff Mahoney * XXX JDM: This needs to be cleaned up for remount. 304edf24abeSChristoph Hellwig */ 3052ff7e61eSJeff Mahoney int btrfs_parse_options(struct btrfs_fs_info *info, char *options, 30696da0919SQu Wenruo unsigned long new_flags) 30795e05289SChris Mason { 30895e05289SChris Mason substring_t args[MAX_OPT_ARGS]; 309e215772cSMisono, Tomohiro char *p, *num; 3104543df7eSChris Mason int intarg; 311a7a3f7caSSage Weil int ret = 0; 312261507a0SLi Zefan char *compress_type; 313261507a0SLi Zefan bool compress_force = false; 314b7c47bbbSTsutomu Itoh enum btrfs_compression_type saved_compress_type; 31527942c99SDavid Sterba int saved_compress_level; 316b7c47bbbSTsutomu Itoh bool saved_compress_force; 317b7c47bbbSTsutomu Itoh int no_compress = 0; 318dbecac26SMaciej S. Szmigiero const bool remounting = test_bit(BTRFS_FS_STATE_REMOUNTING, &info->fs_state); 319b6cda9bcSChris Mason 3200b246afaSJeff Mahoney if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE)) 32170f6d82eSOmar Sandoval btrfs_set_opt(info->mount_opt, FREE_SPACE_TREE); 32294846229SBoris Burkov else if (btrfs_free_space_cache_v1_active(info)) { 3235d1ab66cSNaohiro Aota if (btrfs_is_zoned(info)) { 3245d1ab66cSNaohiro Aota btrfs_info(info, 3255d1ab66cSNaohiro Aota "zoned: clearing existing space cache"); 3265d1ab66cSNaohiro Aota btrfs_set_super_cache_generation(info->super_copy, 0); 3275d1ab66cSNaohiro Aota } else { 32873bc1876SJosef Bacik btrfs_set_opt(info->mount_opt, SPACE_CACHE); 3295d1ab66cSNaohiro Aota } 3305d1ab66cSNaohiro Aota } 33173bc1876SJosef Bacik 33296da0919SQu Wenruo /* 33396da0919SQu Wenruo * Even the options are empty, we still need to do extra check 33496da0919SQu Wenruo * against new flags 33596da0919SQu Wenruo */ 33695e05289SChris Mason if (!options) 33796da0919SQu Wenruo goto check; 33895e05289SChris Mason 33995e05289SChris Mason while ((p = strsep(&options, ",")) != NULL) { 34095e05289SChris Mason int token; 34195e05289SChris Mason if (!*p) 34295e05289SChris Mason continue; 34395e05289SChris Mason 34495e05289SChris Mason token = match_token(p, tokens, args); 34595e05289SChris Mason switch (token) { 346dfe25020SChris Mason case Opt_degraded: 3470b246afaSJeff Mahoney btrfs_info(info, "allowing degraded mounts"); 348dfe25020SChris Mason btrfs_set_opt(info->mount_opt, DEGRADED); 349dfe25020SChris Mason break; 35095e05289SChris Mason case Opt_subvol: 35137becec9SOmar Sandoval case Opt_subvol_empty: 35273f73415SJosef Bacik case Opt_subvolid: 35343e570b0SChristoph Hellwig case Opt_device: 354edf24abeSChristoph Hellwig /* 355fa59f27cSAnand Jain * These are parsed by btrfs_parse_subvol_options or 356fa59f27cSAnand Jain * btrfs_parse_device_options and can be ignored here. 357edf24abeSChristoph Hellwig */ 35895e05289SChris Mason break; 359b6cda9bcSChris Mason case Opt_nodatasum: 3603cdde224SJeff Mahoney btrfs_set_and_info(info, NODATASUM, 36107802534SQu Wenruo "setting nodatasum"); 362be20aa9dSChris Mason break; 363d399167dSQu Wenruo case Opt_datasum: 3643cdde224SJeff Mahoney if (btrfs_test_opt(info, NODATASUM)) { 3653cdde224SJeff Mahoney if (btrfs_test_opt(info, NODATACOW)) 3660b246afaSJeff Mahoney btrfs_info(info, 3675d163e0eSJeff Mahoney "setting datasum, datacow enabled"); 368d399167dSQu Wenruo else 3690b246afaSJeff Mahoney btrfs_info(info, "setting datasum"); 37007802534SQu Wenruo } 371d399167dSQu Wenruo btrfs_clear_opt(info->mount_opt, NODATACOW); 372d399167dSQu Wenruo btrfs_clear_opt(info->mount_opt, NODATASUM); 373d399167dSQu Wenruo break; 374be20aa9dSChris Mason case Opt_nodatacow: 3753cdde224SJeff Mahoney if (!btrfs_test_opt(info, NODATACOW)) { 3763cdde224SJeff Mahoney if (!btrfs_test_opt(info, COMPRESS) || 3773cdde224SJeff Mahoney !btrfs_test_opt(info, FORCE_COMPRESS)) { 3780b246afaSJeff Mahoney btrfs_info(info, 379efe120a0SFrank Holton "setting nodatacow, compression disabled"); 380bedb2ccaSAndrei Popa } else { 3810b246afaSJeff Mahoney btrfs_info(info, "setting nodatacow"); 382bedb2ccaSAndrei Popa } 38307802534SQu Wenruo } 384bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, COMPRESS); 385bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS); 386be20aa9dSChris Mason btrfs_set_opt(info->mount_opt, NODATACOW); 387be20aa9dSChris Mason btrfs_set_opt(info->mount_opt, NODATASUM); 388b6cda9bcSChris Mason break; 389a258af7aSQu Wenruo case Opt_datacow: 3903cdde224SJeff Mahoney btrfs_clear_and_info(info, NODATACOW, 39107802534SQu Wenruo "setting datacow"); 392a258af7aSQu Wenruo break; 393a555f810SChris Mason case Opt_compress_force: 394261507a0SLi Zefan case Opt_compress_force_type: 395261507a0SLi Zefan compress_force = true; 396c730ae0cSMarcos Paulo de Souza fallthrough; 397261507a0SLi Zefan case Opt_compress: 398261507a0SLi Zefan case Opt_compress_type: 3993cdde224SJeff Mahoney saved_compress_type = btrfs_test_opt(info, 4003cdde224SJeff Mahoney COMPRESS) ? 401b7c47bbbSTsutomu Itoh info->compress_type : BTRFS_COMPRESS_NONE; 402b7c47bbbSTsutomu Itoh saved_compress_force = 4033cdde224SJeff Mahoney btrfs_test_opt(info, FORCE_COMPRESS); 40427942c99SDavid Sterba saved_compress_level = info->compress_level; 405261507a0SLi Zefan if (token == Opt_compress || 406261507a0SLi Zefan token == Opt_compress_force || 407a7164fa4SDavid Sterba strncmp(args[0].from, "zlib", 4) == 0) { 408261507a0SLi Zefan compress_type = "zlib"; 409eae8d825SQu Wenruo 410261507a0SLi Zefan info->compress_type = BTRFS_COMPRESS_ZLIB; 411eae8d825SQu Wenruo info->compress_level = BTRFS_ZLIB_DEFAULT_LEVEL; 412eae8d825SQu Wenruo /* 413eae8d825SQu Wenruo * args[0] contains uninitialized data since 414eae8d825SQu Wenruo * for these tokens we don't expect any 415eae8d825SQu Wenruo * parameter. 416eae8d825SQu Wenruo */ 417eae8d825SQu Wenruo if (token != Opt_compress && 418eae8d825SQu Wenruo token != Opt_compress_force) 419f51d2b59SDavid Sterba info->compress_level = 420d0ab62ceSDennis Zhou btrfs_compress_str2level( 421d0ab62ceSDennis Zhou BTRFS_COMPRESS_ZLIB, 422d0ab62ceSDennis Zhou args[0].from + 4); 423063849eaSArnd Hannemann btrfs_set_opt(info->mount_opt, COMPRESS); 424bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, NODATACOW); 425bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, NODATASUM); 426b7c47bbbSTsutomu Itoh no_compress = 0; 427a7164fa4SDavid Sterba } else if (strncmp(args[0].from, "lzo", 3) == 0) { 428a6fa6faeSLi Zefan compress_type = "lzo"; 429a6fa6faeSLi Zefan info->compress_type = BTRFS_COMPRESS_LZO; 430282dd7d7SMarcos Paulo de Souza info->compress_level = 0; 431063849eaSArnd Hannemann btrfs_set_opt(info->mount_opt, COMPRESS); 432bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, NODATACOW); 433bedb2ccaSAndrei Popa btrfs_clear_opt(info->mount_opt, NODATASUM); 4342b0ce2c2SMitch Harder btrfs_set_fs_incompat(info, COMPRESS_LZO); 435b7c47bbbSTsutomu Itoh no_compress = 0; 4363f93aef5SDennis Zhou } else if (strncmp(args[0].from, "zstd", 4) == 0) { 4375c1aab1dSNick Terrell compress_type = "zstd"; 4385c1aab1dSNick Terrell info->compress_type = BTRFS_COMPRESS_ZSTD; 4393f93aef5SDennis Zhou info->compress_level = 4403f93aef5SDennis Zhou btrfs_compress_str2level( 4413f93aef5SDennis Zhou BTRFS_COMPRESS_ZSTD, 4423f93aef5SDennis Zhou args[0].from + 4); 4435c1aab1dSNick Terrell btrfs_set_opt(info->mount_opt, COMPRESS); 4445c1aab1dSNick Terrell btrfs_clear_opt(info->mount_opt, NODATACOW); 4455c1aab1dSNick Terrell btrfs_clear_opt(info->mount_opt, NODATASUM); 4465c1aab1dSNick Terrell btrfs_set_fs_incompat(info, COMPRESS_ZSTD); 4475c1aab1dSNick Terrell no_compress = 0; 448063849eaSArnd Hannemann } else if (strncmp(args[0].from, "no", 2) == 0) { 449063849eaSArnd Hannemann compress_type = "no"; 45027942c99SDavid Sterba info->compress_level = 0; 45127942c99SDavid Sterba info->compress_type = 0; 452063849eaSArnd Hannemann btrfs_clear_opt(info->mount_opt, COMPRESS); 453063849eaSArnd Hannemann btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS); 454063849eaSArnd Hannemann compress_force = false; 455b7c47bbbSTsutomu Itoh no_compress++; 456261507a0SLi Zefan } else { 457e3a4167cSDavid Sterba btrfs_err(info, "unrecognized compression value %s", 458e3a4167cSDavid Sterba args[0].from); 459261507a0SLi Zefan ret = -EINVAL; 460261507a0SLi Zefan goto out; 461261507a0SLi Zefan } 462261507a0SLi Zefan 463261507a0SLi Zefan if (compress_force) { 464b7c47bbbSTsutomu Itoh btrfs_set_opt(info->mount_opt, FORCE_COMPRESS); 465143f3636SDavid Sterba } else { 4664027e0f4SWang Shilong /* 4674027e0f4SWang Shilong * If we remount from compress-force=xxx to 4684027e0f4SWang Shilong * compress=xxx, we need clear FORCE_COMPRESS 4694027e0f4SWang Shilong * flag, otherwise, there is no way for users 4704027e0f4SWang Shilong * to disable forcible compression separately. 4714027e0f4SWang Shilong */ 4724027e0f4SWang Shilong btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS); 473a7e252afSMiao Xie } 47427942c99SDavid Sterba if (no_compress == 1) { 47527942c99SDavid Sterba btrfs_info(info, "use no compression"); 47627942c99SDavid Sterba } else if ((info->compress_type != saved_compress_type) || 47727942c99SDavid Sterba (compress_force != saved_compress_force) || 47827942c99SDavid Sterba (info->compress_level != saved_compress_level)) { 479f51d2b59SDavid Sterba btrfs_info(info, "%s %s compression, level %d", 480b7c47bbbSTsutomu Itoh (compress_force) ? "force" : "use", 481f51d2b59SDavid Sterba compress_type, info->compress_level); 482b7c47bbbSTsutomu Itoh } 483b7c47bbbSTsutomu Itoh compress_force = false; 484a555f810SChris Mason break; 485e18e4809SChris Mason case Opt_ssd: 4863cdde224SJeff Mahoney btrfs_set_and_info(info, SSD, 487583b7231SHans van Kranenburg "enabling ssd optimizations"); 488951e7966SAdam Borowski btrfs_clear_opt(info->mount_opt, NOSSD); 489e18e4809SChris Mason break; 490451d7585SChris Mason case Opt_ssd_spread: 491583b7231SHans van Kranenburg btrfs_set_and_info(info, SSD, 492583b7231SHans van Kranenburg "enabling ssd optimizations"); 4933cdde224SJeff Mahoney btrfs_set_and_info(info, SSD_SPREAD, 494583b7231SHans van Kranenburg "using spread ssd allocation scheme"); 495951e7966SAdam Borowski btrfs_clear_opt(info->mount_opt, NOSSD); 496451d7585SChris Mason break; 4973b30c22fSChris Mason case Opt_nossd: 498583b7231SHans van Kranenburg btrfs_set_opt(info->mount_opt, NOSSD); 499583b7231SHans van Kranenburg btrfs_clear_and_info(info, SSD, 500583b7231SHans van Kranenburg "not using ssd optimizations"); 501c730ae0cSMarcos Paulo de Souza fallthrough; 50262b8e077SHoward McLauchlan case Opt_nossd_spread: 503583b7231SHans van Kranenburg btrfs_clear_and_info(info, SSD_SPREAD, 504583b7231SHans van Kranenburg "not using spread ssd allocation scheme"); 5053b30c22fSChris Mason break; 506842bef58SQu Wenruo case Opt_barrier: 5073cdde224SJeff Mahoney btrfs_clear_and_info(info, NOBARRIER, 50807802534SQu Wenruo "turning on barriers"); 509842bef58SQu Wenruo break; 51021ad10cfSChris Mason case Opt_nobarrier: 5113cdde224SJeff Mahoney btrfs_set_and_info(info, NOBARRIER, 51207802534SQu Wenruo "turning off barriers"); 51321ad10cfSChris Mason break; 5144543df7eSChris Mason case Opt_thread_pool: 5152c334e87SWang Shilong ret = match_int(&args[0], &intarg); 5162c334e87SWang Shilong if (ret) { 517e3a4167cSDavid Sterba btrfs_err(info, "unrecognized thread_pool value %s", 518e3a4167cSDavid Sterba args[0].from); 5192c334e87SWang Shilong goto out; 520f7b885beSAnand Jain } else if (intarg == 0) { 521e3a4167cSDavid Sterba btrfs_err(info, "invalid value 0 for thread_pool"); 5222c334e87SWang Shilong ret = -EINVAL; 5232c334e87SWang Shilong goto out; 5242c334e87SWang Shilong } 525f7b885beSAnand Jain info->thread_pool_size = intarg; 5264543df7eSChris Mason break; 5276f568d35SChris Mason case Opt_max_inline: 528edf24abeSChristoph Hellwig num = match_strdup(&args[0]); 5296f568d35SChris Mason if (num) { 53091748467SAkinobu Mita info->max_inline = memparse(num, NULL); 5316f568d35SChris Mason kfree(num); 5326f568d35SChris Mason 53315ada040SChris Mason if (info->max_inline) { 534feb5f965SMitch Harder info->max_inline = min_t(u64, 53515ada040SChris Mason info->max_inline, 5360b246afaSJeff Mahoney info->sectorsize); 53715ada040SChris Mason } 5380b246afaSJeff Mahoney btrfs_info(info, "max_inline at %llu", 539c1c9ff7cSGeert Uytterhoeven info->max_inline); 5402c334e87SWang Shilong } else { 5412c334e87SWang Shilong ret = -ENOMEM; 5422c334e87SWang Shilong goto out; 5436f568d35SChris Mason } 5446f568d35SChris Mason break; 545bd0330adSQu Wenruo case Opt_acl: 54645ff35d6SGuangliang Zhao #ifdef CONFIG_BTRFS_FS_POSIX_ACL 5471751e8a6SLinus Torvalds info->sb->s_flags |= SB_POSIXACL; 548bd0330adSQu Wenruo break; 54945ff35d6SGuangliang Zhao #else 5500b246afaSJeff Mahoney btrfs_err(info, "support for ACL not compiled in!"); 55145ff35d6SGuangliang Zhao ret = -EINVAL; 55245ff35d6SGuangliang Zhao goto out; 55345ff35d6SGuangliang Zhao #endif 55433268eafSJosef Bacik case Opt_noacl: 5551751e8a6SLinus Torvalds info->sb->s_flags &= ~SB_POSIXACL; 55633268eafSJosef Bacik break; 5573a5e1404SSage Weil case Opt_notreelog: 5583cdde224SJeff Mahoney btrfs_set_and_info(info, NOTREELOG, 55907802534SQu Wenruo "disabling tree log"); 5603a5e1404SSage Weil break; 561a88998f2SQu Wenruo case Opt_treelog: 5623cdde224SJeff Mahoney btrfs_clear_and_info(info, NOTREELOG, 56307802534SQu Wenruo "enabling tree log"); 564a88998f2SQu Wenruo break; 565fed8f166SQu Wenruo case Opt_norecovery: 56696da0919SQu Wenruo case Opt_nologreplay: 56774ef0018SQu Wenruo btrfs_warn(info, 56874ef0018SQu Wenruo "'nologreplay' is deprecated, use 'rescue=nologreplay' instead"); 5693cdde224SJeff Mahoney btrfs_set_and_info(info, NOLOGREPLAY, 57096da0919SQu Wenruo "disabling log replay at mount time"); 57196da0919SQu Wenruo break; 572dccae999SSage Weil case Opt_flushoncommit: 5733cdde224SJeff Mahoney btrfs_set_and_info(info, FLUSHONCOMMIT, 57407802534SQu Wenruo "turning on flush-on-commit"); 575dccae999SSage Weil break; 5762c9ee856SQu Wenruo case Opt_noflushoncommit: 5773cdde224SJeff Mahoney btrfs_clear_and_info(info, FLUSHONCOMMIT, 57807802534SQu Wenruo "turning off flush-on-commit"); 5792c9ee856SQu Wenruo break; 58097e728d4SJosef Bacik case Opt_ratio: 5812c334e87SWang Shilong ret = match_int(&args[0], &intarg); 582e3a4167cSDavid Sterba if (ret) { 583e3a4167cSDavid Sterba btrfs_err(info, "unrecognized metadata_ratio value %s", 584e3a4167cSDavid Sterba args[0].from); 5852c334e87SWang Shilong goto out; 586e3a4167cSDavid Sterba } 58797e728d4SJosef Bacik info->metadata_ratio = intarg; 588764cb8b4SAnand Jain btrfs_info(info, "metadata ratio %u", 58997e728d4SJosef Bacik info->metadata_ratio); 59097e728d4SJosef Bacik break; 591e244a0aeSChristoph Hellwig case Opt_discard: 592b0643e59SDennis Zhou case Opt_discard_mode: 593b0643e59SDennis Zhou if (token == Opt_discard || 594b0643e59SDennis Zhou strcmp(args[0].from, "sync") == 0) { 595b0643e59SDennis Zhou btrfs_clear_opt(info->mount_opt, DISCARD_ASYNC); 59646b27f50SDennis Zhou btrfs_set_and_info(info, DISCARD_SYNC, 59746b27f50SDennis Zhou "turning on sync discard"); 598b0643e59SDennis Zhou } else if (strcmp(args[0].from, "async") == 0) { 599b0643e59SDennis Zhou btrfs_clear_opt(info->mount_opt, DISCARD_SYNC); 600b0643e59SDennis Zhou btrfs_set_and_info(info, DISCARD_ASYNC, 601b0643e59SDennis Zhou "turning on async discard"); 602b0643e59SDennis Zhou } else { 603e3a4167cSDavid Sterba btrfs_err(info, "unrecognized discard mode value %s", 604e3a4167cSDavid Sterba args[0].from); 605b0643e59SDennis Zhou ret = -EINVAL; 606b0643e59SDennis Zhou goto out; 607b0643e59SDennis Zhou } 60863a7cb13SDavid Sterba btrfs_clear_opt(info->mount_opt, NODISCARD); 609e244a0aeSChristoph Hellwig break; 610e07a2adeSQu Wenruo case Opt_nodiscard: 61146b27f50SDennis Zhou btrfs_clear_and_info(info, DISCARD_SYNC, 61207802534SQu Wenruo "turning off discard"); 613b0643e59SDennis Zhou btrfs_clear_and_info(info, DISCARD_ASYNC, 614b0643e59SDennis Zhou "turning off async discard"); 61563a7cb13SDavid Sterba btrfs_set_opt(info->mount_opt, NODISCARD); 616e07a2adeSQu Wenruo break; 6170af3d00bSJosef Bacik case Opt_space_cache: 61870f6d82eSOmar Sandoval case Opt_space_cache_version: 61963cd070dSJosef Bacik /* 62063cd070dSJosef Bacik * We already set FREE_SPACE_TREE above because we have 62163cd070dSJosef Bacik * compat_ro(FREE_SPACE_TREE) set, and we aren't going 62263cd070dSJosef Bacik * to allow v1 to be set for extent tree v2, simply 62363cd070dSJosef Bacik * ignore this setting if we're extent tree v2. 62463cd070dSJosef Bacik */ 62563cd070dSJosef Bacik if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) 62663cd070dSJosef Bacik break; 62770f6d82eSOmar Sandoval if (token == Opt_space_cache || 62870f6d82eSOmar Sandoval strcmp(args[0].from, "v1") == 0) { 6290b246afaSJeff Mahoney btrfs_clear_opt(info->mount_opt, 63070f6d82eSOmar Sandoval FREE_SPACE_TREE); 6313cdde224SJeff Mahoney btrfs_set_and_info(info, SPACE_CACHE, 63207802534SQu Wenruo "enabling disk space caching"); 63370f6d82eSOmar Sandoval } else if (strcmp(args[0].from, "v2") == 0) { 6340b246afaSJeff Mahoney btrfs_clear_opt(info->mount_opt, 63570f6d82eSOmar Sandoval SPACE_CACHE); 6360b246afaSJeff Mahoney btrfs_set_and_info(info, FREE_SPACE_TREE, 63770f6d82eSOmar Sandoval "enabling free space tree"); 63870f6d82eSOmar Sandoval } else { 639e3a4167cSDavid Sterba btrfs_err(info, "unrecognized space_cache value %s", 640e3a4167cSDavid Sterba args[0].from); 64170f6d82eSOmar Sandoval ret = -EINVAL; 64270f6d82eSOmar Sandoval goto out; 64370f6d82eSOmar Sandoval } 6440de90876SJosef Bacik break; 645f420ee1eSStefan Behrens case Opt_rescan_uuid_tree: 646f420ee1eSStefan Behrens btrfs_set_opt(info->mount_opt, RESCAN_UUID_TREE); 647f420ee1eSStefan Behrens break; 64873bc1876SJosef Bacik case Opt_no_space_cache: 64963cd070dSJosef Bacik /* 65063cd070dSJosef Bacik * We cannot operate without the free space tree with 65163cd070dSJosef Bacik * extent tree v2, ignore this option. 65263cd070dSJosef Bacik */ 65363cd070dSJosef Bacik if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) 65463cd070dSJosef Bacik break; 6553cdde224SJeff Mahoney if (btrfs_test_opt(info, SPACE_CACHE)) { 6560b246afaSJeff Mahoney btrfs_clear_and_info(info, SPACE_CACHE, 65707802534SQu Wenruo "disabling disk space caching"); 65870f6d82eSOmar Sandoval } 6593cdde224SJeff Mahoney if (btrfs_test_opt(info, FREE_SPACE_TREE)) { 6600b246afaSJeff Mahoney btrfs_clear_and_info(info, FREE_SPACE_TREE, 66170f6d82eSOmar Sandoval "disabling free space tree"); 66270f6d82eSOmar Sandoval } 66373bc1876SJosef Bacik break; 6644b9465cbSChris Mason case Opt_inode_cache: 6653818aea2SQu Wenruo case Opt_noinode_cache: 6665297199aSNikolay Borisov btrfs_warn(info, 6675297199aSNikolay Borisov "the 'inode_cache' option is deprecated and has no effect since 5.11"); 6684b9465cbSChris Mason break; 66988c2ba3bSJosef Bacik case Opt_clear_cache: 67063cd070dSJosef Bacik /* 67163cd070dSJosef Bacik * We cannot clear the free space tree with extent tree 67263cd070dSJosef Bacik * v2, ignore this option. 67363cd070dSJosef Bacik */ 67463cd070dSJosef Bacik if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) 67563cd070dSJosef Bacik break; 6763cdde224SJeff Mahoney btrfs_set_and_info(info, CLEAR_CACHE, 67707802534SQu Wenruo "force clearing of disk cache"); 6780af3d00bSJosef Bacik break; 6794260f7c7SSage Weil case Opt_user_subvol_rm_allowed: 6804260f7c7SSage Weil btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED); 6814260f7c7SSage Weil break; 68291435650SChris Mason case Opt_enospc_debug: 68391435650SChris Mason btrfs_set_opt(info->mount_opt, ENOSPC_DEBUG); 68491435650SChris Mason break; 68553036293SQu Wenruo case Opt_noenospc_debug: 68653036293SQu Wenruo btrfs_clear_opt(info->mount_opt, ENOSPC_DEBUG); 68753036293SQu Wenruo break; 6884cb5300bSChris Mason case Opt_defrag: 6893cdde224SJeff Mahoney btrfs_set_and_info(info, AUTO_DEFRAG, 69007802534SQu Wenruo "enabling auto defrag"); 6914cb5300bSChris Mason break; 692fc0ca9afSQu Wenruo case Opt_nodefrag: 6933cdde224SJeff Mahoney btrfs_clear_and_info(info, AUTO_DEFRAG, 69407802534SQu Wenruo "disabling auto defrag"); 695fc0ca9afSQu Wenruo break; 696af31f5e5SChris Mason case Opt_recovery: 6978dcddfa0SQu Wenruo case Opt_usebackuproot: 69874ef0018SQu Wenruo btrfs_warn(info, 69974ef0018SQu Wenruo "'%s' is deprecated, use 'rescue=usebackuproot' instead", 70074ef0018SQu Wenruo token == Opt_recovery ? "recovery" : 70174ef0018SQu Wenruo "usebackuproot"); 7020b246afaSJeff Mahoney btrfs_info(info, 7038dcddfa0SQu Wenruo "trying to use backup root at mount time"); 7048dcddfa0SQu Wenruo btrfs_set_opt(info->mount_opt, USEBACKUPROOT); 705af31f5e5SChris Mason break; 7069555c6c1SIlya Dryomov case Opt_skip_balance: 7079555c6c1SIlya Dryomov btrfs_set_opt(info->mount_opt, SKIP_BALANCE); 7089555c6c1SIlya Dryomov break; 70921adbd5cSStefan Behrens #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY 71021adbd5cSStefan Behrens case Opt_check_integrity_including_extent_data: 7110b246afaSJeff Mahoney btrfs_info(info, 712efe120a0SFrank Holton "enabling check integrity including extent data"); 713cbeaae4fSDavid Sterba btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY_DATA); 71421adbd5cSStefan Behrens btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY); 71521adbd5cSStefan Behrens break; 71621adbd5cSStefan Behrens case Opt_check_integrity: 7170b246afaSJeff Mahoney btrfs_info(info, "enabling check integrity"); 71821adbd5cSStefan Behrens btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY); 71921adbd5cSStefan Behrens break; 72021adbd5cSStefan Behrens case Opt_check_integrity_print_mask: 7212c334e87SWang Shilong ret = match_int(&args[0], &intarg); 722e3a4167cSDavid Sterba if (ret) { 723e3a4167cSDavid Sterba btrfs_err(info, 724e3a4167cSDavid Sterba "unrecognized check_integrity_print_mask value %s", 725e3a4167cSDavid Sterba args[0].from); 7262c334e87SWang Shilong goto out; 727e3a4167cSDavid Sterba } 72821adbd5cSStefan Behrens info->check_integrity_print_mask = intarg; 72902453bdeSAnand Jain btrfs_info(info, "check_integrity_print_mask 0x%x", 73021adbd5cSStefan Behrens info->check_integrity_print_mask); 73121adbd5cSStefan Behrens break; 73221adbd5cSStefan Behrens #else 73321adbd5cSStefan Behrens case Opt_check_integrity_including_extent_data: 73421adbd5cSStefan Behrens case Opt_check_integrity: 73521adbd5cSStefan Behrens case Opt_check_integrity_print_mask: 7360b246afaSJeff Mahoney btrfs_err(info, 737efe120a0SFrank Holton "support for check_integrity* not compiled in!"); 73821adbd5cSStefan Behrens ret = -EINVAL; 73921adbd5cSStefan Behrens goto out; 74021adbd5cSStefan Behrens #endif 7418c342930SJeff Mahoney case Opt_fatal_errors: 742e3a4167cSDavid Sterba if (strcmp(args[0].from, "panic") == 0) { 7438c342930SJeff Mahoney btrfs_set_opt(info->mount_opt, 7448c342930SJeff Mahoney PANIC_ON_FATAL_ERROR); 745e3a4167cSDavid Sterba } else if (strcmp(args[0].from, "bug") == 0) { 7468c342930SJeff Mahoney btrfs_clear_opt(info->mount_opt, 7478c342930SJeff Mahoney PANIC_ON_FATAL_ERROR); 748e3a4167cSDavid Sterba } else { 749e3a4167cSDavid Sterba btrfs_err(info, "unrecognized fatal_errors value %s", 750e3a4167cSDavid Sterba args[0].from); 7518c342930SJeff Mahoney ret = -EINVAL; 7528c342930SJeff Mahoney goto out; 7538c342930SJeff Mahoney } 7548c342930SJeff Mahoney break; 7558b87dc17SDavid Sterba case Opt_commit_interval: 7568b87dc17SDavid Sterba intarg = 0; 7578b87dc17SDavid Sterba ret = match_int(&args[0], &intarg); 758e3a4167cSDavid Sterba if (ret) { 759e3a4167cSDavid Sterba btrfs_err(info, "unrecognized commit_interval value %s", 760e3a4167cSDavid Sterba args[0].from); 761e3a4167cSDavid Sterba ret = -EINVAL; 7628b87dc17SDavid Sterba goto out; 763e3a4167cSDavid Sterba } 764d3740608SAnand Jain if (intarg == 0) { 765d3740608SAnand Jain btrfs_info(info, 766d3740608SAnand Jain "using default commit interval %us", 767d3740608SAnand Jain BTRFS_DEFAULT_COMMIT_INTERVAL); 768d3740608SAnand Jain intarg = BTRFS_DEFAULT_COMMIT_INTERVAL; 769d3740608SAnand Jain } else if (intarg > 300) { 770d3740608SAnand Jain btrfs_warn(info, "excessive commit interval %d", 7718b87dc17SDavid Sterba intarg); 7728b87dc17SDavid Sterba } 7738b87dc17SDavid Sterba info->commit_interval = intarg; 7748b87dc17SDavid Sterba break; 77574ef0018SQu Wenruo case Opt_rescue: 77674ef0018SQu Wenruo ret = parse_rescue_options(info, args[0].from); 777e3a4167cSDavid Sterba if (ret < 0) { 778e3a4167cSDavid Sterba btrfs_err(info, "unrecognized rescue value %s", 779e3a4167cSDavid Sterba args[0].from); 78074ef0018SQu Wenruo goto out; 781e3a4167cSDavid Sterba } 78274ef0018SQu Wenruo break; 783d0bd4560SJosef Bacik #ifdef CONFIG_BTRFS_DEBUG 784d0bd4560SJosef Bacik case Opt_fragment_all: 7850b246afaSJeff Mahoney btrfs_info(info, "fragmenting all space"); 786d0bd4560SJosef Bacik btrfs_set_opt(info->mount_opt, FRAGMENT_DATA); 787d0bd4560SJosef Bacik btrfs_set_opt(info->mount_opt, FRAGMENT_METADATA); 788d0bd4560SJosef Bacik break; 789d0bd4560SJosef Bacik case Opt_fragment_metadata: 7900b246afaSJeff Mahoney btrfs_info(info, "fragmenting metadata"); 791d0bd4560SJosef Bacik btrfs_set_opt(info->mount_opt, 792d0bd4560SJosef Bacik FRAGMENT_METADATA); 793d0bd4560SJosef Bacik break; 794d0bd4560SJosef Bacik case Opt_fragment_data: 7950b246afaSJeff Mahoney btrfs_info(info, "fragmenting data"); 796d0bd4560SJosef Bacik btrfs_set_opt(info->mount_opt, FRAGMENT_DATA); 797d0bd4560SJosef Bacik break; 798d0bd4560SJosef Bacik #endif 799fb592373SJosef Bacik #ifdef CONFIG_BTRFS_FS_REF_VERIFY 800fb592373SJosef Bacik case Opt_ref_verify: 801fb592373SJosef Bacik btrfs_info(info, "doing ref verification"); 802fb592373SJosef Bacik btrfs_set_opt(info->mount_opt, REF_VERIFY); 803fb592373SJosef Bacik break; 804fb592373SJosef Bacik #endif 805a7a3f7caSSage Weil case Opt_err: 8067e8f19e5SDavid Sterba btrfs_err(info, "unrecognized mount option '%s'", p); 807a7a3f7caSSage Weil ret = -EINVAL; 808a7a3f7caSSage Weil goto out; 80995e05289SChris Mason default: 810be20aa9dSChris Mason break; 81195e05289SChris Mason } 81295e05289SChris Mason } 81396da0919SQu Wenruo check: 814d70bf748SJosef Bacik /* We're read-only, don't have to check. */ 815d70bf748SJosef Bacik if (new_flags & SB_RDONLY) 816d70bf748SJosef Bacik goto out; 817d70bf748SJosef Bacik 81842437a63SJosef Bacik if (check_ro_option(info, BTRFS_MOUNT_NOLOGREPLAY, "nologreplay") || 819882dbe0cSJosef Bacik check_ro_option(info, BTRFS_MOUNT_IGNOREBADROOTS, "ignorebadroots") || 820882dbe0cSJosef Bacik check_ro_option(info, BTRFS_MOUNT_IGNOREDATACSUMS, "ignoredatacsums")) 82196da0919SQu Wenruo ret = -EINVAL; 822a7a3f7caSSage Weil out: 8230b246afaSJeff Mahoney if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE) && 8243cdde224SJeff Mahoney !btrfs_test_opt(info, FREE_SPACE_TREE) && 8253cdde224SJeff Mahoney !btrfs_test_opt(info, CLEAR_CACHE)) { 8260b246afaSJeff Mahoney btrfs_err(info, "cannot disable free space tree"); 82770f6d82eSOmar Sandoval ret = -EINVAL; 82870f6d82eSOmar Sandoval 82970f6d82eSOmar Sandoval } 8305d1ab66cSNaohiro Aota if (!ret) 8315d1ab66cSNaohiro Aota ret = btrfs_check_mountopts_zoned(info); 832dbecac26SMaciej S. Szmigiero if (!ret && !remounting) { 833dbecac26SMaciej S. Szmigiero if (btrfs_test_opt(info, SPACE_CACHE)) 8340b246afaSJeff Mahoney btrfs_info(info, "disk space caching is enabled"); 835dbecac26SMaciej S. Szmigiero if (btrfs_test_opt(info, FREE_SPACE_TREE)) 8360b246afaSJeff Mahoney btrfs_info(info, "using free space tree"); 837dbecac26SMaciej S. Szmigiero } 838a7a3f7caSSage Weil return ret; 839edf24abeSChristoph Hellwig } 840edf24abeSChristoph Hellwig 841edf24abeSChristoph Hellwig /* 842edf24abeSChristoph Hellwig * Parse mount options that are required early in the mount process. 843edf24abeSChristoph Hellwig * 844edf24abeSChristoph Hellwig * All other options will be parsed on much later in the mount process and 845edf24abeSChristoph Hellwig * only when we need to allocate a new super block. 846edf24abeSChristoph Hellwig */ 847fa59f27cSAnand Jain static int btrfs_parse_device_options(const char *options, fmode_t flags, 848d64dcbd1SGu Jinxiang void *holder) 849edf24abeSChristoph Hellwig { 850edf24abeSChristoph Hellwig substring_t args[MAX_OPT_ARGS]; 85183c8c9bdSJeff Liu char *device_name, *opts, *orig, *p; 85236350e95SGu Jinxiang struct btrfs_device *device = NULL; 853d7407606SMisono, Tomohiro int error = 0; 854d7407606SMisono, Tomohiro 8555139cff5SDavid Sterba lockdep_assert_held(&uuid_mutex); 8565139cff5SDavid Sterba 857d7407606SMisono, Tomohiro if (!options) 858d7407606SMisono, Tomohiro return 0; 859d7407606SMisono, Tomohiro 860d7407606SMisono, Tomohiro /* 861d7407606SMisono, Tomohiro * strsep changes the string, duplicate it because btrfs_parse_options 862d7407606SMisono, Tomohiro * gets called later 863d7407606SMisono, Tomohiro */ 864d7407606SMisono, Tomohiro opts = kstrdup(options, GFP_KERNEL); 865d7407606SMisono, Tomohiro if (!opts) 866d7407606SMisono, Tomohiro return -ENOMEM; 867d7407606SMisono, Tomohiro orig = opts; 868d7407606SMisono, Tomohiro 869d7407606SMisono, Tomohiro while ((p = strsep(&opts, ",")) != NULL) { 870d7407606SMisono, Tomohiro int token; 871d7407606SMisono, Tomohiro 872d7407606SMisono, Tomohiro if (!*p) 873d7407606SMisono, Tomohiro continue; 874d7407606SMisono, Tomohiro 875d7407606SMisono, Tomohiro token = match_token(p, tokens, args); 876d7407606SMisono, Tomohiro if (token == Opt_device) { 877d7407606SMisono, Tomohiro device_name = match_strdup(&args[0]); 878d7407606SMisono, Tomohiro if (!device_name) { 879d7407606SMisono, Tomohiro error = -ENOMEM; 880d7407606SMisono, Tomohiro goto out; 881d7407606SMisono, Tomohiro } 88236350e95SGu Jinxiang device = btrfs_scan_one_device(device_name, flags, 88336350e95SGu Jinxiang holder); 884d7407606SMisono, Tomohiro kfree(device_name); 88536350e95SGu Jinxiang if (IS_ERR(device)) { 88636350e95SGu Jinxiang error = PTR_ERR(device); 887d7407606SMisono, Tomohiro goto out; 888d7407606SMisono, Tomohiro } 889d7407606SMisono, Tomohiro } 89036350e95SGu Jinxiang } 891d7407606SMisono, Tomohiro 892d7407606SMisono, Tomohiro out: 893d7407606SMisono, Tomohiro kfree(orig); 894d7407606SMisono, Tomohiro return error; 895d7407606SMisono, Tomohiro } 896d7407606SMisono, Tomohiro 897d7407606SMisono, Tomohiro /* 898d7407606SMisono, Tomohiro * Parse mount options that are related to subvolume id 899d7407606SMisono, Tomohiro * 900d7407606SMisono, Tomohiro * The value is later passed to mount_subvol() 901d7407606SMisono, Tomohiro */ 90293b9bcdfSGu Jinxiang static int btrfs_parse_subvol_options(const char *options, char **subvol_name, 90393b9bcdfSGu Jinxiang u64 *subvol_objectid) 904d7407606SMisono, Tomohiro { 905d7407606SMisono, Tomohiro substring_t args[MAX_OPT_ARGS]; 906d7407606SMisono, Tomohiro char *opts, *orig, *p; 907edf24abeSChristoph Hellwig int error = 0; 908ccb0e7d1SAnand Jain u64 subvolid; 909edf24abeSChristoph Hellwig 910edf24abeSChristoph Hellwig if (!options) 911830c4adbSJosef Bacik return 0; 912edf24abeSChristoph Hellwig 913edf24abeSChristoph Hellwig /* 914d7407606SMisono, Tomohiro * strsep changes the string, duplicate it because 915fa59f27cSAnand Jain * btrfs_parse_device_options gets called later 916edf24abeSChristoph Hellwig */ 917edf24abeSChristoph Hellwig opts = kstrdup(options, GFP_KERNEL); 918edf24abeSChristoph Hellwig if (!opts) 919edf24abeSChristoph Hellwig return -ENOMEM; 9203f3d0bc0STero Roponen orig = opts; 921edf24abeSChristoph Hellwig 922edf24abeSChristoph Hellwig while ((p = strsep(&opts, ",")) != NULL) { 923edf24abeSChristoph Hellwig int token; 924edf24abeSChristoph Hellwig if (!*p) 925edf24abeSChristoph Hellwig continue; 926edf24abeSChristoph Hellwig 927edf24abeSChristoph Hellwig token = match_token(p, tokens, args); 928edf24abeSChristoph Hellwig switch (token) { 929edf24abeSChristoph Hellwig case Opt_subvol: 930a90e8b6fSIlya Dryomov kfree(*subvol_name); 931edf24abeSChristoph Hellwig *subvol_name = match_strdup(&args[0]); 9322c334e87SWang Shilong if (!*subvol_name) { 9332c334e87SWang Shilong error = -ENOMEM; 9342c334e87SWang Shilong goto out; 9352c334e87SWang Shilong } 936edf24abeSChristoph Hellwig break; 93773f73415SJosef Bacik case Opt_subvolid: 938ccb0e7d1SAnand Jain error = match_u64(&args[0], &subvolid); 939ccb0e7d1SAnand Jain if (error) 9402c334e87SWang Shilong goto out; 941ccb0e7d1SAnand Jain 942ccb0e7d1SAnand Jain /* we want the original fs_tree */ 943ccb0e7d1SAnand Jain if (subvolid == 0) 944ccb0e7d1SAnand Jain subvolid = BTRFS_FS_TREE_OBJECTID; 945ccb0e7d1SAnand Jain 946ccb0e7d1SAnand Jain *subvol_objectid = subvolid; 94773f73415SJosef Bacik break; 948edf24abeSChristoph Hellwig default: 949edf24abeSChristoph Hellwig break; 950edf24abeSChristoph Hellwig } 951edf24abeSChristoph Hellwig } 952edf24abeSChristoph Hellwig 953edf24abeSChristoph Hellwig out: 954830c4adbSJosef Bacik kfree(orig); 955edf24abeSChristoph Hellwig return error; 95695e05289SChris Mason } 95795e05289SChris Mason 958c0c907a4SMarcos Paulo de Souza char *btrfs_get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info, 95973f73415SJosef Bacik u64 subvol_objectid) 96073f73415SJosef Bacik { 961815745cfSAl Viro struct btrfs_root *root = fs_info->tree_root; 9625168489aSJosef Bacik struct btrfs_root *fs_root = NULL; 96305dbe683SOmar Sandoval struct btrfs_root_ref *root_ref; 96405dbe683SOmar Sandoval struct btrfs_inode_ref *inode_ref; 96505dbe683SOmar Sandoval struct btrfs_key key; 96605dbe683SOmar Sandoval struct btrfs_path *path = NULL; 96705dbe683SOmar Sandoval char *name = NULL, *ptr; 96805dbe683SOmar Sandoval u64 dirid; 96905dbe683SOmar Sandoval int len; 97005dbe683SOmar Sandoval int ret; 97105dbe683SOmar Sandoval 97205dbe683SOmar Sandoval path = btrfs_alloc_path(); 97305dbe683SOmar Sandoval if (!path) { 97405dbe683SOmar Sandoval ret = -ENOMEM; 97505dbe683SOmar Sandoval goto err; 97605dbe683SOmar Sandoval } 97705dbe683SOmar Sandoval 9783ec83621SDavid Sterba name = kmalloc(PATH_MAX, GFP_KERNEL); 97905dbe683SOmar Sandoval if (!name) { 98005dbe683SOmar Sandoval ret = -ENOMEM; 98105dbe683SOmar Sandoval goto err; 98205dbe683SOmar Sandoval } 98305dbe683SOmar Sandoval ptr = name + PATH_MAX - 1; 98405dbe683SOmar Sandoval ptr[0] = '\0'; 98505dbe683SOmar Sandoval 98605dbe683SOmar Sandoval /* 98705dbe683SOmar Sandoval * Walk up the subvolume trees in the tree of tree roots by root 98805dbe683SOmar Sandoval * backrefs until we hit the top-level subvolume. 98905dbe683SOmar Sandoval */ 99005dbe683SOmar Sandoval while (subvol_objectid != BTRFS_FS_TREE_OBJECTID) { 99105dbe683SOmar Sandoval key.objectid = subvol_objectid; 99205dbe683SOmar Sandoval key.type = BTRFS_ROOT_BACKREF_KEY; 99305dbe683SOmar Sandoval key.offset = (u64)-1; 99405dbe683SOmar Sandoval 9950ff40a91SMarcos Paulo de Souza ret = btrfs_search_backwards(root, &key, path); 99605dbe683SOmar Sandoval if (ret < 0) { 99705dbe683SOmar Sandoval goto err; 99805dbe683SOmar Sandoval } else if (ret > 0) { 99905dbe683SOmar Sandoval ret = -ENOENT; 100005dbe683SOmar Sandoval goto err; 100105dbe683SOmar Sandoval } 100205dbe683SOmar Sandoval 100305dbe683SOmar Sandoval subvol_objectid = key.offset; 100405dbe683SOmar Sandoval 100505dbe683SOmar Sandoval root_ref = btrfs_item_ptr(path->nodes[0], path->slots[0], 100605dbe683SOmar Sandoval struct btrfs_root_ref); 100705dbe683SOmar Sandoval len = btrfs_root_ref_name_len(path->nodes[0], root_ref); 100805dbe683SOmar Sandoval ptr -= len + 1; 100905dbe683SOmar Sandoval if (ptr < name) { 101005dbe683SOmar Sandoval ret = -ENAMETOOLONG; 101105dbe683SOmar Sandoval goto err; 101205dbe683SOmar Sandoval } 101305dbe683SOmar Sandoval read_extent_buffer(path->nodes[0], ptr + 1, 101405dbe683SOmar Sandoval (unsigned long)(root_ref + 1), len); 101505dbe683SOmar Sandoval ptr[0] = '/'; 101605dbe683SOmar Sandoval dirid = btrfs_root_ref_dirid(path->nodes[0], root_ref); 101705dbe683SOmar Sandoval btrfs_release_path(path); 101805dbe683SOmar Sandoval 101956e9357aSDavid Sterba fs_root = btrfs_get_fs_root(fs_info, subvol_objectid, true); 102005dbe683SOmar Sandoval if (IS_ERR(fs_root)) { 102105dbe683SOmar Sandoval ret = PTR_ERR(fs_root); 10225168489aSJosef Bacik fs_root = NULL; 10235168489aSJosef Bacik goto err; 10245168489aSJosef Bacik } 102505dbe683SOmar Sandoval 102605dbe683SOmar Sandoval /* 102705dbe683SOmar Sandoval * Walk up the filesystem tree by inode refs until we hit the 102805dbe683SOmar Sandoval * root directory. 102905dbe683SOmar Sandoval */ 103005dbe683SOmar Sandoval while (dirid != BTRFS_FIRST_FREE_OBJECTID) { 103105dbe683SOmar Sandoval key.objectid = dirid; 103205dbe683SOmar Sandoval key.type = BTRFS_INODE_REF_KEY; 103305dbe683SOmar Sandoval key.offset = (u64)-1; 103405dbe683SOmar Sandoval 10350ff40a91SMarcos Paulo de Souza ret = btrfs_search_backwards(fs_root, &key, path); 103605dbe683SOmar Sandoval if (ret < 0) { 103705dbe683SOmar Sandoval goto err; 103805dbe683SOmar Sandoval } else if (ret > 0) { 103905dbe683SOmar Sandoval ret = -ENOENT; 104005dbe683SOmar Sandoval goto err; 104105dbe683SOmar Sandoval } 104205dbe683SOmar Sandoval 104305dbe683SOmar Sandoval dirid = key.offset; 104405dbe683SOmar Sandoval 104505dbe683SOmar Sandoval inode_ref = btrfs_item_ptr(path->nodes[0], 104605dbe683SOmar Sandoval path->slots[0], 104705dbe683SOmar Sandoval struct btrfs_inode_ref); 104805dbe683SOmar Sandoval len = btrfs_inode_ref_name_len(path->nodes[0], 104905dbe683SOmar Sandoval inode_ref); 105005dbe683SOmar Sandoval ptr -= len + 1; 105105dbe683SOmar Sandoval if (ptr < name) { 105205dbe683SOmar Sandoval ret = -ENAMETOOLONG; 105305dbe683SOmar Sandoval goto err; 105405dbe683SOmar Sandoval } 105505dbe683SOmar Sandoval read_extent_buffer(path->nodes[0], ptr + 1, 105605dbe683SOmar Sandoval (unsigned long)(inode_ref + 1), len); 105705dbe683SOmar Sandoval ptr[0] = '/'; 105805dbe683SOmar Sandoval btrfs_release_path(path); 105905dbe683SOmar Sandoval } 106000246528SJosef Bacik btrfs_put_root(fs_root); 10615168489aSJosef Bacik fs_root = NULL; 106205dbe683SOmar Sandoval } 106305dbe683SOmar Sandoval 106405dbe683SOmar Sandoval btrfs_free_path(path); 106505dbe683SOmar Sandoval if (ptr == name + PATH_MAX - 1) { 106605dbe683SOmar Sandoval name[0] = '/'; 106705dbe683SOmar Sandoval name[1] = '\0'; 106805dbe683SOmar Sandoval } else { 106905dbe683SOmar Sandoval memmove(name, ptr, name + PATH_MAX - ptr); 107005dbe683SOmar Sandoval } 107105dbe683SOmar Sandoval return name; 107205dbe683SOmar Sandoval 107305dbe683SOmar Sandoval err: 107400246528SJosef Bacik btrfs_put_root(fs_root); 107505dbe683SOmar Sandoval btrfs_free_path(path); 107605dbe683SOmar Sandoval kfree(name); 107705dbe683SOmar Sandoval return ERR_PTR(ret); 107805dbe683SOmar Sandoval } 107905dbe683SOmar Sandoval 108005dbe683SOmar Sandoval static int get_default_subvol_objectid(struct btrfs_fs_info *fs_info, u64 *objectid) 108105dbe683SOmar Sandoval { 108205dbe683SOmar Sandoval struct btrfs_root *root = fs_info->tree_root; 108373f73415SJosef Bacik struct btrfs_dir_item *di; 108473f73415SJosef Bacik struct btrfs_path *path; 108573f73415SJosef Bacik struct btrfs_key location; 10866db75318SSweet Tea Dorminy struct fscrypt_str name = FSTR_INIT("default", 7); 108773f73415SJosef Bacik u64 dir_id; 108873f73415SJosef Bacik 108973f73415SJosef Bacik path = btrfs_alloc_path(); 109073f73415SJosef Bacik if (!path) 109105dbe683SOmar Sandoval return -ENOMEM; 109273f73415SJosef Bacik 109373f73415SJosef Bacik /* 109473f73415SJosef Bacik * Find the "default" dir item which points to the root item that we 109573f73415SJosef Bacik * will mount by default if we haven't been given a specific subvolume 109673f73415SJosef Bacik * to mount. 109773f73415SJosef Bacik */ 1098815745cfSAl Viro dir_id = btrfs_super_root_dir(fs_info->super_copy); 1099e43eec81SSweet Tea Dorminy di = btrfs_lookup_dir_item(NULL, root, path, dir_id, &name, 0); 1100b0839166SJulia Lawall if (IS_ERR(di)) { 1101b0839166SJulia Lawall btrfs_free_path(path); 110205dbe683SOmar Sandoval return PTR_ERR(di); 1103b0839166SJulia Lawall } 110473f73415SJosef Bacik if (!di) { 110573f73415SJosef Bacik /* 110673f73415SJosef Bacik * Ok the default dir item isn't there. This is weird since 110773f73415SJosef Bacik * it's always been there, but don't freak out, just try and 110805dbe683SOmar Sandoval * mount the top-level subvolume. 110973f73415SJosef Bacik */ 111073f73415SJosef Bacik btrfs_free_path(path); 111105dbe683SOmar Sandoval *objectid = BTRFS_FS_TREE_OBJECTID; 111205dbe683SOmar Sandoval return 0; 111373f73415SJosef Bacik } 111473f73415SJosef Bacik 111573f73415SJosef Bacik btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location); 111673f73415SJosef Bacik btrfs_free_path(path); 111705dbe683SOmar Sandoval *objectid = location.objectid; 111805dbe683SOmar Sandoval return 0; 111973f73415SJosef Bacik } 112073f73415SJosef Bacik 11218a4b83ccSChris Mason static int btrfs_fill_super(struct super_block *sb, 11228a4b83ccSChris Mason struct btrfs_fs_devices *fs_devices, 112356e033a7SDavid Sterba void *data) 11242e635a27SChris Mason { 11252e635a27SChris Mason struct inode *inode; 1126815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(sb); 112739279cc3SChris Mason int err; 11282e635a27SChris Mason 11292e635a27SChris Mason sb->s_maxbytes = MAX_LFS_FILESIZE; 11302e635a27SChris Mason sb->s_magic = BTRFS_SUPER_MAGIC; 1131e20d96d6SChris Mason sb->s_op = &btrfs_super_ops; 1132af53d29aSAl Viro sb->s_d_op = &btrfs_dentry_operations; 1133be6e8dc0SBalaji Rao sb->s_export_op = &btrfs_export_ops; 113414605409SBoris Burkov #ifdef CONFIG_FS_VERITY 113514605409SBoris Burkov sb->s_vop = &btrfs_verityops; 113614605409SBoris Burkov #endif 11375103e947SJosef Bacik sb->s_xattr = btrfs_xattr_handlers; 11382e635a27SChris Mason sb->s_time_gran = 1; 11390eda294dSChris Mason #ifdef CONFIG_BTRFS_FS_POSIX_ACL 11401751e8a6SLinus Torvalds sb->s_flags |= SB_POSIXACL; 114149cf6f45SChris Ball #endif 1142357fdad0SMatthew Garrett sb->s_flags |= SB_I_VERSION; 1143da2f0f74SChris Mason sb->s_iflags |= SB_I_CGROUPWB; 11449e11ceeeSJan Kara 11459e11ceeeSJan Kara err = super_setup_bdi(sb); 11469e11ceeeSJan Kara if (err) { 11479e11ceeeSJan Kara btrfs_err(fs_info, "super_setup_bdi failed"); 11489e11ceeeSJan Kara return err; 11499e11ceeeSJan Kara } 11509e11ceeeSJan Kara 1151ad2b2c80SAl Viro err = open_ctree(sb, fs_devices, (char *)data); 1152ad2b2c80SAl Viro if (err) { 1153ab8d0fc4SJeff Mahoney btrfs_err(fs_info, "open_ctree failed"); 1154ad2b2c80SAl Viro return err; 1155e20d96d6SChris Mason } 1156b888db2bSChris Mason 11570202e83fSDavid Sterba inode = btrfs_iget(sb, BTRFS_FIRST_FREE_OBJECTID, fs_info->fs_root); 11585d4f98a2SYan Zheng if (IS_ERR(inode)) { 11595d4f98a2SYan Zheng err = PTR_ERR(inode); 116039279cc3SChris Mason goto fail_close; 116139279cc3SChris Mason } 11622e635a27SChris Mason 116348fde701SAl Viro sb->s_root = d_make_root(inode); 116448fde701SAl Viro if (!sb->s_root) { 116539279cc3SChris Mason err = -ENOMEM; 116639279cc3SChris Mason goto fail_close; 11672e635a27SChris Mason } 116858176a96SJosef Bacik 11691751e8a6SLinus Torvalds sb->s_flags |= SB_ACTIVE; 11702e635a27SChris Mason return 0; 11712e635a27SChris Mason 117239279cc3SChris Mason fail_close: 11736bccf3abSJeff Mahoney close_ctree(fs_info); 1174d5719762SChris Mason return err; 1175d5719762SChris Mason } 1176d5719762SChris Mason 11776bf13c0cSSage Weil int btrfs_sync_fs(struct super_block *sb, int wait) 1178d5719762SChris Mason { 1179d5719762SChris Mason struct btrfs_trans_handle *trans; 1180815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(sb); 1181815745cfSAl Viro struct btrfs_root *root = fs_info->tree_root; 1182df2ce34cSChris Mason 1183bc074524SJeff Mahoney trace_btrfs_sync_fs(fs_info, wait); 11841abe9b8aSliubo 1185d561c025SChris Mason if (!wait) { 1186815745cfSAl Viro filemap_flush(fs_info->btree_inode->i_mapping); 1187df2ce34cSChris Mason return 0; 1188d561c025SChris Mason } 1189771ed689SChris Mason 11906374e57aSChris Mason btrfs_wait_ordered_roots(fs_info, U64_MAX, 0, (u64)-1); 1191771ed689SChris Mason 1192d4edf39bSMiao Xie trans = btrfs_attach_transaction_barrier(root); 119360376ce4SJosef Bacik if (IS_ERR(trans)) { 1194354aa0fbSMiao Xie /* no transaction, don't bother */ 11956b5fe46dSDavid Sterba if (PTR_ERR(trans) == -ENOENT) { 11966b5fe46dSDavid Sterba /* 11976b5fe46dSDavid Sterba * Exit unless we have some pending changes 11986b5fe46dSDavid Sterba * that need to go through commit 11996b5fe46dSDavid Sterba */ 1200c52cc7b7SJosef Bacik if (!test_bit(BTRFS_FS_NEED_TRANS_COMMIT, 1201c52cc7b7SJosef Bacik &fs_info->flags)) 1202bd7de2c9SJosef Bacik return 0; 1203a53f4f8eSQu Wenruo /* 1204a53f4f8eSQu Wenruo * A non-blocking test if the fs is frozen. We must not 1205a53f4f8eSQu Wenruo * start a new transaction here otherwise a deadlock 1206a53f4f8eSQu Wenruo * happens. The pending operations are delayed to the 1207a53f4f8eSQu Wenruo * next commit after thawing. 1208a53f4f8eSQu Wenruo */ 1209a7e3c5f2SRakesh Pandit if (sb_start_write_trylock(sb)) 1210a7e3c5f2SRakesh Pandit sb_end_write(sb); 1211a53f4f8eSQu Wenruo else 1212a53f4f8eSQu Wenruo return 0; 12136b5fe46dSDavid Sterba trans = btrfs_start_transaction(root, 0); 121460376ce4SJosef Bacik } 121598bd5c54SDavid Sterba if (IS_ERR(trans)) 121698bd5c54SDavid Sterba return PTR_ERR(trans); 12176b5fe46dSDavid Sterba } 12183a45bb20SJeff Mahoney return btrfs_commit_transaction(trans); 1219d5719762SChris Mason } 1220d5719762SChris Mason 1221ab0b4a3eSJosef Bacik static void print_rescue_option(struct seq_file *seq, const char *s, bool *printed) 1222ab0b4a3eSJosef Bacik { 1223ab0b4a3eSJosef Bacik seq_printf(seq, "%s%s", (*printed) ? ":" : ",rescue=", s); 1224ab0b4a3eSJosef Bacik *printed = true; 1225ab0b4a3eSJosef Bacik } 1226ab0b4a3eSJosef Bacik 122734c80b1dSAl Viro static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) 1228a9572a15SEric Paris { 1229815745cfSAl Viro struct btrfs_fs_info *info = btrfs_sb(dentry->d_sb); 12300f628c63SDavid Sterba const char *compress_type; 12313ef3959bSJosef Bacik const char *subvol_name; 1232ab0b4a3eSJosef Bacik bool printed = false; 1233a9572a15SEric Paris 12343cdde224SJeff Mahoney if (btrfs_test_opt(info, DEGRADED)) 1235a9572a15SEric Paris seq_puts(seq, ",degraded"); 12363cdde224SJeff Mahoney if (btrfs_test_opt(info, NODATASUM)) 1237a9572a15SEric Paris seq_puts(seq, ",nodatasum"); 12383cdde224SJeff Mahoney if (btrfs_test_opt(info, NODATACOW)) 1239a9572a15SEric Paris seq_puts(seq, ",nodatacow"); 12403cdde224SJeff Mahoney if (btrfs_test_opt(info, NOBARRIER)) 1241a9572a15SEric Paris seq_puts(seq, ",nobarrier"); 124295ac567aSFilipe David Borba Manana if (info->max_inline != BTRFS_DEFAULT_MAX_INLINE) 1243c1c9ff7cSGeert Uytterhoeven seq_printf(seq, ",max_inline=%llu", info->max_inline); 1244a9572a15SEric Paris if (info->thread_pool_size != min_t(unsigned long, 1245a9572a15SEric Paris num_online_cpus() + 2, 8)) 1246f7b885beSAnand Jain seq_printf(seq, ",thread_pool=%u", info->thread_pool_size); 12473cdde224SJeff Mahoney if (btrfs_test_opt(info, COMPRESS)) { 12480f628c63SDavid Sterba compress_type = btrfs_compress_type2str(info->compress_type); 12493cdde224SJeff Mahoney if (btrfs_test_opt(info, FORCE_COMPRESS)) 1250200da64eSTsutomu Itoh seq_printf(seq, ",compress-force=%s", compress_type); 1251200da64eSTsutomu Itoh else 1252200da64eSTsutomu Itoh seq_printf(seq, ",compress=%s", compress_type); 1253f51d2b59SDavid Sterba if (info->compress_level) 1254fa4d885aSAdam Borowski seq_printf(seq, ":%d", info->compress_level); 1255200da64eSTsutomu Itoh } 12563cdde224SJeff Mahoney if (btrfs_test_opt(info, NOSSD)) 1257c289811cSChris Mason seq_puts(seq, ",nossd"); 12583cdde224SJeff Mahoney if (btrfs_test_opt(info, SSD_SPREAD)) 1259451d7585SChris Mason seq_puts(seq, ",ssd_spread"); 12603cdde224SJeff Mahoney else if (btrfs_test_opt(info, SSD)) 1261a9572a15SEric Paris seq_puts(seq, ",ssd"); 12623cdde224SJeff Mahoney if (btrfs_test_opt(info, NOTREELOG)) 12636b65c5c6SSage Weil seq_puts(seq, ",notreelog"); 12643cdde224SJeff Mahoney if (btrfs_test_opt(info, NOLOGREPLAY)) 1265ab0b4a3eSJosef Bacik print_rescue_option(seq, "nologreplay", &printed); 126668319c18SJosef Bacik if (btrfs_test_opt(info, USEBACKUPROOT)) 126768319c18SJosef Bacik print_rescue_option(seq, "usebackuproot", &printed); 126842437a63SJosef Bacik if (btrfs_test_opt(info, IGNOREBADROOTS)) 126942437a63SJosef Bacik print_rescue_option(seq, "ignorebadroots", &printed); 1270882dbe0cSJosef Bacik if (btrfs_test_opt(info, IGNOREDATACSUMS)) 1271882dbe0cSJosef Bacik print_rescue_option(seq, "ignoredatacsums", &printed); 12723cdde224SJeff Mahoney if (btrfs_test_opt(info, FLUSHONCOMMIT)) 12736b65c5c6SSage Weil seq_puts(seq, ",flushoncommit"); 127446b27f50SDennis Zhou if (btrfs_test_opt(info, DISCARD_SYNC)) 127520a5239aSMatthew Wilcox seq_puts(seq, ",discard"); 1276b0643e59SDennis Zhou if (btrfs_test_opt(info, DISCARD_ASYNC)) 1277b0643e59SDennis Zhou seq_puts(seq, ",discard=async"); 12781751e8a6SLinus Torvalds if (!(info->sb->s_flags & SB_POSIXACL)) 1279a9572a15SEric Paris seq_puts(seq, ",noacl"); 128004c41559SBoris Burkov if (btrfs_free_space_cache_v1_active(info)) 1281200da64eSTsutomu Itoh seq_puts(seq, ",space_cache"); 128204c41559SBoris Burkov else if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE)) 128370f6d82eSOmar Sandoval seq_puts(seq, ",space_cache=v2"); 128473bc1876SJosef Bacik else 12858965593eSDavid Sterba seq_puts(seq, ",nospace_cache"); 12863cdde224SJeff Mahoney if (btrfs_test_opt(info, RESCAN_UUID_TREE)) 1287f420ee1eSStefan Behrens seq_puts(seq, ",rescan_uuid_tree"); 12883cdde224SJeff Mahoney if (btrfs_test_opt(info, CLEAR_CACHE)) 1289200da64eSTsutomu Itoh seq_puts(seq, ",clear_cache"); 12903cdde224SJeff Mahoney if (btrfs_test_opt(info, USER_SUBVOL_RM_ALLOWED)) 1291200da64eSTsutomu Itoh seq_puts(seq, ",user_subvol_rm_allowed"); 12923cdde224SJeff Mahoney if (btrfs_test_opt(info, ENOSPC_DEBUG)) 12930942caa3SDavid Sterba seq_puts(seq, ",enospc_debug"); 12943cdde224SJeff Mahoney if (btrfs_test_opt(info, AUTO_DEFRAG)) 12950942caa3SDavid Sterba seq_puts(seq, ",autodefrag"); 12963cdde224SJeff Mahoney if (btrfs_test_opt(info, SKIP_BALANCE)) 12979555c6c1SIlya Dryomov seq_puts(seq, ",skip_balance"); 12988507d216SWang Shilong #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY 1299cbeaae4fSDavid Sterba if (btrfs_test_opt(info, CHECK_INTEGRITY_DATA)) 13008507d216SWang Shilong seq_puts(seq, ",check_int_data"); 13013cdde224SJeff Mahoney else if (btrfs_test_opt(info, CHECK_INTEGRITY)) 13028507d216SWang Shilong seq_puts(seq, ",check_int"); 13038507d216SWang Shilong if (info->check_integrity_print_mask) 13048507d216SWang Shilong seq_printf(seq, ",check_int_print_mask=%d", 13058507d216SWang Shilong info->check_integrity_print_mask); 13068507d216SWang Shilong #endif 13078507d216SWang Shilong if (info->metadata_ratio) 1308764cb8b4SAnand Jain seq_printf(seq, ",metadata_ratio=%u", info->metadata_ratio); 13093cdde224SJeff Mahoney if (btrfs_test_opt(info, PANIC_ON_FATAL_ERROR)) 13108c342930SJeff Mahoney seq_puts(seq, ",fatal_errors=panic"); 13118b87dc17SDavid Sterba if (info->commit_interval != BTRFS_DEFAULT_COMMIT_INTERVAL) 1312d3740608SAnand Jain seq_printf(seq, ",commit=%u", info->commit_interval); 1313d0bd4560SJosef Bacik #ifdef CONFIG_BTRFS_DEBUG 13143cdde224SJeff Mahoney if (btrfs_test_opt(info, FRAGMENT_DATA)) 1315d0bd4560SJosef Bacik seq_puts(seq, ",fragment=data"); 13163cdde224SJeff Mahoney if (btrfs_test_opt(info, FRAGMENT_METADATA)) 1317d0bd4560SJosef Bacik seq_puts(seq, ",fragment=metadata"); 1318d0bd4560SJosef Bacik #endif 1319fb592373SJosef Bacik if (btrfs_test_opt(info, REF_VERIFY)) 1320fb592373SJosef Bacik seq_puts(seq, ",ref_verify"); 1321c8d3fe02SOmar Sandoval seq_printf(seq, ",subvolid=%llu", 1322c8d3fe02SOmar Sandoval BTRFS_I(d_inode(dentry))->root->root_key.objectid); 13233ef3959bSJosef Bacik subvol_name = btrfs_get_subvol_name_from_objectid(info, 13243ef3959bSJosef Bacik BTRFS_I(d_inode(dentry))->root->root_key.objectid); 13253ef3959bSJosef Bacik if (!IS_ERR(subvol_name)) { 1326c8d3fe02SOmar Sandoval seq_puts(seq, ",subvol="); 13273ef3959bSJosef Bacik seq_escape(seq, subvol_name, " \t\n\\"); 13283ef3959bSJosef Bacik kfree(subvol_name); 13293ef3959bSJosef Bacik } 1330a9572a15SEric Paris return 0; 1331a9572a15SEric Paris } 1332a9572a15SEric Paris 1333a061fc8dSChris Mason static int btrfs_test_super(struct super_block *s, void *data) 13342e635a27SChris Mason { 1335815745cfSAl Viro struct btrfs_fs_info *p = data; 1336815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(s); 13374b82d6e4SYan 1338815745cfSAl Viro return fs_info->fs_devices == p->fs_devices; 13394b82d6e4SYan } 13404b82d6e4SYan 1341450ba0eaSJosef Bacik static int btrfs_set_super(struct super_block *s, void *data) 1342450ba0eaSJosef Bacik { 13436de1d09dSAl Viro int err = set_anon_super(s, data); 13446de1d09dSAl Viro if (!err) 1345450ba0eaSJosef Bacik s->s_fs_info = data; 13466de1d09dSAl Viro return err; 1347450ba0eaSJosef Bacik } 1348450ba0eaSJosef Bacik 1349830c4adbSJosef Bacik /* 1350f9d9ef62SDavid Sterba * subvolumes are identified by ino 256 1351f9d9ef62SDavid Sterba */ 1352f9d9ef62SDavid Sterba static inline int is_subvolume_inode(struct inode *inode) 1353f9d9ef62SDavid Sterba { 1354f9d9ef62SDavid Sterba if (inode && inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) 1355f9d9ef62SDavid Sterba return 1; 1356f9d9ef62SDavid Sterba return 0; 1357f9d9ef62SDavid Sterba } 1358f9d9ef62SDavid Sterba 1359bb289b7bSOmar Sandoval static struct dentry *mount_subvol(const char *subvol_name, u64 subvol_objectid, 1360ae0bc863SAnand Jain struct vfsmount *mnt) 1361830c4adbSJosef Bacik { 1362830c4adbSJosef Bacik struct dentry *root; 1363fa330659SOmar Sandoval int ret; 1364830c4adbSJosef Bacik 136505dbe683SOmar Sandoval if (!subvol_name) { 136605dbe683SOmar Sandoval if (!subvol_objectid) { 136705dbe683SOmar Sandoval ret = get_default_subvol_objectid(btrfs_sb(mnt->mnt_sb), 136805dbe683SOmar Sandoval &subvol_objectid); 136905dbe683SOmar Sandoval if (ret) { 137005dbe683SOmar Sandoval root = ERR_PTR(ret); 137105dbe683SOmar Sandoval goto out; 137205dbe683SOmar Sandoval } 137305dbe683SOmar Sandoval } 1374c0c907a4SMarcos Paulo de Souza subvol_name = btrfs_get_subvol_name_from_objectid( 1375c0c907a4SMarcos Paulo de Souza btrfs_sb(mnt->mnt_sb), subvol_objectid); 137605dbe683SOmar Sandoval if (IS_ERR(subvol_name)) { 137705dbe683SOmar Sandoval root = ERR_CAST(subvol_name); 137805dbe683SOmar Sandoval subvol_name = NULL; 137905dbe683SOmar Sandoval goto out; 138005dbe683SOmar Sandoval } 138105dbe683SOmar Sandoval 138205dbe683SOmar Sandoval } 138305dbe683SOmar Sandoval 1384ea441d11SAl Viro root = mount_subtree(mnt, subvol_name); 1385fa330659SOmar Sandoval /* mount_subtree() drops our reference on the vfsmount. */ 1386fa330659SOmar Sandoval mnt = NULL; 1387830c4adbSJosef Bacik 1388bb289b7bSOmar Sandoval if (!IS_ERR(root)) { 1389ea441d11SAl Viro struct super_block *s = root->d_sb; 1390ab8d0fc4SJeff Mahoney struct btrfs_fs_info *fs_info = btrfs_sb(s); 1391bb289b7bSOmar Sandoval struct inode *root_inode = d_inode(root); 1392bb289b7bSOmar Sandoval u64 root_objectid = BTRFS_I(root_inode)->root->root_key.objectid; 1393bb289b7bSOmar Sandoval 1394bb289b7bSOmar Sandoval ret = 0; 1395bb289b7bSOmar Sandoval if (!is_subvolume_inode(root_inode)) { 1396ab8d0fc4SJeff Mahoney btrfs_err(fs_info, "'%s' is not a valid subvolume", 1397bb289b7bSOmar Sandoval subvol_name); 1398bb289b7bSOmar Sandoval ret = -EINVAL; 1399bb289b7bSOmar Sandoval } 1400bb289b7bSOmar Sandoval if (subvol_objectid && root_objectid != subvol_objectid) { 140105dbe683SOmar Sandoval /* 140205dbe683SOmar Sandoval * This will also catch a race condition where a 140305dbe683SOmar Sandoval * subvolume which was passed by ID is renamed and 140405dbe683SOmar Sandoval * another subvolume is renamed over the old location. 140505dbe683SOmar Sandoval */ 1406ab8d0fc4SJeff Mahoney btrfs_err(fs_info, 1407ab8d0fc4SJeff Mahoney "subvol '%s' does not match subvolid %llu", 1408bb289b7bSOmar Sandoval subvol_name, subvol_objectid); 1409bb289b7bSOmar Sandoval ret = -EINVAL; 1410bb289b7bSOmar Sandoval } 1411bb289b7bSOmar Sandoval if (ret) { 1412ea441d11SAl Viro dput(root); 1413bb289b7bSOmar Sandoval root = ERR_PTR(ret); 1414ea441d11SAl Viro deactivate_locked_super(s); 1415bb289b7bSOmar Sandoval } 1416f9d9ef62SDavid Sterba } 1417f9d9ef62SDavid Sterba 1418fa330659SOmar Sandoval out: 1419fa330659SOmar Sandoval mntput(mnt); 1420fa330659SOmar Sandoval kfree(subvol_name); 1421830c4adbSJosef Bacik return root; 1422830c4adbSJosef Bacik } 1423450ba0eaSJosef Bacik 1424312c89fbSMisono, Tomohiro /* 1425312c89fbSMisono, Tomohiro * Find a superblock for the given device / mount point. 1426312c89fbSMisono, Tomohiro * 1427312c89fbSMisono, Tomohiro * Note: This is based on mount_bdev from fs/super.c with a few additions 1428312c89fbSMisono, Tomohiro * for multiple device setup. Make sure to keep it in sync. 1429312c89fbSMisono, Tomohiro */ 143072fa39f5SMisono, Tomohiro static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, 143172fa39f5SMisono, Tomohiro int flags, const char *device_name, void *data) 143272fa39f5SMisono, Tomohiro { 143372fa39f5SMisono, Tomohiro struct block_device *bdev = NULL; 143472fa39f5SMisono, Tomohiro struct super_block *s; 143536350e95SGu Jinxiang struct btrfs_device *device = NULL; 143672fa39f5SMisono, Tomohiro struct btrfs_fs_devices *fs_devices = NULL; 143772fa39f5SMisono, Tomohiro struct btrfs_fs_info *fs_info = NULL; 1438204cc0ccSAl Viro void *new_sec_opts = NULL; 143972fa39f5SMisono, Tomohiro fmode_t mode = FMODE_READ; 144072fa39f5SMisono, Tomohiro int error = 0; 144172fa39f5SMisono, Tomohiro 144272fa39f5SMisono, Tomohiro if (!(flags & SB_RDONLY)) 144372fa39f5SMisono, Tomohiro mode |= FMODE_WRITE; 144472fa39f5SMisono, Tomohiro 144572fa39f5SMisono, Tomohiro if (data) { 1446a65001e8SAl Viro error = security_sb_eat_lsm_opts(data, &new_sec_opts); 144772fa39f5SMisono, Tomohiro if (error) 144872fa39f5SMisono, Tomohiro return ERR_PTR(error); 144972fa39f5SMisono, Tomohiro } 145072fa39f5SMisono, Tomohiro 145172fa39f5SMisono, Tomohiro /* 145272fa39f5SMisono, Tomohiro * Setup a dummy root and fs_info for test/set super. This is because 145372fa39f5SMisono, Tomohiro * we don't actually fill this stuff out until open_ctree, but we need 14548260edbaSJosef Bacik * then open_ctree will properly initialize the file system specific 14558260edbaSJosef Bacik * settings later. btrfs_init_fs_info initializes the static elements 14568260edbaSJosef Bacik * of the fs_info (locks and such) to make cleanup easier if we find a 14578260edbaSJosef Bacik * superblock with our given fs_devices later on at sget() time. 145872fa39f5SMisono, Tomohiro */ 1459a8fd1f71SJeff Mahoney fs_info = kvzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL); 146072fa39f5SMisono, Tomohiro if (!fs_info) { 146172fa39f5SMisono, Tomohiro error = -ENOMEM; 146272fa39f5SMisono, Tomohiro goto error_sec_opts; 146372fa39f5SMisono, Tomohiro } 14648260edbaSJosef Bacik btrfs_init_fs_info(fs_info); 146572fa39f5SMisono, Tomohiro 146672fa39f5SMisono, Tomohiro fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); 146772fa39f5SMisono, Tomohiro fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); 146872fa39f5SMisono, Tomohiro if (!fs_info->super_copy || !fs_info->super_for_commit) { 146972fa39f5SMisono, Tomohiro error = -ENOMEM; 147072fa39f5SMisono, Tomohiro goto error_fs_info; 147172fa39f5SMisono, Tomohiro } 147272fa39f5SMisono, Tomohiro 1473f5194e34SDavid Sterba mutex_lock(&uuid_mutex); 1474fa59f27cSAnand Jain error = btrfs_parse_device_options(data, mode, fs_type); 147581ffd56bSDavid Sterba if (error) { 1476399f7f4cSDavid Sterba mutex_unlock(&uuid_mutex); 1477399f7f4cSDavid Sterba goto error_fs_info; 147881ffd56bSDavid Sterba } 1479399f7f4cSDavid Sterba 148036350e95SGu Jinxiang device = btrfs_scan_one_device(device_name, mode, fs_type); 148136350e95SGu Jinxiang if (IS_ERR(device)) { 1482399f7f4cSDavid Sterba mutex_unlock(&uuid_mutex); 148336350e95SGu Jinxiang error = PTR_ERR(device); 1484399f7f4cSDavid Sterba goto error_fs_info; 148581ffd56bSDavid Sterba } 1486399f7f4cSDavid Sterba 148736350e95SGu Jinxiang fs_devices = device->fs_devices; 1488399f7f4cSDavid Sterba fs_info->fs_devices = fs_devices; 1489399f7f4cSDavid Sterba 149072fa39f5SMisono, Tomohiro error = btrfs_open_devices(fs_devices, mode, fs_type); 1491f5194e34SDavid Sterba mutex_unlock(&uuid_mutex); 149272fa39f5SMisono, Tomohiro if (error) 149372fa39f5SMisono, Tomohiro goto error_fs_info; 149472fa39f5SMisono, Tomohiro 149572fa39f5SMisono, Tomohiro if (!(flags & SB_RDONLY) && fs_devices->rw_devices == 0) { 149672fa39f5SMisono, Tomohiro error = -EACCES; 149772fa39f5SMisono, Tomohiro goto error_close_devices; 149872fa39f5SMisono, Tomohiro } 149972fa39f5SMisono, Tomohiro 1500d24fa5c1SAnand Jain bdev = fs_devices->latest_dev->bdev; 150172fa39f5SMisono, Tomohiro s = sget(fs_type, btrfs_test_super, btrfs_set_super, flags | SB_NOSEC, 150272fa39f5SMisono, Tomohiro fs_info); 150372fa39f5SMisono, Tomohiro if (IS_ERR(s)) { 150472fa39f5SMisono, Tomohiro error = PTR_ERR(s); 150572fa39f5SMisono, Tomohiro goto error_close_devices; 150672fa39f5SMisono, Tomohiro } 150772fa39f5SMisono, Tomohiro 150872fa39f5SMisono, Tomohiro if (s->s_root) { 150972fa39f5SMisono, Tomohiro btrfs_close_devices(fs_devices); 15100d4b0463SJosef Bacik btrfs_free_fs_info(fs_info); 151172fa39f5SMisono, Tomohiro if ((flags ^ s->s_flags) & SB_RDONLY) 151272fa39f5SMisono, Tomohiro error = -EBUSY; 151372fa39f5SMisono, Tomohiro } else { 151472fa39f5SMisono, Tomohiro snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev); 1515e33c267aSRoman Gushchin shrinker_debugfs_rename(&s->s_shrink, "sb-%s:%s", fs_type->name, 1516e33c267aSRoman Gushchin s->s_id); 151772fa39f5SMisono, Tomohiro btrfs_sb(s)->bdev_holder = fs_type; 15189b4e675aSDavid Sterba if (!strstr(crc32c_impl(), "generic")) 15199b4e675aSDavid Sterba set_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags); 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); 1633fccb5d86SQu Wenruo btrfs_workqueue_set_max(fs_info->endio_write_workers, new_pool_size); 1634fccb5d86SQu Wenruo btrfs_workqueue_set_max(fs_info->endio_freespace_worker, new_pool_size); 16355b3bc44eSQu Wenruo btrfs_workqueue_set_max(fs_info->delayed_workers, new_pool_size); 16360d2450abSSergei Trofimovich } 16370d2450abSSergei Trofimovich 1638f42a34b2SMiao Xie static inline void btrfs_remount_begin(struct btrfs_fs_info *fs_info, 1639f42a34b2SMiao Xie unsigned long old_opts, int flags) 1640f42a34b2SMiao Xie { 1641dc81cdc5SMiao Xie if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) && 1642dc81cdc5SMiao Xie (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) || 16431751e8a6SLinus Torvalds (flags & SB_RDONLY))) { 1644dc81cdc5SMiao Xie /* wait for any defraggers to finish */ 1645dc81cdc5SMiao Xie wait_event(fs_info->transaction_wait, 1646dc81cdc5SMiao Xie (atomic_read(&fs_info->defrag_running) == 0)); 16471751e8a6SLinus Torvalds if (flags & SB_RDONLY) 1648dc81cdc5SMiao Xie sync_filesystem(fs_info->sb); 1649dc81cdc5SMiao Xie } 1650dc81cdc5SMiao Xie } 1651dc81cdc5SMiao Xie 1652dc81cdc5SMiao Xie static inline void btrfs_remount_cleanup(struct btrfs_fs_info *fs_info, 1653dc81cdc5SMiao Xie unsigned long old_opts) 1654dc81cdc5SMiao Xie { 165594846229SBoris Burkov const bool cache_opt = btrfs_test_opt(fs_info, SPACE_CACHE); 165694846229SBoris Burkov 1657dc81cdc5SMiao Xie /* 1658180e4d47SLuis de Bethencourt * We need to cleanup all defragable inodes if the autodefragment is 1659180e4d47SLuis de Bethencourt * close or the filesystem is read only. 1660dc81cdc5SMiao Xie */ 1661dc81cdc5SMiao Xie if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) && 1662bc98a42cSDavid Howells (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) || sb_rdonly(fs_info->sb))) { 1663dc81cdc5SMiao Xie btrfs_cleanup_defrag_inodes(fs_info); 1664dc81cdc5SMiao Xie } 1665dc81cdc5SMiao Xie 1666b0643e59SDennis Zhou /* If we toggled discard async */ 1667b0643e59SDennis Zhou if (!btrfs_raw_test_opt(old_opts, DISCARD_ASYNC) && 1668b0643e59SDennis Zhou btrfs_test_opt(fs_info, DISCARD_ASYNC)) 1669b0643e59SDennis Zhou btrfs_discard_resume(fs_info); 1670b0643e59SDennis Zhou else if (btrfs_raw_test_opt(old_opts, DISCARD_ASYNC) && 1671b0643e59SDennis Zhou !btrfs_test_opt(fs_info, DISCARD_ASYNC)) 1672b0643e59SDennis Zhou btrfs_discard_cleanup(fs_info); 167394846229SBoris Burkov 167494846229SBoris Burkov /* If we toggled space cache */ 167594846229SBoris Burkov if (cache_opt != btrfs_free_space_cache_v1_active(fs_info)) 167694846229SBoris Burkov btrfs_set_free_space_cache_v1_active(fs_info, cache_opt); 1677dc81cdc5SMiao Xie } 1678dc81cdc5SMiao Xie 1679c146afadSYan Zheng static int btrfs_remount(struct super_block *sb, int *flags, char *data) 1680c146afadSYan Zheng { 1681815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(sb); 168249b25e05SJeff Mahoney unsigned old_flags = sb->s_flags; 168349b25e05SJeff Mahoney unsigned long old_opts = fs_info->mount_opt; 168449b25e05SJeff Mahoney unsigned long old_compress_type = fs_info->compress_type; 168549b25e05SJeff Mahoney u64 old_max_inline = fs_info->max_inline; 1686f7b885beSAnand Jain u32 old_thread_pool_size = fs_info->thread_pool_size; 1687d612ac59SAnand Jain u32 old_metadata_ratio = fs_info->metadata_ratio; 1688c146afadSYan Zheng int ret; 1689c146afadSYan Zheng 169002b9984dSTheodore Ts'o sync_filesystem(sb); 169188c4703fSJohannes Thumshirn set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); 1692dc81cdc5SMiao Xie 1693f667aef6SQu Wenruo if (data) { 1694204cc0ccSAl Viro void *new_sec_opts = NULL; 1695f667aef6SQu Wenruo 1696a65001e8SAl Viro ret = security_sb_eat_lsm_opts(data, &new_sec_opts); 1697a65001e8SAl Viro if (!ret) 1698204cc0ccSAl Viro ret = security_sb_remount(sb, new_sec_opts); 1699a65001e8SAl Viro security_free_mnt_opts(&new_sec_opts); 1700f667aef6SQu Wenruo if (ret) 1701f667aef6SQu Wenruo goto restore; 1702f667aef6SQu Wenruo } 1703f667aef6SQu Wenruo 17042ff7e61eSJeff Mahoney ret = btrfs_parse_options(fs_info, data, *flags); 1705891f41cbSChengguang Xu if (ret) 170649b25e05SJeff Mahoney goto restore; 1707b288052eSChris Mason 1708d7f67ac9SQu Wenruo ret = btrfs_check_features(fs_info, sb); 1709d7f67ac9SQu Wenruo if (ret < 0) 17100591f040SQu Wenruo goto restore; 1711d7f67ac9SQu Wenruo 1712f42a34b2SMiao Xie btrfs_remount_begin(fs_info, old_opts, *flags); 17130d2450abSSergei Trofimovich btrfs_resize_thread_pool(fs_info, 17140d2450abSSergei Trofimovich fs_info->thread_pool_size, old_thread_pool_size); 17150d2450abSSergei Trofimovich 1716c55a4319SBoris Burkov if ((bool)btrfs_test_opt(fs_info, FREE_SPACE_TREE) != 1717c55a4319SBoris Burkov (bool)btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) && 17182838d255SBoris Burkov (!sb_rdonly(sb) || (*flags & SB_RDONLY))) { 17192838d255SBoris Burkov btrfs_warn(fs_info, 17202838d255SBoris Burkov "remount supports changing free space tree only from ro to rw"); 17212838d255SBoris Burkov /* Make sure free space cache options match the state on disk */ 17222838d255SBoris Burkov if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) { 17232838d255SBoris Burkov btrfs_set_opt(fs_info->mount_opt, FREE_SPACE_TREE); 17242838d255SBoris Burkov btrfs_clear_opt(fs_info->mount_opt, SPACE_CACHE); 17252838d255SBoris Burkov } 17262838d255SBoris Burkov if (btrfs_free_space_cache_v1_active(fs_info)) { 17272838d255SBoris Burkov btrfs_clear_opt(fs_info->mount_opt, FREE_SPACE_TREE); 17282838d255SBoris Burkov btrfs_set_opt(fs_info->mount_opt, SPACE_CACHE); 17292838d255SBoris Burkov } 17302838d255SBoris Burkov } 17312838d255SBoris Burkov 17321751e8a6SLinus Torvalds if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb)) 1733dc81cdc5SMiao Xie goto out; 1734c146afadSYan Zheng 17351751e8a6SLinus Torvalds if (*flags & SB_RDONLY) { 17368dabb742SStefan Behrens /* 17378dabb742SStefan Behrens * this also happens on 'umount -rf' or on shutdown, when 17388dabb742SStefan Behrens * the filesystem is busy. 17398dabb742SStefan Behrens */ 174021c7e756SMiao Xie cancel_work_sync(&fs_info->async_reclaim_work); 174157056740SJosef Bacik cancel_work_sync(&fs_info->async_data_reclaim_work); 1742361c093dSStefan Behrens 1743b0643e59SDennis Zhou btrfs_discard_cleanup(fs_info); 1744b0643e59SDennis Zhou 1745361c093dSStefan Behrens /* wait for the uuid_scan task to finish */ 1746361c093dSStefan Behrens down(&fs_info->uuid_tree_rescan_sem); 1747361c093dSStefan Behrens /* avoid complains from lockdep et al. */ 1748361c093dSStefan Behrens up(&fs_info->uuid_tree_rescan_sem); 1749361c093dSStefan Behrens 1750a0a1db70SFilipe Manana btrfs_set_sb_rdonly(sb); 1751c146afadSYan Zheng 1752e44163e1SJeff Mahoney /* 17531751e8a6SLinus Torvalds * Setting SB_RDONLY will put the cleaner thread to 1754e44163e1SJeff Mahoney * sleep at the next loop if it's already active. 1755e44163e1SJeff Mahoney * If it's already asleep, we'll leave unused block 1756e44163e1SJeff Mahoney * groups on disk until we're mounted read-write again 1757e44163e1SJeff Mahoney * unless we clean them up here. 1758e44163e1SJeff Mahoney */ 1759e44163e1SJeff Mahoney btrfs_delete_unused_bgs(fs_info); 1760e44163e1SJeff Mahoney 1761a0a1db70SFilipe Manana /* 1762a0a1db70SFilipe Manana * The cleaner task could be already running before we set the 1763a0a1db70SFilipe Manana * flag BTRFS_FS_STATE_RO (and SB_RDONLY in the superblock). 1764a0a1db70SFilipe Manana * We must make sure that after we finish the remount, i.e. after 1765a0a1db70SFilipe Manana * we call btrfs_commit_super(), the cleaner can no longer start 1766a0a1db70SFilipe Manana * a transaction - either because it was dropping a dead root, 1767a0a1db70SFilipe Manana * running delayed iputs or deleting an unused block group (the 1768a0a1db70SFilipe Manana * cleaner picked a block group from the list of unused block 1769a0a1db70SFilipe Manana * groups before we were able to in the previous call to 1770a0a1db70SFilipe Manana * btrfs_delete_unused_bgs()). 1771a0a1db70SFilipe Manana */ 1772a0a1db70SFilipe Manana wait_on_bit(&fs_info->flags, BTRFS_FS_CLEANER_RUNNING, 1773a0a1db70SFilipe Manana TASK_UNINTERRUPTIBLE); 1774a0a1db70SFilipe Manana 1775a8cc263eSFilipe Manana /* 1776a8cc263eSFilipe Manana * We've set the superblock to RO mode, so we might have made 1777a8cc263eSFilipe Manana * the cleaner task sleep without running all pending delayed 1778a8cc263eSFilipe Manana * iputs. Go through all the delayed iputs here, so that if an 1779a8cc263eSFilipe Manana * unmount happens without remounting RW we don't end up at 1780a8cc263eSFilipe Manana * finishing close_ctree() with a non-empty list of delayed 1781a8cc263eSFilipe Manana * iputs. 1782a8cc263eSFilipe Manana */ 1783a8cc263eSFilipe Manana btrfs_run_delayed_iputs(fs_info); 1784a8cc263eSFilipe Manana 17858dabb742SStefan Behrens btrfs_dev_replace_suspend_for_unmount(fs_info); 17868dabb742SStefan Behrens btrfs_scrub_cancel(fs_info); 1787061594efSMiao Xie btrfs_pause_balance(fs_info); 17888dabb742SStefan Behrens 1789cb13eea3SFilipe Manana /* 1790cb13eea3SFilipe Manana * Pause the qgroup rescan worker if it is running. We don't want 1791cb13eea3SFilipe Manana * it to be still running after we are in RO mode, as after that, 1792cb13eea3SFilipe Manana * by the time we unmount, it might have left a transaction open, 1793cb13eea3SFilipe Manana * so we would leak the transaction and/or crash. 1794cb13eea3SFilipe Manana */ 1795cb13eea3SFilipe Manana btrfs_qgroup_wait_for_completion(fs_info, false); 1796cb13eea3SFilipe Manana 17976bccf3abSJeff Mahoney ret = btrfs_commit_super(fs_info); 179849b25e05SJeff Mahoney if (ret) 179949b25e05SJeff Mahoney goto restore; 1800c146afadSYan Zheng } else { 180184961539SJosef Bacik if (BTRFS_FS_ERROR(fs_info)) { 18026ef3de9cSDavid Sterba btrfs_err(fs_info, 1803efe120a0SFrank Holton "Remounting read-write after error is not allowed"); 18046ef3de9cSDavid Sterba ret = -EINVAL; 18056ef3de9cSDavid Sterba goto restore; 18066ef3de9cSDavid Sterba } 18078a3db184SSergei Trofimovich if (fs_info->fs_devices->rw_devices == 0) { 180849b25e05SJeff Mahoney ret = -EACCES; 180949b25e05SJeff Mahoney goto restore; 18108a3db184SSergei Trofimovich } 18112b82032cSYan Zheng 18126528b99dSAnand Jain if (!btrfs_check_rw_degradable(fs_info, NULL)) { 1813efe120a0SFrank Holton btrfs_warn(fs_info, 181452042d8eSAndrea Gelmini "too many missing devices, writable remount is not allowed"); 1815292fd7fcSStefan Behrens ret = -EACCES; 1816292fd7fcSStefan Behrens goto restore; 1817292fd7fcSStefan Behrens } 1818292fd7fcSStefan Behrens 18198a3db184SSergei Trofimovich if (btrfs_super_log_root(fs_info->super_copy) != 0) { 182010a3a3edSDavid Sterba btrfs_warn(fs_info, 182110a3a3edSDavid Sterba "mount required to replay tree-log, cannot remount read-write"); 182249b25e05SJeff Mahoney ret = -EINVAL; 182349b25e05SJeff Mahoney goto restore; 18248a3db184SSergei Trofimovich } 1825c146afadSYan Zheng 182644c0ca21SBoris Burkov /* 182744c0ca21SBoris Burkov * NOTE: when remounting with a change that does writes, don't 182844c0ca21SBoris Burkov * put it anywhere above this point, as we are not sure to be 182944c0ca21SBoris Burkov * safe to write until we pass the above checks. 183044c0ca21SBoris Burkov */ 183144c0ca21SBoris Burkov ret = btrfs_start_pre_rw_mount(fs_info); 183249b25e05SJeff Mahoney if (ret) 183349b25e05SJeff Mahoney goto restore; 1834c146afadSYan Zheng 1835a0a1db70SFilipe Manana btrfs_clear_sb_rdonly(sb); 183690c711abSZygo Blaxell 1837afcdd129SJosef Bacik set_bit(BTRFS_FS_OPEN, &fs_info->flags); 1838c146afadSYan Zheng } 1839dc81cdc5SMiao Xie out: 1840faa00889SJosef Bacik /* 1841faa00889SJosef Bacik * We need to set SB_I_VERSION here otherwise it'll get cleared by VFS, 1842faa00889SJosef Bacik * since the absence of the flag means it can be toggled off by remount. 1843faa00889SJosef Bacik */ 1844faa00889SJosef Bacik *flags |= SB_I_VERSION; 1845faa00889SJosef Bacik 18462c6a92b0SJustin Maggard wake_up_process(fs_info->transaction_kthread); 1847dc81cdc5SMiao Xie btrfs_remount_cleanup(fs_info, old_opts); 18488cd29088SBoris Burkov btrfs_clear_oneshot_options(fs_info); 184988c4703fSJohannes Thumshirn clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); 185088c4703fSJohannes Thumshirn 1851c146afadSYan Zheng return 0; 185249b25e05SJeff Mahoney 185349b25e05SJeff Mahoney restore: 18541751e8a6SLinus Torvalds /* We've hit an error - don't reset SB_RDONLY */ 1855bc98a42cSDavid Howells if (sb_rdonly(sb)) 18561751e8a6SLinus Torvalds old_flags |= SB_RDONLY; 1857a0a1db70SFilipe Manana if (!(old_flags & SB_RDONLY)) 1858a0a1db70SFilipe Manana clear_bit(BTRFS_FS_STATE_RO, &fs_info->fs_state); 185949b25e05SJeff Mahoney sb->s_flags = old_flags; 186049b25e05SJeff Mahoney fs_info->mount_opt = old_opts; 186149b25e05SJeff Mahoney fs_info->compress_type = old_compress_type; 186249b25e05SJeff Mahoney fs_info->max_inline = old_max_inline; 18630d2450abSSergei Trofimovich btrfs_resize_thread_pool(fs_info, 18640d2450abSSergei Trofimovich old_thread_pool_size, fs_info->thread_pool_size); 186549b25e05SJeff Mahoney fs_info->metadata_ratio = old_metadata_ratio; 1866dc81cdc5SMiao Xie btrfs_remount_cleanup(fs_info, old_opts); 186788c4703fSJohannes Thumshirn clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); 186888c4703fSJohannes Thumshirn 186949b25e05SJeff Mahoney return ret; 1870c146afadSYan Zheng } 1871c146afadSYan Zheng 1872bcd53741SArne Jansen /* Used to sort the devices by max_avail(descending sort) */ 1873214cc184SDavid Sterba static int btrfs_cmp_device_free_bytes(const void *a, const void *b) 1874bcd53741SArne Jansen { 1875214cc184SDavid Sterba const struct btrfs_device_info *dev_info1 = a; 1876214cc184SDavid Sterba const struct btrfs_device_info *dev_info2 = b; 1877214cc184SDavid Sterba 1878214cc184SDavid Sterba if (dev_info1->max_avail > dev_info2->max_avail) 1879bcd53741SArne Jansen return -1; 1880214cc184SDavid Sterba else if (dev_info1->max_avail < dev_info2->max_avail) 1881bcd53741SArne Jansen return 1; 1882bcd53741SArne Jansen return 0; 1883bcd53741SArne Jansen } 1884bcd53741SArne Jansen 1885bcd53741SArne Jansen /* 1886bcd53741SArne Jansen * sort the devices by max_avail, in which max free extent size of each device 1887bcd53741SArne Jansen * is stored.(Descending Sort) 1888bcd53741SArne Jansen */ 1889bcd53741SArne Jansen static inline void btrfs_descending_sort_devices( 1890bcd53741SArne Jansen struct btrfs_device_info *devices, 1891bcd53741SArne Jansen size_t nr_devices) 1892bcd53741SArne Jansen { 1893bcd53741SArne Jansen sort(devices, nr_devices, sizeof(struct btrfs_device_info), 1894bcd53741SArne Jansen btrfs_cmp_device_free_bytes, NULL); 1895bcd53741SArne Jansen } 1896bcd53741SArne Jansen 18976d07bcecSMiao Xie /* 18986d07bcecSMiao Xie * The helper to calc the free space on the devices that can be used to store 18996d07bcecSMiao Xie * file data. 19006d07bcecSMiao Xie */ 19017e17916bSArnd Bergmann static inline int btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info, 19026bccf3abSJeff Mahoney u64 *free_bytes) 19036d07bcecSMiao Xie { 19046d07bcecSMiao Xie struct btrfs_device_info *devices_info; 19056d07bcecSMiao Xie struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; 19066d07bcecSMiao Xie struct btrfs_device *device; 19076d07bcecSMiao Xie u64 type; 19086d07bcecSMiao Xie u64 avail_space; 19096d07bcecSMiao Xie u64 min_stripe_size; 1910559ca6eaSNikolay Borisov int num_stripes = 1; 19116d07bcecSMiao Xie int i = 0, nr_devices; 19124f080f57SDavid Sterba const struct btrfs_raid_attr *rattr; 19136d07bcecSMiao Xie 19147e33fd99SJosef Bacik /* 191501327610SNicholas D Steeves * We aren't under the device list lock, so this is racy-ish, but good 19167e33fd99SJosef Bacik * enough for our purposes. 19177e33fd99SJosef Bacik */ 1918b772a86eSLi Zefan nr_devices = fs_info->fs_devices->open_devices; 19197e33fd99SJosef Bacik if (!nr_devices) { 19207e33fd99SJosef Bacik smp_mb(); 19217e33fd99SJosef Bacik nr_devices = fs_info->fs_devices->open_devices; 19227e33fd99SJosef Bacik ASSERT(nr_devices); 19237e33fd99SJosef Bacik if (!nr_devices) { 19247e33fd99SJosef Bacik *free_bytes = 0; 19257e33fd99SJosef Bacik return 0; 19267e33fd99SJosef Bacik } 19277e33fd99SJosef Bacik } 19286d07bcecSMiao Xie 1929d9b0d9baSDulshani Gunawardhana devices_info = kmalloc_array(nr_devices, sizeof(*devices_info), 19306a44517dSDavid Sterba GFP_KERNEL); 19316d07bcecSMiao Xie if (!devices_info) 19326d07bcecSMiao Xie return -ENOMEM; 19336d07bcecSMiao Xie 193401327610SNicholas D Steeves /* calc min stripe number for data space allocation */ 19351b86826dSJeff Mahoney type = btrfs_data_alloc_profile(fs_info); 19364f080f57SDavid Sterba rattr = &btrfs_raid_array[btrfs_bg_flags_to_raid_index(type)]; 19374f080f57SDavid Sterba 1938e1ea2beeSDavid Sterba if (type & BTRFS_BLOCK_GROUP_RAID0) 193939fb26c3SMiao Xie num_stripes = nr_devices; 1940d09cb9e1SDavid Sterba else if (type & BTRFS_BLOCK_GROUP_RAID1_MASK) 1941d09cb9e1SDavid Sterba num_stripes = rattr->ncopies; 1942e1ea2beeSDavid Sterba else if (type & BTRFS_BLOCK_GROUP_RAID10) 194339fb26c3SMiao Xie num_stripes = 4; 19446d07bcecSMiao Xie 19454f080f57SDavid Sterba /* Adjust for more than 1 stripe per device */ 19464f080f57SDavid Sterba min_stripe_size = rattr->dev_stripes * BTRFS_STRIPE_LEN; 19476d07bcecSMiao Xie 19487e33fd99SJosef Bacik rcu_read_lock(); 19497e33fd99SJosef Bacik list_for_each_entry_rcu(device, &fs_devices->devices, dev_list) { 1950e12c9621SAnand Jain if (!test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, 1951e12c9621SAnand Jain &device->dev_state) || 1952401e29c1SAnand Jain !device->bdev || 1953401e29c1SAnand Jain test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state)) 19546d07bcecSMiao Xie continue; 19556d07bcecSMiao Xie 19567e33fd99SJosef Bacik if (i >= nr_devices) 19577e33fd99SJosef Bacik break; 19587e33fd99SJosef Bacik 19596d07bcecSMiao Xie avail_space = device->total_bytes - device->bytes_used; 19606d07bcecSMiao Xie 19616d07bcecSMiao Xie /* align with stripe_len */ 1962559ca6eaSNikolay Borisov avail_space = rounddown(avail_space, BTRFS_STRIPE_LEN); 19636d07bcecSMiao Xie 19646d07bcecSMiao Xie /* 196537f85ec3SQu Wenruo * Ensure we have at least min_stripe_size on top of the 196637f85ec3SQu Wenruo * reserved space on the device. 19676d07bcecSMiao Xie */ 196837f85ec3SQu Wenruo if (avail_space <= BTRFS_DEVICE_RANGE_RESERVED + min_stripe_size) 19696d07bcecSMiao Xie continue; 19706d07bcecSMiao Xie 197137f85ec3SQu Wenruo avail_space -= BTRFS_DEVICE_RANGE_RESERVED; 1972559ca6eaSNikolay Borisov 19736d07bcecSMiao Xie devices_info[i].dev = device; 19746d07bcecSMiao Xie devices_info[i].max_avail = avail_space; 19756d07bcecSMiao Xie 19766d07bcecSMiao Xie i++; 19776d07bcecSMiao Xie } 19787e33fd99SJosef Bacik rcu_read_unlock(); 19796d07bcecSMiao Xie 19806d07bcecSMiao Xie nr_devices = i; 19816d07bcecSMiao Xie 19826d07bcecSMiao Xie btrfs_descending_sort_devices(devices_info, nr_devices); 19836d07bcecSMiao Xie 19846d07bcecSMiao Xie i = nr_devices - 1; 19856d07bcecSMiao Xie avail_space = 0; 1986559ca6eaSNikolay Borisov while (nr_devices >= rattr->devs_min) { 1987559ca6eaSNikolay Borisov num_stripes = min(num_stripes, nr_devices); 198839fb26c3SMiao Xie 19896d07bcecSMiao Xie if (devices_info[i].max_avail >= min_stripe_size) { 19906d07bcecSMiao Xie int j; 19916d07bcecSMiao Xie u64 alloc_size; 19926d07bcecSMiao Xie 199339fb26c3SMiao Xie avail_space += devices_info[i].max_avail * num_stripes; 19946d07bcecSMiao Xie alloc_size = devices_info[i].max_avail; 199539fb26c3SMiao Xie for (j = i + 1 - num_stripes; j <= i; j++) 19966d07bcecSMiao Xie devices_info[j].max_avail -= alloc_size; 19976d07bcecSMiao Xie } 19986d07bcecSMiao Xie i--; 19996d07bcecSMiao Xie nr_devices--; 20006d07bcecSMiao Xie } 20016d07bcecSMiao Xie 20026d07bcecSMiao Xie kfree(devices_info); 20036d07bcecSMiao Xie *free_bytes = avail_space; 20046d07bcecSMiao Xie return 0; 20056d07bcecSMiao Xie } 20066d07bcecSMiao Xie 2007ba7b6e62SDavid Sterba /* 2008ba7b6e62SDavid Sterba * Calculate numbers for 'df', pessimistic in case of mixed raid profiles. 2009ba7b6e62SDavid Sterba * 2010ba7b6e62SDavid Sterba * If there's a redundant raid level at DATA block groups, use the respective 2011ba7b6e62SDavid Sterba * multiplier to scale the sizes. 2012ba7b6e62SDavid Sterba * 2013ba7b6e62SDavid Sterba * Unused device space usage is based on simulating the chunk allocator 20140d0c71b3SDavid Sterba * algorithm that respects the device sizes and order of allocations. This is 20150d0c71b3SDavid Sterba * a close approximation of the actual use but there are other factors that may 20160d0c71b3SDavid Sterba * change the result (like a new metadata chunk). 2017ba7b6e62SDavid Sterba * 2018ca8a51b3SDavid Sterba * If metadata is exhausted, f_bavail will be 0. 2019ba7b6e62SDavid Sterba */ 20208fd17795SChris Mason static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) 20218fd17795SChris Mason { 2022815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(dentry->d_sb); 2023815745cfSAl Viro struct btrfs_super_block *disk_super = fs_info->super_copy; 2024bd4d1088SJosef Bacik struct btrfs_space_info *found; 2025bd4d1088SJosef Bacik u64 total_used = 0; 20266d07bcecSMiao Xie u64 total_free_data = 0; 2027ca8a51b3SDavid Sterba u64 total_free_meta = 0; 2028265fdfa6SDavid Sterba u32 bits = fs_info->sectorsize_bits; 2029de37aa51SNikolay Borisov __be32 *fsid = (__be32 *)fs_info->fs_devices->fsid; 2030ba7b6e62SDavid Sterba unsigned factor = 1; 2031ba7b6e62SDavid Sterba struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; 20326d07bcecSMiao Xie int ret; 2033ca8a51b3SDavid Sterba u64 thresh = 0; 2034ae02d1bdSLuis de Bethencourt int mixed = 0; 20358fd17795SChris Mason 203672804905SJosef Bacik list_for_each_entry(found, &fs_info->space_info, list) { 20376d07bcecSMiao Xie if (found->flags & BTRFS_BLOCK_GROUP_DATA) { 2038ba7b6e62SDavid Sterba int i; 2039ba7b6e62SDavid Sterba 20406d07bcecSMiao Xie total_free_data += found->disk_total - found->disk_used; 20416d07bcecSMiao Xie total_free_data -= 20426d07bcecSMiao Xie btrfs_account_ro_block_groups_free_space(found); 2043ba7b6e62SDavid Sterba 2044ba7b6e62SDavid Sterba for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) { 204546df06b8SDavid Sterba if (!list_empty(&found->block_groups[i])) 204646df06b8SDavid Sterba factor = btrfs_bg_type_to_factor( 204746df06b8SDavid Sterba btrfs_raid_array[i].bg_flag); 2048ba7b6e62SDavid Sterba } 20496d07bcecSMiao Xie } 2050ae02d1bdSLuis de Bethencourt 2051ae02d1bdSLuis de Bethencourt /* 2052ae02d1bdSLuis de Bethencourt * Metadata in mixed block goup profiles are accounted in data 2053ae02d1bdSLuis de Bethencourt */ 2054ae02d1bdSLuis de Bethencourt if (!mixed && found->flags & BTRFS_BLOCK_GROUP_METADATA) { 2055ae02d1bdSLuis de Bethencourt if (found->flags & BTRFS_BLOCK_GROUP_DATA) 2056ae02d1bdSLuis de Bethencourt mixed = 1; 2057ae02d1bdSLuis de Bethencourt else 2058ae02d1bdSLuis de Bethencourt total_free_meta += found->disk_total - 2059ae02d1bdSLuis de Bethencourt found->disk_used; 2060ae02d1bdSLuis de Bethencourt } 20616d07bcecSMiao Xie 2062b742bb82SYan, Zheng total_used += found->disk_used; 206389a55897SJosef Bacik } 2064ba7b6e62SDavid Sterba 2065ba7b6e62SDavid Sterba buf->f_blocks = div_u64(btrfs_super_total_bytes(disk_super), factor); 2066ba7b6e62SDavid Sterba buf->f_blocks >>= bits; 2067ba7b6e62SDavid Sterba buf->f_bfree = buf->f_blocks - (div_u64(total_used, factor) >> bits); 2068ba7b6e62SDavid Sterba 2069ba7b6e62SDavid Sterba /* Account global block reserve as used, it's in logical size already */ 2070ba7b6e62SDavid Sterba spin_lock(&block_rsv->lock); 207141b34accSLuis de Bethencourt /* Mixed block groups accounting is not byte-accurate, avoid overflow */ 207241b34accSLuis de Bethencourt if (buf->f_bfree >= block_rsv->size >> bits) 2073ba7b6e62SDavid Sterba buf->f_bfree -= block_rsv->size >> bits; 207441b34accSLuis de Bethencourt else 207541b34accSLuis de Bethencourt buf->f_bfree = 0; 2076ba7b6e62SDavid Sterba spin_unlock(&block_rsv->lock); 2077ba7b6e62SDavid Sterba 20780d95c1beSDavid Sterba buf->f_bavail = div_u64(total_free_data, factor); 20796bccf3abSJeff Mahoney ret = btrfs_calc_avail_data_space(fs_info, &total_free_data); 20807e33fd99SJosef Bacik if (ret) 20816d07bcecSMiao Xie return ret; 2082ba7b6e62SDavid Sterba buf->f_bavail += div_u64(total_free_data, factor); 20836d07bcecSMiao Xie buf->f_bavail = buf->f_bavail >> bits; 2084d397712bSChris Mason 2085ca8a51b3SDavid Sterba /* 2086ca8a51b3SDavid Sterba * We calculate the remaining metadata space minus global reserve. If 2087ca8a51b3SDavid Sterba * this is (supposedly) smaller than zero, there's no space. But this 2088ca8a51b3SDavid Sterba * does not hold in practice, the exhausted state happens where's still 2089ca8a51b3SDavid Sterba * some positive delta. So we apply some guesswork and compare the 2090ca8a51b3SDavid Sterba * delta to a 4M threshold. (Practically observed delta was ~2M.) 2091ca8a51b3SDavid Sterba * 2092ca8a51b3SDavid Sterba * We probably cannot calculate the exact threshold value because this 2093ca8a51b3SDavid Sterba * depends on the internal reservations requested by various 2094ca8a51b3SDavid Sterba * operations, so some operations that consume a few metadata will 2095ca8a51b3SDavid Sterba * succeed even if the Avail is zero. But this is better than the other 2096ca8a51b3SDavid Sterba * way around. 2097ca8a51b3SDavid Sterba */ 2098d4417e22SNikolay Borisov thresh = SZ_4M; 2099ca8a51b3SDavid Sterba 2100d55966c4SJosef Bacik /* 2101d55966c4SJosef Bacik * We only want to claim there's no available space if we can no longer 2102d55966c4SJosef Bacik * allocate chunks for our metadata profile and our global reserve will 2103d55966c4SJosef Bacik * not fit in the free metadata space. If we aren't ->full then we 2104d55966c4SJosef Bacik * still can allocate chunks and thus are fine using the currently 2105d55966c4SJosef Bacik * calculated f_bavail. 2106d55966c4SJosef Bacik */ 2107d55966c4SJosef Bacik if (!mixed && block_rsv->space_info->full && 2108d55966c4SJosef Bacik total_free_meta - thresh < block_rsv->size) 2109ca8a51b3SDavid Sterba buf->f_bavail = 0; 2110ca8a51b3SDavid Sterba 2111ba7b6e62SDavid Sterba buf->f_type = BTRFS_SUPER_MAGIC; 2112ba7b6e62SDavid Sterba buf->f_bsize = dentry->d_sb->s_blocksize; 2113ba7b6e62SDavid Sterba buf->f_namelen = BTRFS_NAME_LEN; 2114ba7b6e62SDavid Sterba 21159d03632eSDavid Woodhouse /* We treat it as constant endianness (it doesn't matter _which_) 21169d03632eSDavid Woodhouse because we want the fsid to come out the same whether mounted 21179d03632eSDavid Woodhouse on a big-endian or little-endian host */ 21189d03632eSDavid Woodhouse buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]); 21199d03632eSDavid Woodhouse buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]); 212032d48fa1SDavid Woodhouse /* Mask in the root object ID too, to disambiguate subvols */ 21214fd786e6SMisono Tomohiro buf->f_fsid.val[0] ^= 21224fd786e6SMisono Tomohiro BTRFS_I(d_inode(dentry))->root->root_key.objectid >> 32; 21234fd786e6SMisono Tomohiro buf->f_fsid.val[1] ^= 21244fd786e6SMisono Tomohiro BTRFS_I(d_inode(dentry))->root->root_key.objectid; 212532d48fa1SDavid Woodhouse 21268fd17795SChris Mason return 0; 21278fd17795SChris Mason } 2128b5133862SChris Mason 2129aea52e19SAl Viro static void btrfs_kill_super(struct super_block *sb) 2130aea52e19SAl Viro { 2131815745cfSAl Viro struct btrfs_fs_info *fs_info = btrfs_sb(sb); 2132aea52e19SAl Viro kill_anon_super(sb); 21330d4b0463SJosef Bacik btrfs_free_fs_info(fs_info); 2134aea52e19SAl Viro } 2135aea52e19SAl Viro 21362e635a27SChris Mason static struct file_system_type btrfs_fs_type = { 21372e635a27SChris Mason .owner = THIS_MODULE, 21382e635a27SChris Mason .name = "btrfs", 2139061dbc6bSAl Viro .mount = btrfs_mount, 2140aea52e19SAl Viro .kill_sb = btrfs_kill_super, 2141f667aef6SQu Wenruo .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA, 21422e635a27SChris Mason }; 214372fa39f5SMisono, Tomohiro 214472fa39f5SMisono, Tomohiro static struct file_system_type btrfs_root_fs_type = { 214572fa39f5SMisono, Tomohiro .owner = THIS_MODULE, 214672fa39f5SMisono, Tomohiro .name = "btrfs", 214772fa39f5SMisono, Tomohiro .mount = btrfs_mount_root, 214872fa39f5SMisono, Tomohiro .kill_sb = btrfs_kill_super, 21495b9b26f5SChristian Brauner .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA | FS_ALLOW_IDMAP, 215072fa39f5SMisono, Tomohiro }; 215172fa39f5SMisono, Tomohiro 21527f78e035SEric W. Biederman MODULE_ALIAS_FS("btrfs"); 2153a9218f6bSChris Mason 2154d8620958STom Van Braeckel static int btrfs_control_open(struct inode *inode, struct file *file) 2155d8620958STom Van Braeckel { 2156d8620958STom Van Braeckel /* 2157d8620958STom Van Braeckel * The control file's private_data is used to hold the 2158d8620958STom Van Braeckel * transaction when it is started and is used to keep 2159d8620958STom Van Braeckel * track of whether a transaction is already in progress. 2160d8620958STom Van Braeckel */ 2161d8620958STom Van Braeckel file->private_data = NULL; 2162d8620958STom Van Braeckel return 0; 2163d8620958STom Van Braeckel } 2164d8620958STom Van Braeckel 2165d352ac68SChris Mason /* 2166cfe953c8SSu Yue * Used by /dev/btrfs-control for devices ioctls. 2167d352ac68SChris Mason */ 21688a4b83ccSChris Mason static long btrfs_control_ioctl(struct file *file, unsigned int cmd, 21698a4b83ccSChris Mason unsigned long arg) 21708a4b83ccSChris Mason { 21718a4b83ccSChris Mason struct btrfs_ioctl_vol_args *vol; 217236350e95SGu Jinxiang struct btrfs_device *device = NULL; 217316cab91aSAnand Jain dev_t devt = 0; 2174c071fcfdSChris Mason int ret = -ENOTTY; 21758a4b83ccSChris Mason 2176e441d54dSChris Mason if (!capable(CAP_SYS_ADMIN)) 2177e441d54dSChris Mason return -EPERM; 2178e441d54dSChris Mason 2179dae7b665SLi Zefan vol = memdup_user((void __user *)arg, sizeof(*vol)); 2180dae7b665SLi Zefan if (IS_ERR(vol)) 2181dae7b665SLi Zefan return PTR_ERR(vol); 2182f505754fSFilipe Manana vol->name[BTRFS_PATH_NAME_MAX] = '\0'; 2183c071fcfdSChris Mason 21848a4b83ccSChris Mason switch (cmd) { 21858a4b83ccSChris Mason case BTRFS_IOC_SCAN_DEV: 2186899f9307SDavid Sterba mutex_lock(&uuid_mutex); 218736350e95SGu Jinxiang device = btrfs_scan_one_device(vol->name, FMODE_READ, 218836350e95SGu Jinxiang &btrfs_root_fs_type); 218936350e95SGu Jinxiang ret = PTR_ERR_OR_ZERO(device); 2190899f9307SDavid Sterba mutex_unlock(&uuid_mutex); 21918a4b83ccSChris Mason break; 2192228a73abSAnand Jain case BTRFS_IOC_FORGET_DEV: 219316cab91aSAnand Jain if (vol->name[0] != 0) { 219416cab91aSAnand Jain ret = lookup_bdev(vol->name, &devt); 219516cab91aSAnand Jain if (ret) 219616cab91aSAnand Jain break; 219716cab91aSAnand Jain } 219816cab91aSAnand Jain ret = btrfs_forget_devices(devt); 2199228a73abSAnand Jain break; 220002db0844SJosef Bacik case BTRFS_IOC_DEVICES_READY: 2201899f9307SDavid Sterba mutex_lock(&uuid_mutex); 220236350e95SGu Jinxiang device = btrfs_scan_one_device(vol->name, FMODE_READ, 220336350e95SGu Jinxiang &btrfs_root_fs_type); 220436350e95SGu Jinxiang if (IS_ERR(device)) { 2205899f9307SDavid Sterba mutex_unlock(&uuid_mutex); 220636350e95SGu Jinxiang ret = PTR_ERR(device); 220702db0844SJosef Bacik break; 2208899f9307SDavid Sterba } 220936350e95SGu Jinxiang ret = !(device->fs_devices->num_devices == 221036350e95SGu Jinxiang device->fs_devices->total_devices); 2211899f9307SDavid Sterba mutex_unlock(&uuid_mutex); 221202db0844SJosef Bacik break; 2213c5868f83SDavid Sterba case BTRFS_IOC_GET_SUPPORTED_FEATURES: 2214d5131b65SDavid Sterba ret = btrfs_ioctl_get_supported_features((void __user*)arg); 2215c5868f83SDavid Sterba break; 22168a4b83ccSChris Mason } 2217dae7b665SLi Zefan 22188a4b83ccSChris Mason kfree(vol); 2219f819d837SLinda Knippers return ret; 22208a4b83ccSChris Mason } 22218a4b83ccSChris Mason 22220176260fSLinus Torvalds static int btrfs_freeze(struct super_block *sb) 2223ed0dab6bSYan { 2224354aa0fbSMiao Xie struct btrfs_trans_handle *trans; 22250b246afaSJeff Mahoney struct btrfs_fs_info *fs_info = btrfs_sb(sb); 22260b246afaSJeff Mahoney struct btrfs_root *root = fs_info->tree_root; 2227354aa0fbSMiao Xie 2228fac03c8dSDavid Sterba set_bit(BTRFS_FS_FROZEN, &fs_info->flags); 22299e7cc91aSWang Xiaoguang /* 22309e7cc91aSWang Xiaoguang * We don't need a barrier here, we'll wait for any transaction that 22319e7cc91aSWang Xiaoguang * could be in progress on other threads (and do delayed iputs that 22329e7cc91aSWang Xiaoguang * we want to avoid on a frozen filesystem), or do the commit 22339e7cc91aSWang Xiaoguang * ourselves. 22349e7cc91aSWang Xiaoguang */ 2235d4edf39bSMiao Xie trans = btrfs_attach_transaction_barrier(root); 2236354aa0fbSMiao Xie if (IS_ERR(trans)) { 2237354aa0fbSMiao Xie /* no transaction, don't bother */ 2238354aa0fbSMiao Xie if (PTR_ERR(trans) == -ENOENT) 22390176260fSLinus Torvalds return 0; 2240354aa0fbSMiao Xie return PTR_ERR(trans); 2241354aa0fbSMiao Xie } 22423a45bb20SJeff Mahoney return btrfs_commit_transaction(trans); 2243ed0dab6bSYan } 2244ed0dab6bSYan 2245a05d3c91SQu Wenruo static int check_dev_super(struct btrfs_device *dev) 2246a05d3c91SQu Wenruo { 2247a05d3c91SQu Wenruo struct btrfs_fs_info *fs_info = dev->fs_info; 2248a05d3c91SQu Wenruo struct btrfs_super_block *sb; 22493d17adeaSQu Wenruo u16 csum_type; 2250a05d3c91SQu Wenruo int ret = 0; 2251a05d3c91SQu Wenruo 2252a05d3c91SQu Wenruo /* This should be called with fs still frozen. */ 2253a05d3c91SQu Wenruo ASSERT(test_bit(BTRFS_FS_FROZEN, &fs_info->flags)); 2254a05d3c91SQu Wenruo 2255a05d3c91SQu Wenruo /* Missing dev, no need to check. */ 2256a05d3c91SQu Wenruo if (!dev->bdev) 2257a05d3c91SQu Wenruo return 0; 2258a05d3c91SQu Wenruo 2259a05d3c91SQu Wenruo /* Only need to check the primary super block. */ 2260a05d3c91SQu Wenruo sb = btrfs_read_dev_one_super(dev->bdev, 0, true); 2261a05d3c91SQu Wenruo if (IS_ERR(sb)) 2262a05d3c91SQu Wenruo return PTR_ERR(sb); 2263a05d3c91SQu Wenruo 22643d17adeaSQu Wenruo /* Verify the checksum. */ 22653d17adeaSQu Wenruo csum_type = btrfs_super_csum_type(sb); 22663d17adeaSQu Wenruo if (csum_type != btrfs_super_csum_type(fs_info->super_copy)) { 22673d17adeaSQu Wenruo btrfs_err(fs_info, "csum type changed, has %u expect %u", 22683d17adeaSQu Wenruo csum_type, btrfs_super_csum_type(fs_info->super_copy)); 22693d17adeaSQu Wenruo ret = -EUCLEAN; 22703d17adeaSQu Wenruo goto out; 22713d17adeaSQu Wenruo } 22723d17adeaSQu Wenruo 22733d17adeaSQu Wenruo if (btrfs_check_super_csum(fs_info, sb)) { 22743d17adeaSQu Wenruo btrfs_err(fs_info, "csum for on-disk super block no longer matches"); 22753d17adeaSQu Wenruo ret = -EUCLEAN; 22763d17adeaSQu Wenruo goto out; 22773d17adeaSQu Wenruo } 22783d17adeaSQu Wenruo 2279a05d3c91SQu Wenruo /* Btrfs_validate_super() includes fsid check against super->fsid. */ 2280a05d3c91SQu Wenruo ret = btrfs_validate_super(fs_info, sb, 0); 2281a05d3c91SQu Wenruo if (ret < 0) 2282a05d3c91SQu Wenruo goto out; 2283a05d3c91SQu Wenruo 2284a05d3c91SQu Wenruo if (btrfs_super_generation(sb) != fs_info->last_trans_committed) { 2285a05d3c91SQu Wenruo btrfs_err(fs_info, "transid mismatch, has %llu expect %llu", 2286a05d3c91SQu Wenruo btrfs_super_generation(sb), 2287a05d3c91SQu Wenruo fs_info->last_trans_committed); 2288a05d3c91SQu Wenruo ret = -EUCLEAN; 2289a05d3c91SQu Wenruo goto out; 2290a05d3c91SQu Wenruo } 2291a05d3c91SQu Wenruo out: 2292a05d3c91SQu Wenruo btrfs_release_disk_super(sb); 2293a05d3c91SQu Wenruo return ret; 2294a05d3c91SQu Wenruo } 2295a05d3c91SQu Wenruo 22969e7cc91aSWang Xiaoguang static int btrfs_unfreeze(struct super_block *sb) 22979e7cc91aSWang Xiaoguang { 2298fac03c8dSDavid Sterba struct btrfs_fs_info *fs_info = btrfs_sb(sb); 2299a05d3c91SQu Wenruo struct btrfs_device *device; 2300a05d3c91SQu Wenruo int ret = 0; 2301fac03c8dSDavid Sterba 2302a05d3c91SQu Wenruo /* 2303a05d3c91SQu Wenruo * Make sure the fs is not changed by accident (like hibernation then 2304a05d3c91SQu Wenruo * modified by other OS). 2305a05d3c91SQu Wenruo * If we found anything wrong, we mark the fs error immediately. 2306a05d3c91SQu Wenruo * 2307a05d3c91SQu Wenruo * And since the fs is frozen, no one can modify the fs yet, thus 2308a05d3c91SQu Wenruo * we don't need to hold device_list_mutex. 2309a05d3c91SQu Wenruo */ 2310a05d3c91SQu Wenruo list_for_each_entry(device, &fs_info->fs_devices->devices, dev_list) { 2311a05d3c91SQu Wenruo ret = check_dev_super(device); 2312a05d3c91SQu Wenruo if (ret < 0) { 2313a05d3c91SQu Wenruo btrfs_handle_fs_error(fs_info, ret, 2314a05d3c91SQu Wenruo "super block on devid %llu got modified unexpectedly", 2315a05d3c91SQu Wenruo device->devid); 2316a05d3c91SQu Wenruo break; 2317a05d3c91SQu Wenruo } 2318a05d3c91SQu Wenruo } 2319fac03c8dSDavid Sterba clear_bit(BTRFS_FS_FROZEN, &fs_info->flags); 2320a05d3c91SQu Wenruo 2321a05d3c91SQu Wenruo /* 2322a05d3c91SQu Wenruo * We still return 0, to allow VFS layer to unfreeze the fs even the 2323a05d3c91SQu Wenruo * above checks failed. Since the fs is either fine or read-only, we're 2324a05d3c91SQu Wenruo * safe to continue, without causing further damage. 2325a05d3c91SQu Wenruo */ 23269e7cc91aSWang Xiaoguang return 0; 23279e7cc91aSWang Xiaoguang } 23289e7cc91aSWang Xiaoguang 23299c5085c1SJosef Bacik static int btrfs_show_devname(struct seq_file *m, struct dentry *root) 23309c5085c1SJosef Bacik { 23319c5085c1SJosef Bacik struct btrfs_fs_info *fs_info = btrfs_sb(root->d_sb); 23329c5085c1SJosef Bacik 233388c14590SDavid Sterba /* 23346605fd2fSAnand Jain * There should be always a valid pointer in latest_dev, it may be stale 23356605fd2fSAnand Jain * for a short moment in case it's being deleted but still valid until 23366605fd2fSAnand Jain * the end of RCU grace period. 233788c14590SDavid Sterba */ 233888c14590SDavid Sterba rcu_read_lock(); 2339cb3e217bSQu Wenruo seq_escape(m, btrfs_dev_name(fs_info->fs_devices->latest_dev), " \t\n\\"); 234088c14590SDavid Sterba rcu_read_unlock(); 23416605fd2fSAnand Jain 23429c5085c1SJosef Bacik return 0; 23439c5085c1SJosef Bacik } 23449c5085c1SJosef Bacik 2345b87221deSAlexey Dobriyan static const struct super_operations btrfs_super_ops = { 234676dda93cSYan, Zheng .drop_inode = btrfs_drop_inode, 2347bd555975SAl Viro .evict_inode = btrfs_evict_inode, 2348e20d96d6SChris Mason .put_super = btrfs_put_super, 2349d5719762SChris Mason .sync_fs = btrfs_sync_fs, 2350a9572a15SEric Paris .show_options = btrfs_show_options, 23519c5085c1SJosef Bacik .show_devname = btrfs_show_devname, 23522c90e5d6SChris Mason .alloc_inode = btrfs_alloc_inode, 23532c90e5d6SChris Mason .destroy_inode = btrfs_destroy_inode, 235426602cabSAl Viro .free_inode = btrfs_free_inode, 23558fd17795SChris Mason .statfs = btrfs_statfs, 2356c146afadSYan Zheng .remount_fs = btrfs_remount, 23570176260fSLinus Torvalds .freeze_fs = btrfs_freeze, 23589e7cc91aSWang Xiaoguang .unfreeze_fs = btrfs_unfreeze, 2359e20d96d6SChris Mason }; 2360a9218f6bSChris Mason 2361a9218f6bSChris Mason static const struct file_operations btrfs_ctl_fops = { 2362d8620958STom Van Braeckel .open = btrfs_control_open, 2363a9218f6bSChris Mason .unlocked_ioctl = btrfs_control_ioctl, 23641832f2d8SArnd Bergmann .compat_ioctl = compat_ptr_ioctl, 2365a9218f6bSChris Mason .owner = THIS_MODULE, 23666038f373SArnd Bergmann .llseek = noop_llseek, 2367a9218f6bSChris Mason }; 2368a9218f6bSChris Mason 2369a9218f6bSChris Mason static struct miscdevice btrfs_misc = { 2370578454ffSKay Sievers .minor = BTRFS_MINOR, 2371a9218f6bSChris Mason .name = "btrfs-control", 2372a9218f6bSChris Mason .fops = &btrfs_ctl_fops 2373a9218f6bSChris Mason }; 2374a9218f6bSChris Mason 2375578454ffSKay Sievers MODULE_ALIAS_MISCDEV(BTRFS_MINOR); 2376578454ffSKay Sievers MODULE_ALIAS("devname:btrfs-control"); 2377578454ffSKay Sievers 2378f5c29bd9SLiu Bo static int __init btrfs_interface_init(void) 2379a9218f6bSChris Mason { 2380a9218f6bSChris Mason return misc_register(&btrfs_misc); 2381a9218f6bSChris Mason } 2382a9218f6bSChris Mason 2383e67c718bSDavid Sterba static __cold void btrfs_interface_exit(void) 2384a9218f6bSChris Mason { 2385f368ed60SGreg Kroah-Hartman misc_deregister(&btrfs_misc); 2386a9218f6bSChris Mason } 2387a9218f6bSChris Mason 23885565b8e0SQu Wenruo static int __init btrfs_print_mod_info(void) 238985965600SDavid Sterba { 2390edf57cbfSBart Van Assche static const char options[] = "" 239185965600SDavid Sterba #ifdef CONFIG_BTRFS_DEBUG 239285965600SDavid Sterba ", debug=on" 239385965600SDavid Sterba #endif 239479556c3dSStefan Behrens #ifdef CONFIG_BTRFS_ASSERT 239579556c3dSStefan Behrens ", assert=on" 239679556c3dSStefan Behrens #endif 239785965600SDavid Sterba #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY 239885965600SDavid Sterba ", integrity-checker=on" 239985965600SDavid Sterba #endif 2400fb592373SJosef Bacik #ifdef CONFIG_BTRFS_FS_REF_VERIFY 2401fb592373SJosef Bacik ", ref-verify=on" 2402fb592373SJosef Bacik #endif 24035b316468SNaohiro Aota #ifdef CONFIG_BLK_DEV_ZONED 24045b316468SNaohiro Aota ", zoned=yes" 24055b316468SNaohiro Aota #else 24065b316468SNaohiro Aota ", zoned=no" 24075b316468SNaohiro Aota #endif 2408ea3dc7d2SDavid Sterba #ifdef CONFIG_FS_VERITY 2409ea3dc7d2SDavid Sterba ", fsverity=yes" 2410ea3dc7d2SDavid Sterba #else 2411ea3dc7d2SDavid Sterba ", fsverity=no" 2412ea3dc7d2SDavid Sterba #endif 2413edf57cbfSBart Van Assche ; 2414edf57cbfSBart Van Assche pr_info("Btrfs loaded, crc32c=%s%s\n", crc32c_impl(), options); 24155565b8e0SQu Wenruo return 0; 24165565b8e0SQu Wenruo } 24175565b8e0SQu Wenruo 24185565b8e0SQu Wenruo static int register_btrfs(void) 24195565b8e0SQu Wenruo { 24205565b8e0SQu Wenruo return register_filesystem(&btrfs_fs_type); 24215565b8e0SQu Wenruo } 24225565b8e0SQu Wenruo 24235565b8e0SQu Wenruo static void unregister_btrfs(void) 24245565b8e0SQu Wenruo { 24255565b8e0SQu Wenruo unregister_filesystem(&btrfs_fs_type); 24265565b8e0SQu Wenruo } 24275565b8e0SQu Wenruo 24285565b8e0SQu Wenruo /* Helper structure for long init/exit functions. */ 24295565b8e0SQu Wenruo struct init_sequence { 24305565b8e0SQu Wenruo int (*init_func)(void); 24315565b8e0SQu Wenruo /* Can be NULL if the init_func doesn't need cleanup. */ 24325565b8e0SQu Wenruo void (*exit_func)(void); 24335565b8e0SQu Wenruo }; 24345565b8e0SQu Wenruo 24355565b8e0SQu Wenruo static const struct init_sequence mod_init_seq[] = { 24365565b8e0SQu Wenruo { 24375565b8e0SQu Wenruo .init_func = btrfs_props_init, 24385565b8e0SQu Wenruo .exit_func = NULL, 24395565b8e0SQu Wenruo }, { 24405565b8e0SQu Wenruo .init_func = btrfs_init_sysfs, 24415565b8e0SQu Wenruo .exit_func = btrfs_exit_sysfs, 24425565b8e0SQu Wenruo }, { 24435565b8e0SQu Wenruo .init_func = btrfs_init_compress, 24445565b8e0SQu Wenruo .exit_func = btrfs_exit_compress, 24455565b8e0SQu Wenruo }, { 24465565b8e0SQu Wenruo .init_func = btrfs_init_cachep, 24475565b8e0SQu Wenruo .exit_func = btrfs_destroy_cachep, 24485565b8e0SQu Wenruo }, { 24495565b8e0SQu Wenruo .init_func = btrfs_transaction_init, 24505565b8e0SQu Wenruo .exit_func = btrfs_transaction_exit, 24515565b8e0SQu Wenruo }, { 24525565b8e0SQu Wenruo .init_func = btrfs_ctree_init, 24535565b8e0SQu Wenruo .exit_func = btrfs_ctree_exit, 24545565b8e0SQu Wenruo }, { 24555565b8e0SQu Wenruo .init_func = btrfs_free_space_init, 24565565b8e0SQu Wenruo .exit_func = btrfs_free_space_exit, 24575565b8e0SQu Wenruo }, { 24585565b8e0SQu Wenruo .init_func = extent_state_init_cachep, 24595565b8e0SQu Wenruo .exit_func = extent_state_free_cachep, 24605565b8e0SQu Wenruo }, { 24615565b8e0SQu Wenruo .init_func = extent_buffer_init_cachep, 24625565b8e0SQu Wenruo .exit_func = extent_buffer_free_cachep, 24635565b8e0SQu Wenruo }, { 24645565b8e0SQu Wenruo .init_func = btrfs_bioset_init, 24655565b8e0SQu Wenruo .exit_func = btrfs_bioset_exit, 24665565b8e0SQu Wenruo }, { 24675565b8e0SQu Wenruo .init_func = extent_map_init, 24685565b8e0SQu Wenruo .exit_func = extent_map_exit, 24695565b8e0SQu Wenruo }, { 24705565b8e0SQu Wenruo .init_func = ordered_data_init, 24715565b8e0SQu Wenruo .exit_func = ordered_data_exit, 24725565b8e0SQu Wenruo }, { 24735565b8e0SQu Wenruo .init_func = btrfs_delayed_inode_init, 24745565b8e0SQu Wenruo .exit_func = btrfs_delayed_inode_exit, 24755565b8e0SQu Wenruo }, { 24765565b8e0SQu Wenruo .init_func = btrfs_auto_defrag_init, 24775565b8e0SQu Wenruo .exit_func = btrfs_auto_defrag_exit, 24785565b8e0SQu Wenruo }, { 24795565b8e0SQu Wenruo .init_func = btrfs_delayed_ref_init, 24805565b8e0SQu Wenruo .exit_func = btrfs_delayed_ref_exit, 24815565b8e0SQu Wenruo }, { 24825565b8e0SQu Wenruo .init_func = btrfs_prelim_ref_init, 24835565b8e0SQu Wenruo .exit_func = btrfs_prelim_ref_exit, 24845565b8e0SQu Wenruo }, { 24855565b8e0SQu Wenruo .init_func = btrfs_interface_init, 24865565b8e0SQu Wenruo .exit_func = btrfs_interface_exit, 24875565b8e0SQu Wenruo }, { 24885565b8e0SQu Wenruo .init_func = btrfs_print_mod_info, 24895565b8e0SQu Wenruo .exit_func = NULL, 24905565b8e0SQu Wenruo }, { 24915565b8e0SQu Wenruo .init_func = btrfs_run_sanity_tests, 24925565b8e0SQu Wenruo .exit_func = NULL, 24935565b8e0SQu Wenruo }, { 24945565b8e0SQu Wenruo .init_func = register_btrfs, 24955565b8e0SQu Wenruo .exit_func = unregister_btrfs, 24965565b8e0SQu Wenruo } 24975565b8e0SQu Wenruo }; 24985565b8e0SQu Wenruo 24995565b8e0SQu Wenruo static bool mod_init_result[ARRAY_SIZE(mod_init_seq)]; 25005565b8e0SQu Wenruo 250182c0efd3SAnand Jain static __always_inline void btrfs_exit_btrfs_fs(void) 25025565b8e0SQu Wenruo { 25035565b8e0SQu Wenruo int i; 25045565b8e0SQu Wenruo 25055565b8e0SQu Wenruo for (i = ARRAY_SIZE(mod_init_seq) - 1; i >= 0; i--) { 25065565b8e0SQu Wenruo if (!mod_init_result[i]) 25075565b8e0SQu Wenruo continue; 25085565b8e0SQu Wenruo if (mod_init_seq[i].exit_func) 25095565b8e0SQu Wenruo mod_init_seq[i].exit_func(); 25105565b8e0SQu Wenruo mod_init_result[i] = false; 25115565b8e0SQu Wenruo } 251285965600SDavid Sterba } 251385965600SDavid Sterba 251482c0efd3SAnand Jain static void __exit exit_btrfs_fs(void) 251582c0efd3SAnand Jain { 251682c0efd3SAnand Jain btrfs_exit_btrfs_fs(); 2517*c68f7290SFilipe Manana btrfs_cleanup_fs_uuids(); 251882c0efd3SAnand Jain } 251982c0efd3SAnand Jain 25202e635a27SChris Mason static int __init init_btrfs_fs(void) 25212e635a27SChris Mason { 25225565b8e0SQu Wenruo int ret; 25235565b8e0SQu Wenruo int i; 252458176a96SJosef Bacik 25255565b8e0SQu Wenruo for (i = 0; i < ARRAY_SIZE(mod_init_seq); i++) { 25265565b8e0SQu Wenruo ASSERT(!mod_init_result[i]); 25275565b8e0SQu Wenruo ret = mod_init_seq[i].init_func(); 252882c0efd3SAnand Jain if (ret < 0) { 252982c0efd3SAnand Jain btrfs_exit_btrfs_fs(); 253082c0efd3SAnand Jain return ret; 253182c0efd3SAnand Jain } 25325565b8e0SQu Wenruo mod_init_result[i] = true; 25335565b8e0SQu Wenruo } 25342f4cbe64SWyatt Banks return 0; 25352e635a27SChris Mason } 25362e635a27SChris Mason 253760efa5ebSFilipe David Borba Manana late_initcall(init_btrfs_fs); 25382e635a27SChris Mason module_exit(exit_btrfs_fs) 25392e635a27SChris Mason 25402e635a27SChris Mason MODULE_LICENSE("GPL"); 2541d5178578SJohannes Thumshirn MODULE_SOFTDEP("pre: crc32c"); 25423951e7f0SJohannes Thumshirn MODULE_SOFTDEP("pre: xxhash64"); 25433831bf00SJohannes Thumshirn MODULE_SOFTDEP("pre: sha256"); 2544352ae07bSDavid Sterba MODULE_SOFTDEP("pre: blake2b-256"); 2545