From patchwork Wed Aug 12 16:36:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcos Paulo de Souza X-Patchwork-Id: 11711045 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E2AAA138C for ; Wed, 12 Aug 2020 17:02:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C875E20774 for ; Wed, 12 Aug 2020 17:02:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=mpdesouza.com header.i=@mpdesouza.com header.b="D+kVlanr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726518AbgHLRCI (ORCPT ); Wed, 12 Aug 2020 13:02:08 -0400 Received: from gateway34.websitewelcome.com ([192.185.149.222]:20837 "EHLO gateway34.websitewelcome.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726503AbgHLRCH (ORCPT ); Wed, 12 Aug 2020 13:02:07 -0400 X-Greylist: delayed 1488 seconds by postgrey-1.27 at vger.kernel.org; Wed, 12 Aug 2020 13:02:06 EDT Received: from cm14.websitewelcome.com (cm14.websitewelcome.com [100.42.49.7]) by gateway34.websitewelcome.com (Postfix) with ESMTP id E311913044E9 for ; Wed, 12 Aug 2020 11:37:14 -0500 (CDT) Received: from br540.hostgator.com.br ([108.179.252.180]) by cmsmtp with SMTP id 5tkYk2dcIBD8b5tkYkankf; Wed, 12 Aug 2020 11:37:14 -0500 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mpdesouza.com; s=default; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=pO77dVds1g9gtkb3TWWO4PVsOHRc//6M3zgKr1rAC04=; b=D+kVlanrCxqvyWgGb5EDeChJzQ RpifXx5/cuOURJt+JQ1+QTmXN2fQKBrgVau4W0nt18VAe8J/Sv8KxSOwdKzpSpzwl7ddwPUYmQN+h BwlqsUtizSQWArrVp9SlQHVqF40ZAkBV6OzuylsZaYX6nkS+TeTh5FE5Wck6NhnIwMjQy74+HNV3Z q0LcQCc+y+tGt1P2ByVWfEJNgrOFb4dXp4h+QzMkCnOB6U68x3lATNNuNuY65DJBnYkqjN88w439c zLFDVgsNAHaWPJf2rMBGS+zx7iW54Ct/fvch3IdtJkQLHFiTiPx8arS6loP1j9PKLdvQ3sV5z9H2T nq8lNKpw==; Received: from [179.185.221.211] (port=55300 helo=hephaestus.suse.de) by br540.hostgator.com.br with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1k5tkY-004J9r-Ct; Wed, 12 Aug 2020 13:37:14 -0300 From: Marcos Paulo de Souza To: dsterba@suse.com, linux-btrfs@vger.kernel.org Cc: Marcos Paulo de Souza Subject: [RFC PATCH 1/8] btrfs: fs_context: Add initial fscontext parameters Date: Wed, 12 Aug 2020 13:36:47 -0300 Message-Id: <20200812163654.17080-2-marcos@mpdesouza.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812163654.17080-1-marcos@mpdesouza.com> References: <20200812163654.17080-1-marcos@mpdesouza.com> MIME-Version: 1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - br540.hostgator.com.br X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - mpdesouza.com X-BWhitelist: no X-Source-IP: 179.185.221.211 X-Source-L: No X-Exim-ID: 1k5tkY-004J9r-Ct X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: (hephaestus.suse.de) [179.185.221.211]:55300 X-Source-Auth: marcos@mpdesouza.com X-Email-Count: 5 X-Source-Cap: bXBkZXNvNTM7bXBkZXNvNTM7YnI1NDAuaG9zdGdhdG9yLmNvbS5icg== X-Local-Domain: yes Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Marcos Paulo de Souza The same old parameters but now using the fs_parameter_spec form. As the fscontext has a flag_no variant we don't need to map the Opt_no* version of the same flags. Opt_fragment is added as a generic entry point for all fragment type to be used only in fscontext argument parser. Signed-off-by: Marcos Paulo de Souza --- fs/btrfs/super.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 53639de3a064..4e6654af90ea 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -370,6 +371,7 @@ enum { Opt_check_integrity_print_mask, Opt_enospc_debug, Opt_noenospc_debug, #ifdef CONFIG_BTRFS_DEBUG + Opt_fragment, Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all, #endif #ifdef CONFIG_BTRFS_FS_REF_VERIFY @@ -458,6 +460,65 @@ static const match_table_t rescue_tokens = { {Opt_err, NULL}, }; +static const struct fs_parameter_spec btrfs_fs_parameters[] = { + fsparam_flag_no("acl", Opt_acl), + fsparam_flag_no("autodefrag", Opt_defrag), + fsparam_flag_no("barrier", Opt_barrier), + fsparam_flag("clear_cache", Opt_clear_cache), + fsparam_u32("commit", Opt_commit_interval), + fsparam_flag("compress", Opt_compress), + fsparam_string("compress", Opt_compress_type), + fsparam_flag("compress-force", Opt_compress_force), + fsparam_string("compress-force", Opt_compress_force_type), + fsparam_flag_no("datacow", Opt_datacow), + fsparam_flag_no("datasum", Opt_datasum), + fsparam_flag("degraded", Opt_degraded), + fsparam_string("device", Opt_device), + fsparam_flag_no("discard", Opt_discard), + fsparam_string("discard", Opt_discard_mode), + fsparam_string("fatal_errors", Opt_fatal_errors), + fsparam_flag_no("flushoncommit", Opt_flushoncommit), + fsparam_flag_no("inode_cache", Opt_inode_cache), + fsparam_string("max_inline", Opt_max_inline), + fsparam_u32("metadata_ratio", Opt_ratio), + fsparam_flag("norecovery", Opt_norecovery), + fsparam_flag("rescan_uuid_tree", Opt_rescan_uuid_tree), + fsparam_flag("skip_balance", Opt_skip_balance), + fsparam_flag_no("space_cache", Opt_space_cache), + fsparam_string("space_cache", Opt_space_cache_version), + fsparam_string("subvol", Opt_subvol), + fsparam_u64("subvolid", Opt_subvolid), + fsparam_flag_no("ssd", Opt_ssd), + fsparam_flag_no("ssd_spread", Opt_ssd_spread), + fsparam_u32("thread_pool", Opt_thread_pool), + fsparam_flag_no("treelog", Opt_treelog), + fsparam_flag("user_subvol_rm_allowed", Opt_user_subvol_rm_allowed), + + /* Debugging options */ + fsparam_flag("check_int", Opt_check_integrity), + fsparam_flag("check_int_data", Opt_check_integrity_including_extent_data), + fsparam_u32("check_int_print_mask", Opt_check_integrity_print_mask), + + /* Rescue options */ + fsparam_string("rescue", Opt_rescue), + /* Deprecated, with alias rescue=nologreplay */ + fsparam_flag("nologreplay", Opt_nologreplay), + /* Deprecated, with alias rescue=usebackuproot */ + fsparam_flag("usebackuproot", Opt_usebackuproot), + + /* Deprecated options */ + fsparam_flag("recovery", Opt_recovery), + fsparam_flag_no("enospc_debug", Opt_enospc_debug), + + #ifdef CONFIG_BTRFS_DEBUG + fsparam_string("fragment", Opt_fragment), + #endif + #ifdef CONFIG_BTRFS_FS_REF_VERIFY + fsparam_flag("ref_verify", Opt_ref_verify), + #endif + {} +}; + static int parse_rescue_options(struct btrfs_fs_info *info, const char *options) { char *opts; @@ -2269,6 +2330,7 @@ static struct file_system_type btrfs_fs_type = { .owner = THIS_MODULE, .name = "btrfs", .mount = btrfs_mount, + .parameters = btrfs_fs_parameters, .kill_sb = btrfs_kill_super, .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA, }; @@ -2277,6 +2339,7 @@ static struct file_system_type btrfs_root_fs_type = { .owner = THIS_MODULE, .name = "btrfs", .mount = btrfs_mount_root, + .parameters = btrfs_fs_parameters, .kill_sb = btrfs_kill_super, .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA, }; From patchwork Wed Aug 12 16:36:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcos Paulo de Souza X-Patchwork-Id: 11711041 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5526A138C for ; Wed, 12 Aug 2020 17:01:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3BC7320774 for ; Wed, 12 Aug 2020 17:01:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=mpdesouza.com header.i=@mpdesouza.com header.b="g5D95w/K" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726447AbgHLRBf (ORCPT ); Wed, 12 Aug 2020 13:01:35 -0400 Received: from gateway30.websitewelcome.com ([192.185.146.7]:49791 "EHLO gateway30.websitewelcome.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725872AbgHLRBd (ORCPT ); Wed, 12 Aug 2020 13:01:33 -0400 X-Greylist: delayed 1454 seconds by postgrey-1.27 at vger.kernel.org; Wed, 12 Aug 2020 13:01:32 EDT Received: from cm12.websitewelcome.com (cm12.websitewelcome.com [100.42.49.8]) by gateway30.websitewelcome.com (Postfix) with ESMTP id AFF4B1CE5C for ; Wed, 12 Aug 2020 11:37:16 -0500 (CDT) Received: from br540.hostgator.com.br ([108.179.252.180]) by cmsmtp with SMTP id 5tkakl2cVn9FW5tkakSgJj; Wed, 12 Aug 2020 11:37:16 -0500 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mpdesouza.com; s=default; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=UqG29ATigcmuwfC9sOjNO8C0MQBzUDF2ZiYms3j4BtU=; b=g5D95w/KV9Eqg6tt1ZjQtKOfM/ 6ioKmAh+ijy/2nTgvt35zjbwhNqurvQeTQ4t3KnaQTflG9U8X/srL+NiPCKNWQotTxOvDDXha7grV vMdd2q4sLKhMibGsKNjrh7gzNjHL0w+SBino5UChFACTGQecm4lRy2fpy8foun5bdjt7kG43ATVLp 36W85dne743S4Bwc+qzK0kcvamVRA1I94iGfH1hCAwfmBCp+BKXIRZpy3n07jEcHxdyoMdZJDNTfh N+pz6LQWWoGWwPDkt1khOEPk6z1T5q9qkJUndK08kFoNFwhS3i26G8D/zwFNa/YSRZq8BzZzRaXhb hS+R/wuA==; Received: from [179.185.221.211] (port=55300 helo=hephaestus.suse.de) by br540.hostgator.com.br with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1k5tkZ-004J9r-Pd; Wed, 12 Aug 2020 13:37:16 -0300 From: Marcos Paulo de Souza To: dsterba@suse.com, linux-btrfs@vger.kernel.org Cc: Marcos Paulo de Souza Subject: [RFC PATCH 2/8] btrfs: super: Introduce fs_context ops, init and free functions Date: Wed, 12 Aug 2020 13:36:48 -0300 Message-Id: <20200812163654.17080-3-marcos@mpdesouza.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812163654.17080-1-marcos@mpdesouza.com> References: <20200812163654.17080-1-marcos@mpdesouza.com> MIME-Version: 1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - br540.hostgator.com.br X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - mpdesouza.com X-BWhitelist: no X-Source-IP: 179.185.221.211 X-Source-L: No X-Exim-ID: 1k5tkZ-004J9r-Pd X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: (hephaestus.suse.de) [179.185.221.211]:55300 X-Source-Auth: marcos@mpdesouza.com X-Email-Count: 8 X-Source-Cap: bXBkZXNvNTM7bXBkZXNvNTM7YnI1NDAuaG9zdGdhdG9yLmNvbS5icg== X-Local-Domain: yes Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Marcos Paulo de Souza Create a btrfs_fs_context struct that will be used as fs_private between the fs context calls, holding options to be later assigned to fs_info, since we don't have a proper btrfs_fs_info at the parse_args phase. fs_context is still not being used since the init function isn't being assigned in btrfs_fs_type. Signed-off-by: Marcos Paulo de Souza --- fs/btrfs/ctree.h | 27 +++++++++++++++++++++++++++ fs/btrfs/super.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 9c7e466f27a9..b7e3962a0941 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -28,6 +28,7 @@ #include #include #include +#include "compression.h" #include "extent-io-tree.h" #include "extent_io.h" #include "extent_map.h" @@ -35,6 +36,32 @@ #include "block-rsv.h" #include "locking.h" +struct btrfs_fs_context { + char **devices; + char *subvol_name; + u64 subvolid; + + int nr_devices; + unsigned long mount_opt; + unsigned long mount_opt_explicity; + unsigned long pending_changes; + enum btrfs_compression_type compress_type; + unsigned int compress_level; + + u64 max_inline; + u32 metadata_ratio; + u32 thread_pool_size; + u32 commit_interval; +#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY + u32 check_integrity_print_mask; +#endif + + struct vfsmount *root_mnt; + bool root; + bool nospace_cache; + bool no_compress; +}; + struct btrfs_trans_handle; struct btrfs_transaction; struct btrfs_pending_snapshot; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 4e6654af90ea..fe19ffe962c6 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -2326,6 +2326,51 @@ static void btrfs_kill_super(struct super_block *sb) btrfs_free_fs_info(fs_info); } +static void btrfs_fc_free(struct fs_context *fc) +{ + struct btrfs_fs_context *ctx = fc->fs_private; + struct btrfs_fs_info *info = fc->s_fs_info; + + if (info) + btrfs_free_fs_info(info); + if (ctx) { + mntput(ctx->root_mnt); + if (ctx->devices) { + int i; + + for (i = 0; i < ctx->nr_devices; i++) + kfree(ctx->devices[i]); + kfree(ctx->devices); + } + kfree(ctx->subvol_name); + kfree(ctx); + } +} + +static const struct fs_context_operations btrfs_context_ops = { + .free = btrfs_fc_free, +}; + +static int btrfs_init_fs_context(struct fs_context *fc) +{ + struct btrfs_fs_context *ctx; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + /* currently default options */ + btrfs_set_opt(ctx->mount_opt, SPACE_CACHE); +#ifdef CONFIG_BTRFS_FS_POSIX_ACL + fc->sb_flags |= SB_POSIXACL; +#endif + ctx->commit_interval = BTRFS_DEFAULT_COMMIT_INTERVAL; + + fc->fs_private = ctx; + fc->ops = &btrfs_context_ops; + return 0; +} + static struct file_system_type btrfs_fs_type = { .owner = THIS_MODULE, .name = "btrfs", From patchwork Wed Aug 12 16:36:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcos Paulo de Souza X-Patchwork-Id: 11711051 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8E38013A4 for ; Wed, 12 Aug 2020 17:02:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 66EF020855 for ; Wed, 12 Aug 2020 17:02:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=mpdesouza.com header.i=@mpdesouza.com header.b="Qfl79ljy" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726660AbgHLRCS (ORCPT ); Wed, 12 Aug 2020 13:02:18 -0400 Received: from gateway34.websitewelcome.com ([192.185.149.222]:43488 "EHLO gateway34.websitewelcome.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726558AbgHLRCR (ORCPT ); Wed, 12 Aug 2020 13:02:17 -0400 Received: from cm14.websitewelcome.com (cm14.websitewelcome.com [100.42.49.7]) by gateway34.websitewelcome.com (Postfix) with ESMTP id 310EB1359C1A for ; Wed, 12 Aug 2020 11:37:18 -0500 (CDT) Received: from br540.hostgator.com.br ([108.179.252.180]) by cmsmtp with SMTP id 5tkbk2dfxBD8b5tkckanoU; Wed, 12 Aug 2020 11:37:18 -0500 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mpdesouza.com; s=default; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=2BMCy+0SbO7eVzsw1Y8+sDSJ6MFKuBG+3CNXULF3zus=; b=Qfl79ljySXPL5UkRHMTUT/JYB9 PL6uE6w0Wm+RqvDXnyWSJ55kvauVZG+h12jZ6/AThMABswWrUkFmCoFeiyH7TdD1oN2AGFDDCCsPQ of+3IW65tWNjknpRkZkDkexkBmg3xDGJBfOnlfOHPx9uR182Vbx/zTf8RAk+hu6OeR3jPPHaejDZ3 kEmP9ngBKfVe+FFYcrDzjPk6lyHCcjWpFY4IPLH/DEI43JNlD0b0hn+S/whJuoa1tMJTuECkqPwmk G6g/KGW167p1RbAWvU+xlroOzrOFz4XRoqmUZ5fLPMhIro1e1/8WyZy5Q9WeR0acPhFBvjcHhnCHc sjzh/MtA==; Received: from [179.185.221.211] (port=55300 helo=hephaestus.suse.de) by br540.hostgator.com.br with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1k5tkb-004J9r-2x; Wed, 12 Aug 2020 13:37:17 -0300 From: Marcos Paulo de Souza To: dsterba@suse.com, linux-btrfs@vger.kernel.org Cc: Marcos Paulo de Souza Subject: [RFC PATCH 3/8] btrfs: super: Introduce btrfs_fc_parse_param and btrfs_apply_configuration Date: Wed, 12 Aug 2020 13:36:49 -0300 Message-Id: <20200812163654.17080-4-marcos@mpdesouza.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812163654.17080-1-marcos@mpdesouza.com> References: <20200812163654.17080-1-marcos@mpdesouza.com> MIME-Version: 1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - br540.hostgator.com.br X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - mpdesouza.com X-BWhitelist: no X-Source-IP: 179.185.221.211 X-Source-L: No X-Exim-ID: 1k5tkb-004J9r-2x X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: (hephaestus.suse.de) [179.185.221.211]:55300 X-Source-Auth: marcos@mpdesouza.com X-Email-Count: 11 X-Source-Cap: bXBkZXNvNTM7bXBkZXNvNTM7YnI1NDAuaG9zdGdhdG9yLmNvbS5icg== X-Local-Domain: yes Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Marcos Paulo de Souza The first function will parse the arguments using the new fs_context API saving the arguments in btrfs_fs_context, while the second one populate the settings of btrfs_fs_info using the context previously set. Signed-off-by: Marcos Paulo de Souza --- fs/btrfs/ctree.h | 1 + fs/btrfs/super.c | 609 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 610 insertions(+) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index b7e3962a0941..d96bce2ea5bb 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3102,6 +3102,7 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, /* super.c */ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, unsigned long new_flags); +int btrfs_apply_configuration(struct fs_context *fc, struct super_block *sb); int btrfs_sync_fs(struct super_block *sb, int wait); char *btrfs_get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info, u64 subvol_objectid); diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index fe19ffe962c6..3425a77ecd57 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1051,6 +1051,394 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, return ret; } +struct btrfs_flag_map { + int bit; + bool enabled; +}; + +#define INIT_MAP(OPT) { BTRFS_MOUNT_##OPT, false } +#define btrfs_test_exp_opt(fs_info, opt) \ + ((fs_info)->mount_opt_explicity & BTRFS_MOUNT_##opt) + +/* Opt_err is the latest option */ +static struct btrfs_flag_map btrfs_opt_map[Opt_err] = { + [Opt_barrier] = INIT_MAP(NOBARRIER), + [Opt_check_integrity] = INIT_MAP(CHECK_INTEGRITY), + [Opt_check_integrity_including_extent_data] = + INIT_MAP(CHECK_INTEGRITY_INCLUDING_EXTENT_DATA), + [Opt_datacow] = INIT_MAP(NODATACOW), + [Opt_datasum] = INIT_MAP(NODATASUM), + [Opt_discard] = INIT_MAP(DISCARD_SYNC), + [Opt_defrag] = INIT_MAP(AUTO_DEFRAG), + [Opt_degraded] = INIT_MAP(DEGRADED), + [Opt_flushoncommit] = INIT_MAP(FLUSHONCOMMIT), + [Opt_inode_cache] = INIT_MAP(INODE_MAP_CACHE), + [Opt_nologreplay] = INIT_MAP(NOLOGREPLAY), + [Opt_ssd] = INIT_MAP(SSD), + [Opt_ssd_spread] = INIT_MAP(SSD_SPREAD), + [Opt_treelog] = INIT_MAP(NOTREELOG), + [Opt_ref_verify] = INIT_MAP(REF_VERIFY), +}; + +static int btrfs_fc_parse_param(struct fs_context *fc, struct fs_parameter *param) +{ + int opt; + char *compress_type; + char **devs; + bool compress_force = false; + enum btrfs_compression_type saved_compress_type; + bool saved_compress_force; + struct fs_parse_result result; + struct btrfs_fs_context *ctx = fc->fs_private; + + opt = fs_parse(fc, btrfs_fs_parameters, param, &result); + if (opt < 0) + return opt; + + /* + * Store the option parsed to avoid being too noisy in + * btrfs_apply_configuration. + */ + ctx->mount_opt_explicity |= btrfs_opt_map[opt].bit; + btrfs_opt_map[opt].enabled = !result.negated; + + switch (opt) { + case Opt_acl: + if (result.negated) { + fc->sb_flags &= ~SB_POSIXACL; + } else { +#ifndef CONFIG_BTRFS_FS_POSIX_ACL + return invalf(fc, "support for ACL not compiled in!"); +#else + fc->sb_flags |= SB_POSIXACL; +#endif + } + break; + case Opt_barrier: + if (result.negated) + btrfs_set_opt(ctx->mount_opt, NOBARRIER); + else + btrfs_clear_opt(ctx->mount_opt, NOBARRIER); + break; + case Opt_clear_cache: + btrfs_set_opt(ctx->mount_opt, CLEAR_CACHE); + break; + case Opt_commit_interval: + ctx->commit_interval = result.uint_32; + break; + case Opt_compress_force: + case Opt_compress_force_type: + compress_force = true; + fallthrough; + case Opt_compress: + case Opt_compress_type: + saved_compress_type = btrfs_test_opt(ctx, COMPRESS) ? + ctx->compress_type : BTRFS_COMPRESS_NONE; + saved_compress_force = + btrfs_test_opt(ctx, FORCE_COMPRESS); + if (opt == Opt_compress || + opt == Opt_compress_force || + strncmp(param->string, "zlib", 4) == 0) { + compress_type = "zlib"; + + ctx->compress_type = BTRFS_COMPRESS_ZLIB; + ctx->compress_level = BTRFS_ZLIB_DEFAULT_LEVEL; + /* + * param->string contains uninitialized data since + * for these options we don't expect any + * parameter. + */ + if (opt != Opt_compress && + opt != Opt_compress_force) + ctx->compress_level = + btrfs_compress_str2level( + BTRFS_COMPRESS_ZLIB, + param->string + 4); + btrfs_set_opt(ctx->mount_opt, COMPRESS); + btrfs_clear_opt(ctx->mount_opt, NODATACOW); + btrfs_clear_opt(ctx->mount_opt, NODATASUM); + ctx->no_compress = false; + } else if (strncmp(param->string, "lzo", 3) == 0) { + compress_type = "lzo"; + ctx->compress_type = BTRFS_COMPRESS_LZO; + /* btrfs does not exposes lzo compression levels */ + ctx->compress_level = 0; + btrfs_set_opt(ctx->mount_opt, COMPRESS); + btrfs_clear_opt(ctx->mount_opt, NODATACOW); + btrfs_clear_opt(ctx->mount_opt, NODATASUM); + ctx->no_compress = false; + } else if (strncmp(param->string, "zstd", 4) == 0) { + compress_type = "zstd"; + ctx->compress_type = BTRFS_COMPRESS_ZSTD; + ctx->compress_level = + btrfs_compress_str2level( + BTRFS_COMPRESS_ZSTD, + param->string + 4); + btrfs_set_opt(ctx->mount_opt, COMPRESS); + btrfs_clear_opt(ctx->mount_opt, NODATACOW); + btrfs_clear_opt(ctx->mount_opt, NODATASUM); + ctx->no_compress = false; + } else if (strncmp(param->string, "no", 2) == 0) { + compress_type = "no"; + ctx->compress_level = 0; + btrfs_clear_opt(ctx->mount_opt, COMPRESS); + btrfs_clear_opt(ctx->mount_opt, FORCE_COMPRESS); + compress_force = false; + ctx->no_compress = true; + } else { + return invalf(fc, "Invalid compression option: %s", + param->string); + } + + if (compress_force) { + btrfs_set_opt(ctx->mount_opt, FORCE_COMPRESS); + } else { + /* + * If we reconfigure from compress-force=xxx to + * compress=xxx, we need clear FORCE_COMPRESS + * flag, otherwise, there is no way for users + * to disable forcible compression separately. + */ + btrfs_clear_opt(ctx->mount_opt, FORCE_COMPRESS); + } + break; + case Opt_degraded: + btrfs_set_opt(ctx->mount_opt, DEGRADED); + break; + case Opt_device: + devs = krealloc(ctx->devices, + sizeof(char *) * (ctx->nr_devices + 1), + GFP_KERNEL); + if (!devs) + return -ENOMEM; + devs[ctx->nr_devices] = param->string; + param->string = NULL; + ctx->devices = devs; + ctx->nr_devices++; + break; + case Opt_datacow: + if (result.negated) { + btrfs_clear_opt(ctx->mount_opt, COMPRESS); + btrfs_clear_opt(ctx->mount_opt, FORCE_COMPRESS); + btrfs_set_opt(ctx->mount_opt, NODATACOW); + btrfs_set_opt(ctx->mount_opt, NODATASUM); + } else { + btrfs_clear_opt(ctx->mount_opt, NODATACOW); + } + break; + case Opt_datasum: + if (result.negated) { + btrfs_set_opt(ctx->mount_opt, NODATASUM); + } else { + btrfs_clear_opt(ctx->mount_opt, NODATACOW); + btrfs_clear_opt(ctx->mount_opt, NODATASUM); + } + break; + case Opt_defrag: + if (result.negated) + btrfs_clear_opt(ctx->mount_opt, AUTO_DEFRAG); + else + btrfs_set_opt(ctx->mount_opt, AUTO_DEFRAG); + break; + case Opt_discard: + if (result.negated) { + btrfs_clear_opt(ctx->mount_opt, DISCARD_SYNC); + btrfs_clear_opt(ctx->mount_opt, DISCARD_ASYNC); + } else { + btrfs_clear_opt(ctx->mount_opt, DISCARD_ASYNC); + btrfs_set_opt(ctx->mount_opt, DISCARD_SYNC); + } + break; + case Opt_discard_mode: + if (strcmp(param->string, "sync") == 0) { + btrfs_clear_opt(ctx->mount_opt, DISCARD_ASYNC); + btrfs_set_opt(ctx->mount_opt, DISCARD_SYNC); + } else if (strcmp(param->string, "async") == 0) { + btrfs_clear_opt(ctx->mount_opt, DISCARD_SYNC); + btrfs_set_opt(ctx->mount_opt, DISCARD_ASYNC); + } else { + return invalf(fc, "Invalid discard mode: %s", + param->string); + } + break; + case Opt_enospc_debug: + if (result.negated) + btrfs_clear_opt(ctx->mount_opt, ENOSPC_DEBUG); + else + btrfs_set_opt(ctx->mount_opt, ENOSPC_DEBUG); + break; + case Opt_fatal_errors: + if (strcmp(param->string, "panic") == 0) + btrfs_set_opt(ctx->mount_opt, PANIC_ON_FATAL_ERROR); + else if (strcmp(param->string, "bug") == 0) + btrfs_clear_opt(ctx->mount_opt, PANIC_ON_FATAL_ERROR); + else + return invalf(fc, "Invalid fatal_errors option: %s", + param->string); + break; + case Opt_flushoncommit: + if (result.negated) + btrfs_clear_opt(ctx->mount_opt, FLUSHONCOMMIT); + else + btrfs_set_opt(ctx->mount_opt, FLUSHONCOMMIT); + break; +#ifdef CONFIG_BTRFS_DEBUG + case Opt_fragment: + if (strcmp(param->string, "all") == 0) { + btrfs_set_opt(ctx->mount_opt, FRAGMENT_DATA); + btrfs_set_opt(ctx->mount_opt, FRAGMENT_METADATA); + } else if (strcmp(param->string, "metadata") == 0) { + btrfs_set_opt(ctx->mount_opt, FRAGMENT_METADATA); + } else if (strcmp(param->string, "data") == 0) { + btrfs_set_opt(ctx->mount_opt, FRAGMENT_DATA); + } else { + return invalf(fc, "Invalid fragment option: %s", + param->string); + } + break; +#endif +#ifdef CONFIG_BTRFS_FS_REF_VERIFY + case Opt_ref_verify: + btrfs_set_opt(ctx->mount_opt, REF_VERIFY); + break; +#endif + case Opt_inode_cache: + /* handled in btrfs_apply_configuration */ + break; + case Opt_max_inline: + ctx->max_inline = memparse(param->string, NULL); + break; + case Opt_norecovery: + case Opt_nologreplay: + warnf(fc, "'%s' is deprecated, use 'rescue=nologreplay' instead", + opt == Opt_norecovery ? "norecovery" + : "nologreplay"); + btrfs_set_opt(ctx->mount_opt, NOLOGREPLAY); + break; + case Opt_ratio: + ctx->metadata_ratio = result.uint_32; + break; + case Opt_rescue: + if (strcmp(param->string, "usebackuproot") == 0) { + btrfs_set_opt(ctx->mount_opt, USEBACKUPROOT); + } else if (strcmp(param->string, "nologreplay") == 0) { + btrfs_set_opt(ctx->mount_opt, NOLOGREPLAY); + } else { + return invalf(fc, "unrecognized rescue option '%s'", + param->string); + } + break; + case Opt_skip_balance: + btrfs_set_opt(ctx->mount_opt, SKIP_BALANCE); + break; + case Opt_rescan_uuid_tree: + btrfs_set_opt(ctx->mount_opt, RESCAN_UUID_TREE); + break; + case Opt_space_cache: + if (result.negated) { + if (btrfs_test_opt(ctx, SPACE_CACHE)) + btrfs_clear_opt(ctx->mount_opt, SPACE_CACHE); + if (btrfs_test_opt(ctx, FREE_SPACE_TREE)) + btrfs_clear_opt(ctx->mount_opt, FREE_SPACE_TREE); + ctx->nospace_cache = true; + } else { + btrfs_clear_opt(ctx->mount_opt, FREE_SPACE_TREE); + btrfs_set_opt(ctx->mount_opt, SPACE_CACHE); + ctx->nospace_cache = false; + } + break; + case Opt_space_cache_version: + ctx->nospace_cache = false; + if (strcmp(param->string, "v1") == 0) { + btrfs_clear_opt(ctx->mount_opt, FREE_SPACE_TREE); + btrfs_set_opt(ctx->mount_opt, SPACE_CACHE); + } else if (strcmp(param->string, "v2") == 0) { + btrfs_clear_opt(ctx->mount_opt, SPACE_CACHE); + btrfs_set_opt(ctx->mount_opt, FREE_SPACE_TREE); + } else { + return invalf(fc, "Invalid space_cache version: %s", + param->string); + } + break; + case Opt_ssd: + if (result.negated) { + btrfs_set_opt(ctx->mount_opt, NOSSD); + btrfs_clear_opt(ctx->mount_opt, SSD); + btrfs_clear_opt(ctx->mount_opt, SSD_SPREAD); + } else { + btrfs_clear_opt(ctx->mount_opt, NOSSD); + btrfs_set_opt(ctx->mount_opt, SSD); + } + break; + case Opt_ssd_spread: + if (result.negated) { + btrfs_clear_opt(ctx->mount_opt, SSD_SPREAD); + } else { + btrfs_set_opt(ctx->mount_opt, SSD); + btrfs_set_opt(ctx->mount_opt, SSD_SPREAD); + btrfs_clear_opt(ctx->mount_opt, NOSSD); + } + break; + case Opt_subvol: + kfree(ctx->subvol_name); + ctx->subvol_name = param->string; + param->string = NULL; + break; + case Opt_subvolid: + ctx->subvolid = result.uint_64; + + /* we want the original fs_tree */ + if (ctx->subvolid == 0) + ctx->subvolid = BTRFS_FS_TREE_OBJECTID; + break; + case Opt_thread_pool: + if (result.uint_32 == 0) + return invalf(fc, "Invalid thread_pool value: 0"); + + ctx->thread_pool_size = result.uint_32; + break; + case Opt_treelog: + if (result.negated) + btrfs_set_opt(ctx->mount_opt, NOTREELOG); + else + btrfs_clear_opt(ctx->mount_opt, NOTREELOG); + break; +#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY + case Opt_check_integrity_including_extent_data: + btrfs_set_opt(ctx->mount_opt, + CHECK_INTEGRITY_INCLUDING_EXTENT_DATA); + btrfs_set_opt(ctx->mount_opt, CHECK_INTEGRITY); + break; + case Opt_check_integrity: + btrfs_set_opt(ctx->mount_opt, CHECK_INTEGRITY); + break; + case Opt_check_integrity_print_mask: + ctx->check_integrity_print_mask = result.uint_32; + break; +#else + case Opt_check_integrity_including_extent_data: + case Opt_check_integrity: + case Opt_check_integrity_print_mask: + return invalf(fc, "support for check_integrity* not compiled in!"); +#endif + case Opt_user_subvol_rm_allowed: + btrfs_set_opt(ctx->mount_opt, USER_SUBVOL_RM_ALLOWED); + break; + case Opt_recovery: + fallthrough; + case Opt_usebackuproot: + warnf(fc, "'%s' is deprecated, use 'rescue=usebackuproot' instead", + opt == Opt_recovery ? "recovery" : + "usebackuproot"); + btrfs_set_opt(ctx->mount_opt, USEBACKUPROOT); + break; + default: + return invalf(fc, "Invalid mount option: %s", param->key); + } + + return 0; +} + /* * Parse mount options that are required early in the mount process. * @@ -1400,6 +1788,226 @@ static int btrfs_fill_super(struct super_block *sb, return err; } +int btrfs_apply_configuration(struct fs_context *fc, + struct super_block *sb) +{ + struct btrfs_fs_context *ctx = fc->fs_private; + struct btrfs_fs_info *info = sb->s_fs_info; + +#ifdef CONFIG_BTRFS_FS_POSIX_ACL + if (!(fc->sb_flags & SB_POSIXACL)) + sb->s_flags &= ~SB_POSIXACL; + else + sb->s_flags |= SB_POSIXACL; +#endif + + if (btrfs_test_exp_opt(ctx, NOBARRIER)) + btrfs_info(info, "turning %s barriers", + btrfs_opt_map[Opt_barrier].enabled ? "on" : "off"); + + if (btrfs_test_exp_opt(ctx, CLEAR_CACHE)) + btrfs_info(info, "force clearing of disk cache"); + + if (ctx->commit_interval == 0) { + btrfs_info(info, "using default commit interval %us", + BTRFS_DEFAULT_COMMIT_INTERVAL); + ctx->commit_interval = BTRFS_DEFAULT_COMMIT_INTERVAL; + } else if (ctx->commit_interval > 300) { + btrfs_warn(info, "excessive commit interval %d", + ctx->commit_interval); + } + info->commit_interval = ctx->commit_interval; + + if (btrfs_test_opt(ctx, COMPRESS) || ctx->no_compress) { + btrfs_info(info, "%s %s compression, level %d", + btrfs_test_opt(ctx, FORCE_COMPRESS) ? "force" : "use", + ctx->no_compress ? "no" + : btrfs_compress_type2str(ctx->compress_type), + ctx->compress_level); + + if (ctx->compress_type == BTRFS_COMPRESS_LZO) + btrfs_set_fs_incompat(info, COMPRESS_LZO); + else if (ctx->compress_type == BTRFS_COMPRESS_ZSTD) + btrfs_set_fs_incompat(info, COMPRESS_ZSTD); + } + + if (btrfs_test_exp_opt(ctx, DEGRADED)) + btrfs_info(info, "allowing degraded mounts"); + + if (btrfs_test_exp_opt(ctx, NODATACOW)) { + if (btrfs_opt_map[Opt_datacow].enabled) { + btrfs_info(info, "setting datacow"); + } else { + if (!btrfs_test_opt(ctx, COMPRESS) || + !btrfs_test_opt(ctx, FORCE_COMPRESS)) { + btrfs_info(info, "setting nodatacow, compression disabled"); + } else { + btrfs_info(info, "setting nodatacow"); + } + } + } + + if (btrfs_test_exp_opt(ctx, NODATASUM)) { + if (!btrfs_opt_map[Opt_datasum].enabled) { + btrfs_info(info, "setting nodatasum"); + } else { + if (btrfs_test_opt(ctx, NODATASUM)) { + if (btrfs_test_opt(ctx, NODATACOW)) + btrfs_info(info, "setting datasum, datacow enabled"); + else + btrfs_info(info, "setting datasum"); + } + } + } + + if (btrfs_test_exp_opt(ctx, AUTO_DEFRAG)) + btrfs_info(info, "%s auto defrag", + btrfs_opt_map[Opt_barrier].enabled ? "enabling" + : "disabling"); + + if (btrfs_test_opt(ctx, DISCARD_ASYNC)) { + btrfs_info(info, "turning on async discard"); + } else if (btrfs_test_exp_opt(ctx, DISCARD_SYNC)) { + if (!btrfs_opt_map[Opt_discard].enabled) { + btrfs_info(info, "turning off discard"); + btrfs_info(info, "turning off async discard"); + } else { + btrfs_info(info, "turning on sync discard"); + } + } + + if (btrfs_test_exp_opt(ctx, FLUSHONCOMMIT)) + btrfs_info(info, "turning %s flush-on-commit", + btrfs_opt_map[Opt_flushoncommit].enabled ? "on" : "off"); + +#ifdef CONFIG_BTRFS_DEBUG + if (btrfs_test_opt(ctx, FRAGMENT_DATA) && btrfs_test_opt(ctx, FRAGMENT_METADATA)) + btrfs_info(info, "fragmenting all space"); + else if (btrfs_test_opt(ctx, FRAGMENT_METADATA)) + btrfs_info(info, "fragmenting metadata"); + else if (btrfs_test_opt(ctx, FRAGMENT_DATA)) + btrfs_info(info, "fragmenting data"); +#endif + +#ifdef CONFIG_BTRFS_FS_REF_VERIFY + if (btrfs_test_exp_opt(ctx, REF_VERIFY)) + btrfs_info(info, "doing ref verification"); +#endif + + if (btrfs_test_exp_opt(ctx, INODE_MAP_CACHE)) { + if (btrfs_opt_map[Opt_inode_cache].enabled) { + btrfs_clear_pending_and_info(info, INODE_MAP_CACHE, + "disabling inode map caching"); + } else { + btrfs_info(info, + "the 'inode_cache' option is deprecated and will have no effect from 5.11"); + btrfs_set_pending_and_info(info, INODE_MAP_CACHE, + "enabling inode map caching"); + } + } + + if (ctx->max_inline) { + ctx->max_inline = min_t(u64, ctx->max_inline, info->sectorsize); + if (ctx->max_inline != info->max_inline) + btrfs_info(info, "max_inline at %llu", ctx->max_inline); + info->max_inline = ctx->max_inline; + } + + if (btrfs_test_exp_opt(ctx, NOLOGREPLAY)) + btrfs_info(info, "disabling log replay at mount time"); + + info->metadata_ratio = ctx->metadata_ratio; + if (ctx->metadata_ratio) + btrfs_info(info, "Metadata ratio %u", ctx->metadata_ratio); + + if (btrfs_test_opt(ctx, USEBACKUPROOT)) + btrfs_info(info, "trying to use backup root at mount time"); + + /* set a default space_cache value if none was specified */ + if (!ctx->nospace_cache && !btrfs_test_opt(ctx, SPACE_CACHE) && + !btrfs_test_opt(ctx, FREE_SPACE_TREE)) { + if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE)) + btrfs_set_opt(ctx->mount_opt, FREE_SPACE_TREE); + else + btrfs_set_opt(ctx->mount_opt, SPACE_CACHE); + } + + if (ctx->nospace_cache) { + if (btrfs_test_opt(ctx, SPACE_CACHE)) + btrfs_info(info, "disabling disk space caching"); + if (btrfs_test_opt(ctx, FREE_SPACE_TREE)) + btrfs_info(info, "disabling free space tree"); + } else if (btrfs_test_opt(ctx, SPACE_CACHE)) { + btrfs_info(info, "enabling disk space caching"); + } else if (btrfs_test_opt(ctx, FREE_SPACE_TREE)) { + btrfs_info(info, "enabling free space tree"); + } + + /* + * When the free space tree is enabled: + * -o nospace_cache, -o space_cache=v1: error + * no options, -o space_cache=v2: keep using the free space tree + * -o clear_cache, -o clear_cache,space_cache=v2: clear and recreate the free space tree + * -o clear_cache,nospace_cache: clear the free space tree + * -o clear_cache,space_cache=v1: clear the free space tree, enable the free space cache + */ + if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE)) { + bool opt_clear = btrfs_test_opt(ctx, CLEAR_CACHE); + bool opt_cache_v1 = btrfs_test_opt(ctx, SPACE_CACHE); + bool no_space_cache = ctx->nospace_cache; + + if ((no_space_cache && !opt_clear) || (opt_cache_v1 && !opt_clear)) { + btrfs_err(info, "cannot disable free space tree XX"); + return -EINVAL; + } + } + + if (btrfs_test_exp_opt(ctx, SSD_SPREAD)) { + if (!btrfs_opt_map[Opt_ssd_spread].enabled) { + btrfs_info(info, "not using spread ssd allocation scheme"); + } else { + btrfs_info(info, "enabling ssd optimizations"); + btrfs_info(info, "using spread ssd allocation scheme"); + } + } + + if (btrfs_test_exp_opt(ctx, SSD)) { + if (!btrfs_opt_map[Opt_ssd].enabled) { + btrfs_info(info, "not using ssd optimizations"); + btrfs_info(info, "not using spread ssd allocation scheme"); + } else { + btrfs_info(info, "enabling ssd optimizations"); + } + } + + if (ctx->thread_pool_size) + info->thread_pool_size = ctx->thread_pool_size; + + if (btrfs_test_exp_opt(ctx, NOTREELOG)) + btrfs_info(info, "%s tree log", + btrfs_opt_map[Opt_notreelog].enabled ? "enabling" + : "disabling"); + +#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY + if (btrfs_test_exp_opt(ctx, CHECK_INTEGRITY_INCLUDING_EXTENT_DATA)) + btrfs_info(info, "disabling log replay at mount time"); + else if (btrfs_test_exp_opt(ctx, CHECK_INTEGRITY)) + btrfs_info(info, "enabling check integrity"); + if (ctx->check_integrity_print_mask != info->check_integrity_print_mask) { + info->check_integrity_print_mask = ctx->check_integrity_print_mask; + btrfs_info(info, "check_integrity_print_mask 0x%x", + info->check_integrity_print_mask); + } +#endif + + info->compress_type = ctx->compress_type; + info->compress_level = ctx->compress_level; + info->pending_changes = ctx->pending_changes; + info->mount_opt = ctx->mount_opt; + + return 0; +} + int btrfs_sync_fs(struct super_block *sb, int wait) { struct btrfs_trans_handle *trans; @@ -2349,6 +2957,7 @@ static void btrfs_fc_free(struct fs_context *fc) static const struct fs_context_operations btrfs_context_ops = { .free = btrfs_fc_free, + .parse_param = btrfs_fc_parse_param, }; static int btrfs_init_fs_context(struct fs_context *fc) From patchwork Wed Aug 12 16:36:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcos Paulo de Souza X-Patchwork-Id: 11711037 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AC4851392 for ; Wed, 12 Aug 2020 16:59:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6E57020855 for ; Wed, 12 Aug 2020 16:59:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=mpdesouza.com header.i=@mpdesouza.com header.b="mzrj0UUI" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726558AbgHLQ7x (ORCPT ); Wed, 12 Aug 2020 12:59:53 -0400 Received: from gateway24.websitewelcome.com ([192.185.50.252]:42259 "EHLO gateway24.websitewelcome.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726526AbgHLQ7q (ORCPT ); Wed, 12 Aug 2020 12:59:46 -0400 Received: from cm10.websitewelcome.com (cm10.websitewelcome.com [100.42.49.4]) by gateway24.websitewelcome.com (Postfix) with ESMTP id 295906394 for ; Wed, 12 Aug 2020 11:37:19 -0500 (CDT) Received: from br540.hostgator.com.br ([108.179.252.180]) by cmsmtp with SMTP id 5tkdkxh8ALFNk5tkdkaVfX; Wed, 12 Aug 2020 11:37:19 -0500 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mpdesouza.com; s=default; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=Nz5hLOr319Knu6F+K422STnqvdJwNZ2qMiLxocCmbVE=; b=mzrj0UUI3UblmaA4gKwuta12/H hdQr2w/hAdlGmgxKkcxrOYhvy2ZWppKE0NdU2JAnxXJt8iU9n4IogFR4wR5IfqwBzHQuw73du3FQz 1ELgIqLPy2Gr3FIiBN2YPCdaL7PLQU4pUVXn7F6nCl8XgjOfF9m0WrHkV3dpN1pxPLK3wMmVowsdl x7GPoehY1aTjjt451SHtE+UZwwYGaYJjxRcWHrsGBHqpRa2OX1oIMgGgfIKNRoUudUVcJt6x0Gdcm xQf1l1Jr4izzHkHZ7C8SYbV+99ZoIkI0OdAJGJrcNjYDOLbQ3QFz1pTXCvRF82ridU59c4G+Bv6qy jbkncHgg==; Received: from [179.185.221.211] (port=55300 helo=hephaestus.suse.de) by br540.hostgator.com.br with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1k5tkc-004J9r-Fg; Wed, 12 Aug 2020 13:37:18 -0300 From: Marcos Paulo de Souza To: dsterba@suse.com, linux-btrfs@vger.kernel.org Cc: Marcos Paulo de Souza Subject: [RFC PATCH 4/8] btrfs: super: Introduce btrfs_fc_validate Date: Wed, 12 Aug 2020 13:36:50 -0300 Message-Id: <20200812163654.17080-5-marcos@mpdesouza.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812163654.17080-1-marcos@mpdesouza.com> References: <20200812163654.17080-1-marcos@mpdesouza.com> MIME-Version: 1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - br540.hostgator.com.br X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - mpdesouza.com X-BWhitelist: no X-Source-IP: 179.185.221.211 X-Source-L: No X-Exim-ID: 1k5tkc-004J9r-Fg X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: (hephaestus.suse.de) [179.185.221.211]:55300 X-Source-Auth: marcos@mpdesouza.com X-Email-Count: 14 X-Source-Cap: bXBkZXNvNTM7bXBkZXNvNTM7YnI1NDAuaG9zdGdhdG9yLmNvbS5icg== X-Local-Domain: yes Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Marcos Paulo de Souza This function will be used in later patches in get_tree and in remount to ensure that we don't mount btrfs using nologreplay with a writable fs. Signed-off-by: Marcos Paulo de Souza --- fs/btrfs/super.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 3425a77ecd57..88221d1d8bae 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1080,6 +1080,17 @@ static struct btrfs_flag_map btrfs_opt_map[Opt_err] = { [Opt_ref_verify] = INIT_MAP(REF_VERIFY), }; +static int btrfs_fc_validate(struct fs_context *fc) +{ + struct btrfs_fs_context *ctx = fc->fs_private; + + /* Check for current option against current flag */ + if (btrfs_test_opt(ctx, NOLOGREPLAY) && !(fc->sb_flags & SB_RDONLY)) + return invalf(fc, "nologreplay must be used with ro mount option"); + + return 0; +} + static int btrfs_fc_parse_param(struct fs_context *fc, struct fs_parameter *param) { int opt; From patchwork Wed Aug 12 16:36:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcos Paulo de Souza X-Patchwork-Id: 11711043 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DF6D813A4 for ; Wed, 12 Aug 2020 17:02:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C694220774 for ; Wed, 12 Aug 2020 17:02:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=mpdesouza.com header.i=@mpdesouza.com header.b="o2H1HLeg" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726554AbgHLRCJ (ORCPT ); Wed, 12 Aug 2020 13:02:09 -0400 Received: from gateway34.websitewelcome.com ([192.185.149.222]:15196 "EHLO gateway34.websitewelcome.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726456AbgHLRCI (ORCPT ); Wed, 12 Aug 2020 13:02:08 -0400 Received: from cm14.websitewelcome.com (cm14.websitewelcome.com [100.42.49.7]) by gateway34.websitewelcome.com (Postfix) with ESMTP id 871F5141D019 for ; Wed, 12 Aug 2020 11:37:20 -0500 (CDT) Received: from br540.hostgator.com.br ([108.179.252.180]) by cmsmtp with SMTP id 5tkek2djIBD8b5tkekanrh; Wed, 12 Aug 2020 11:37:20 -0500 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mpdesouza.com; s=default; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=vHbIM+Ja9pYEQy0JHmnFDv//pFqrdiLV1Cb3bZ9BJvo=; b=o2H1HLegYvQUz0CA36qVRT7MqA v/lssd2uAAMIz+xu93Q+kyMOqabwKyAcOoFGwwzvTZ+ABfG5rwlBHTEbFL03lbNax819J1M+90NRe RWK/VZaMiimRGcFBHgaIekN3GdgE/WebZ28Om/7U9oxlD2CB1WTD9YERNveKWc8wRm1rE7f928qQy 8qq2yMtlklWs5yCebAqRnIgVFBBWy4nvo2UMsH0XcCovtGi405hDjrP5BwRH0MyO2C/z31g8/h3cy IwHQLlRCSO4R81k6Ug69s5aIwXe5EW7JKHcgr2WQf7VIQcfN8XtjWCKjfN/YBSFm1vEp8fCfkUceq cy0mucXQ==; Received: from [179.185.221.211] (port=55300 helo=hephaestus.suse.de) by br540.hostgator.com.br with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1k5tkd-004J9r-PH; Wed, 12 Aug 2020 13:37:20 -0300 From: Marcos Paulo de Souza To: dsterba@suse.com, linux-btrfs@vger.kernel.org Cc: Marcos Paulo de Souza Subject: [RFC PATCH 5/8] btrfs: super: Introduce btrfs_dup_fc Date: Wed, 12 Aug 2020 13:36:51 -0300 Message-Id: <20200812163654.17080-6-marcos@mpdesouza.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812163654.17080-1-marcos@mpdesouza.com> References: <20200812163654.17080-1-marcos@mpdesouza.com> MIME-Version: 1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - br540.hostgator.com.br X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - mpdesouza.com X-BWhitelist: no X-Source-IP: 179.185.221.211 X-Source-L: No X-Exim-ID: 1k5tkd-004J9r-PH X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: (hephaestus.suse.de) [179.185.221.211]:55300 X-Source-Auth: marcos@mpdesouza.com X-Email-Count: 17 X-Source-Cap: bXBkZXNvNTM7bXBkZXNvNTM7YnI1NDAuaG9zdGdhdG9yLmNvbS5icg== X-Local-Domain: yes Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Marcos Paulo de Souza This function will be used in a future patch when mounting root filesystem before mounting a subvolume. Signed-off-by: Marcos Paulo de Souza --- fs/btrfs/super.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 88221d1d8bae..6b70fb73a1ea 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1091,6 +1091,56 @@ static int btrfs_fc_validate(struct fs_context *fc) return 0; } +static int btrfs_dup_fc(struct fs_context *fc, struct fs_context *src_fc) +{ + int i; + struct btrfs_fs_context *ctx, *src = src_fc->fs_private; + + ctx = kmemdup(src, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ctx->subvol_name = NULL; + ctx->devices = NULL; + ctx->root_mnt = NULL; + + if (src->subvol_name) { + ctx->subvol_name = kstrdup(src->subvol_name, GFP_KERNEL); + if (!ctx->subvol_name) + goto nomem_ctx; + } + + if (ctx->nr_devices) { + ctx->devices = kcalloc(ctx->nr_devices, sizeof(char *), GFP_KERNEL); + if (!ctx->devices) + goto nomem_sub; + for (i = 0; i < ctx->nr_devices; i++) { + ctx->devices[i] = kstrdup(src->devices[i], GFP_KERNEL); + if (!ctx->devices[i]) + goto nomem_devs; + } + } + + if (src_fc->source) { + fc->source = kstrdup(src_fc->source, GFP_KERNEL); + if (!fc->source) + goto nomem_devs; + } + + fc->fs_private = ctx; + return 0; + +nomem_devs: + for (i = 0; i < ctx->nr_devices; i++) + kfree(ctx->devices[i]); + kfree(ctx->devices); +nomem_sub: + kfree(ctx->subvol_name); +nomem_ctx: + kfree(ctx); + return -ENOMEM; +} + static int btrfs_fc_parse_param(struct fs_context *fc, struct fs_parameter *param) { int opt; @@ -2967,6 +3017,7 @@ static void btrfs_fc_free(struct fs_context *fc) } static const struct fs_context_operations btrfs_context_ops = { + .dup = btrfs_dup_fc, .free = btrfs_fc_free, .parse_param = btrfs_fc_parse_param, }; From patchwork Wed Aug 12 16:36:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcos Paulo de Souza X-Patchwork-Id: 11711049 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6C4B2138C for ; Wed, 12 Aug 2020 17:02:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 52A7B20774 for ; Wed, 12 Aug 2020 17:02:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=mpdesouza.com header.i=@mpdesouza.com header.b="Dpc0HZ2D" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726642AbgHLRCR (ORCPT ); Wed, 12 Aug 2020 13:02:17 -0400 Received: from gateway34.websitewelcome.com ([192.185.149.222]:13420 "EHLO gateway34.websitewelcome.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726477AbgHLRCP (ORCPT ); Wed, 12 Aug 2020 13:02:15 -0400 Received: from cm14.websitewelcome.com (cm14.websitewelcome.com [100.42.49.7]) by gateway34.websitewelcome.com (Postfix) with ESMTP id D6C9E142358C for ; Wed, 12 Aug 2020 11:37:21 -0500 (CDT) Received: from br540.hostgator.com.br ([108.179.252.180]) by cmsmtp with SMTP id 5tkfk2dkhBD8b5tkfkant7; Wed, 12 Aug 2020 11:37:21 -0500 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mpdesouza.com; s=default; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=ib1dxV5xpxWZvM9JalwRoCb+oYMm/ykxexGTVa+GOv4=; b=Dpc0HZ2DJFLWVc7IQFK45+kd+1 OgA+FIyp1MnxggbhkxAXx2Sp5evySVLwREfn7v1rHMAzbW8SGgRqVLElknpirK3JQkjI4/cOwKJ0g qibYz/9L53KWThdBa4nM30IW+7pvneP2vYjP+i59HokxTH5CgJZYRWTr+CQuJx5CIALPCtsWTEVQc iwc6tuF9pRIufehdWomNRR0cTG/u3nzK7KGCut4fI3oqB4TxmW80geWD64v2u561w5J4bVAuSk6Fc 0t3Bbwrpo/UlBUYFI89auw/m7dFp3hmJVcv72dIupmWgaxZFNiyPE1hxKzycRKaCdDhIqQ6RrXP/X XBLIc87g==; Received: from [179.185.221.211] (port=55300 helo=hephaestus.suse.de) by br540.hostgator.com.br with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1k5tkf-004J9r-3p; Wed, 12 Aug 2020 13:37:21 -0300 From: Marcos Paulo de Souza To: dsterba@suse.com, linux-btrfs@vger.kernel.org Cc: Marcos Paulo de Souza Subject: [RFC PATCH 6/8] btrfs: super: Introduce btrfs_mount_root_fc Date: Wed, 12 Aug 2020 13:36:52 -0300 Message-Id: <20200812163654.17080-7-marcos@mpdesouza.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812163654.17080-1-marcos@mpdesouza.com> References: <20200812163654.17080-1-marcos@mpdesouza.com> MIME-Version: 1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - br540.hostgator.com.br X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - mpdesouza.com X-BWhitelist: no X-Source-IP: 179.185.221.211 X-Source-L: No X-Exim-ID: 1k5tkf-004J9r-3p X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: (hephaestus.suse.de) [179.185.221.211]:55300 X-Source-Auth: marcos@mpdesouza.com X-Email-Count: 20 X-Source-Cap: bXBkZXNvNTM7bXBkZXNvNTM7YnI1NDAuaG9zdGdhdG9yLmNvbS5icg== X-Local-Domain: yes Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Marcos Paulo de Souza This function will be used by the following patches to mount the root fs before mounting a subvolume. Signed-off-by: Marcos Paulo de Souza --- fs/btrfs/super.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 6b70fb73a1ea..5bbf4b947125 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -2419,6 +2419,47 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, return ERR_PTR(error); } +/* + * Duplicate the current fc and prepare for mounting the root. + * btrfs_get_tree will be called recursively, but then will check for the + * ctx->root being set and call btrfs_root_get_tree. + */ +static int btrfs_mount_root_fc(struct fs_context *fc, unsigned int rdonly) +{ + struct btrfs_fs_context *ctx, *root_ctx; + struct fs_context *root_fc; + struct vfsmount *root_mnt; + int ret; + + root_fc = vfs_dup_fs_context(fc); + if (IS_ERR(root_fc)) + return PTR_ERR(root_fc); + + root_fc->sb_flags &= ~SB_RDONLY; + root_fc->sb_flags |= rdonly | SB_NOSEC; + root_ctx = root_fc->fs_private; + root_ctx->root_mnt = NULL; + root_ctx->root = true; + + /* + * fc_mount will call btrfs_get_tree again, and by checking ctx->root + * being true it'll call btrfs_root_get_tree to avoid infinite recursion. + */ + root_mnt = fc_mount(root_fc); + if (IS_ERR(root_mnt)) { + ret = PTR_ERR(root_mnt); + goto error_fc; + } + + ctx = fc->fs_private; + ctx->root_mnt = root_mnt; + ret = 0; + +error_fc: + put_fs_context(root_fc); + return ret; +} + /* * Mount function which is called by VFS layer. * From patchwork Wed Aug 12 16:36:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcos Paulo de Souza X-Patchwork-Id: 11711039 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D51071392 for ; Wed, 12 Aug 2020 16:59:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ADC6920855 for ; Wed, 12 Aug 2020 16:59:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=mpdesouza.com header.i=@mpdesouza.com header.b="Mgjo1jqk" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726596AbgHLQ7y (ORCPT ); Wed, 12 Aug 2020 12:59:54 -0400 Received: from gateway21.websitewelcome.com ([192.185.45.140]:39410 "EHLO gateway21.websitewelcome.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725872AbgHLQ7s (ORCPT ); Wed, 12 Aug 2020 12:59:48 -0400 X-Greylist: delayed 1339 seconds by postgrey-1.27 at vger.kernel.org; Wed, 12 Aug 2020 12:59:46 EDT Received: from cm10.websitewelcome.com (cm10.websitewelcome.com [100.42.49.4]) by gateway21.websitewelcome.com (Postfix) with ESMTP id 2F6AC400C558C for ; Wed, 12 Aug 2020 11:37:23 -0500 (CDT) Received: from br540.hostgator.com.br ([108.179.252.180]) by cmsmtp with SMTP id 5tkhkxhD8LFNk5tkhkaVkN; Wed, 12 Aug 2020 11:37:23 -0500 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mpdesouza.com; s=default; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=6FGHWWXb/MGjXq8U4VgD2UjQWH5uFdWjIYENLmVnFlw=; b=Mgjo1jqk4WdufPjC3IMfszB7+W or5u5k3u8vTakAXrXwGe4QKfTHdv4KpWIV/LVGda4pnLIzD2F/cRL+Yam2s1u7utRnr9QOA1ttMPb aZy/XVhxYAXjTX6sIdlZN+iV765dRNu2qY0ntpdhYKIXf+zdh0eXOFM6kGG7Ucico04wnDeUz/DIR BFDB58zE05hcK1Y/PSUS9WnT5Bkn0Lmoqg7AlS96eri7xC+1NWm50mlvWfF7bLFoZtmn0eU6TgPe1 jzMCyACpfrD+xRqKGEUHYemwH1qAiOniEaULZthNA6cmEGmNR5Npydm4s5DNA9TNMbuOKGcMgvo10 u17rdNpw==; Received: from [179.185.221.211] (port=55300 helo=hephaestus.suse.de) by br540.hostgator.com.br with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1k5tkg-004J9r-Ge; Wed, 12 Aug 2020 13:37:22 -0300 From: Marcos Paulo de Souza To: dsterba@suse.com, linux-btrfs@vger.kernel.org Cc: Marcos Paulo de Souza Subject: [RFC PATCH 7/8] btrfs: Convert to fs_context Date: Wed, 12 Aug 2020 13:36:53 -0300 Message-Id: <20200812163654.17080-8-marcos@mpdesouza.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812163654.17080-1-marcos@mpdesouza.com> References: <20200812163654.17080-1-marcos@mpdesouza.com> MIME-Version: 1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - br540.hostgator.com.br X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - mpdesouza.com X-BWhitelist: no X-Source-IP: 179.185.221.211 X-Source-L: No X-Exim-ID: 1k5tkg-004J9r-Ge X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: (hephaestus.suse.de) [179.185.221.211]:55300 X-Source-Auth: marcos@mpdesouza.com X-Email-Count: 23 X-Source-Cap: bXBkZXNvNTM7bXBkZXNvNTM7YnI1NDAuaG9zdGdhdG9yLmNvbS5icg== X-Local-Domain: yes Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Marcos Paulo de Souza This commit makes btrfs full use of the fs_context API. It's heavily based in David Howells POC when fs_context was introduced[1]. As fs_context divides the mount procedure into different steps, the btrfs code needed to be rearranged in order to store the mount points and other properties without having a fs_info already allocated. The btrfs_fs_context struct is the responsible struct for storing the options used to mount the fs, and these options are set to fs_info->mount_opts in btrfs_apply_configuration. Some notable changes: * There is no need for a second file_system_type anymore. Now we use a special flag in btrfs_fs_context to identify the mount of the root subvol before mounting the specified subvol. * With the introduction of fs_context all mount options are parsed _before_ doing the mount procedure. In our case, btrfs_fc_parse_param is the function being called to parse all options, making btrfs_parse_device_options, btrfs_parse_subvol_options btrfs_parse_options obsolete. * Function btrfs_mount_root was renamed to btrfs_root_get_tree to reflect that fs_context is being used. * Function btrfs_remount was renamed to btrfs_reconfigure by the same reason from above. * Function btrfs_mount was renamed to btrfs_get_tree, and this function is called by vfs after all the mount options are parsed. * There is no need for btrfs_root_fs_type anymore, and so fs_info->bdev_holder can also be removed. Functions like open_ctree and btrfs_fill_super are now using a fs_context argument instead of other btrfs related structs, since the fs_context->fs_private contains a btrfs_fs_context that holds the necessary data. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git/commit/?h=Q46&id=554cb2019cda83e1aba10bd9eea485afd2ddb983 Signed-off-by: Marcos Paulo de Souza --- fs/btrfs/ctree.h | 1 + fs/btrfs/dev-replace.c | 2 +- fs/btrfs/disk-io.c | 10 +- fs/btrfs/disk-io.h | 4 +- fs/btrfs/super.c | 347 ++++++++++++++++++++--------------------- fs/btrfs/volumes.c | 6 +- 6 files changed, 178 insertions(+), 192 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index d96bce2ea5bb..9060be6a6c6e 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3100,6 +3100,7 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, struct btrfs_root *root); /* super.c */ +extern struct file_system_type btrfs_fs_type; int btrfs_parse_options(struct btrfs_fs_info *info, char *options, unsigned long new_flags); int btrfs_apply_configuration(struct fs_context *fc, struct super_block *sb); diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index db93909b25e0..9a3275845b13 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -236,7 +236,7 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, } bdev = blkdev_get_by_path(device_path, FMODE_WRITE | FMODE_EXCL, - fs_info->bdev_holder); + &btrfs_fs_type); if (IS_ERR(bdev)) { btrfs_err(fs_info, "target device %s is invalid!", device_path); return PTR_ERR(bdev); diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index c850d7f44fbe..f2e7543e9913 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2894,8 +2894,7 @@ static int btrfs_check_uuid_tree(struct btrfs_fs_info *fs_info) return 0; } -int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_devices, - char *options) +int __cold open_ctree(struct fs_context *fc, struct super_block *sb) { u32 sectorsize; u32 nodesize; @@ -2905,6 +2904,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device u16 csum_type; struct btrfs_super_block *disk_super; struct btrfs_fs_info *fs_info = btrfs_sb(sb); + struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; struct btrfs_root *tree_root; struct btrfs_root *chunk_root; int ret; @@ -3030,11 +3030,9 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device */ fs_info->compress_type = BTRFS_COMPRESS_ZLIB; - ret = btrfs_parse_options(fs_info, options, sb->s_flags); - if (ret) { - err = ret; + err = btrfs_apply_configuration(fc, sb); + if (err) goto fail_alloc; - } features = btrfs_super_incompat_flags(disk_super) & ~BTRFS_FEATURE_INCOMPAT_SUPP; diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 00dc39d47ed3..712ea61ffdfe 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h @@ -50,9 +50,7 @@ struct extent_buffer *btrfs_find_create_tree_block( struct btrfs_fs_info *fs_info, u64 bytenr); void btrfs_clean_tree_block(struct extent_buffer *buf); -int __cold open_ctree(struct super_block *sb, - struct btrfs_fs_devices *fs_devices, - char *options); +int __cold open_ctree(struct fs_context *fc, struct super_block *sb); void __cold close_ctree(struct btrfs_fs_info *fs_info); int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors); struct btrfs_super_block *btrfs_read_dev_super(struct block_device *bdev); diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 5bbf4b947125..d9a0faea8c88 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -63,10 +63,9 @@ static const struct super_operations btrfs_super_ops; * * The new btrfs_root_fs_type also servers as a tag for the bdev_holder. */ -static struct file_system_type btrfs_fs_type; static struct file_system_type btrfs_root_fs_type; -static int btrfs_remount(struct super_block *sb, int *flags, char *data); +static int btrfs_reconfigure(struct fs_context *fc); /* * Generally the error codes correspond to their respective errors, but there @@ -1542,7 +1541,7 @@ static int btrfs_parse_device_options(const char *options, fmode_t flags, goto out; } device = btrfs_scan_one_device(device_name, flags, - holder); + &btrfs_fs_type); kfree(device_name); if (IS_ERR(device)) { error = PTR_ERR(device); @@ -1795,13 +1794,13 @@ static int get_default_subvol_objectid(struct btrfs_fs_info *fs_info, u64 *objec return 0; } -static int btrfs_fill_super(struct super_block *sb, - struct btrfs_fs_devices *fs_devices, - void *data) +static int btrfs_fill_super(struct fs_context *fc, + struct super_block *sb, + struct btrfs_fs_devices *fs_devices) { + int err; struct inode *inode; struct btrfs_fs_info *fs_info = btrfs_sb(sb); - int err; sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_magic = BTRFS_SUPER_MAGIC; @@ -1810,9 +1809,6 @@ static int btrfs_fill_super(struct super_block *sb, sb->s_export_op = &btrfs_export_ops; sb->s_xattr = btrfs_xattr_handlers; sb->s_time_gran = 1; -#ifdef CONFIG_BTRFS_FS_POSIX_ACL - sb->s_flags |= SB_POSIXACL; -#endif sb->s_flags |= SB_I_VERSION; sb->s_iflags |= SB_I_CGROUPWB; @@ -1822,7 +1818,7 @@ static int btrfs_fill_super(struct super_block *sb, return err; } - err = open_ctree(sb, fs_devices, (char *)data); + err = open_ctree(fc, sb); if (err) { btrfs_err(fs_info, "open_ctree failed"); return err; @@ -1951,19 +1947,20 @@ int btrfs_apply_configuration(struct fs_context *fc, #endif #ifdef CONFIG_BTRFS_FS_REF_VERIFY - if (btrfs_test_exp_opt(ctx, REF_VERIFY)) - btrfs_info(info, "doing ref verification"); + if (btrfs_test_exp_opt(ctx, REF_VERIFY)) + btrfs_info(info, "doing ref verification"); #endif + info->pending_changes = ctx->pending_changes; if (btrfs_test_exp_opt(ctx, INODE_MAP_CACHE)) { - if (btrfs_opt_map[Opt_inode_cache].enabled) { - btrfs_clear_pending_and_info(info, INODE_MAP_CACHE, - "disabling inode map caching"); + if (!btrfs_opt_map[Opt_inode_cache].enabled) { + btrfs_clear_pending_and_info(info, INODE_MAP_CACHE, + "disabling inode map caching"); } else { btrfs_info(info, "the 'inode_cache' option is deprecated and will have no effect from 5.11"); btrfs_set_pending_and_info(info, INODE_MAP_CACHE, - "enabling inode map caching"); + "enabling inode map caching"); } } @@ -2015,10 +2012,9 @@ int btrfs_apply_configuration(struct fs_context *fc, if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE)) { bool opt_clear = btrfs_test_opt(ctx, CLEAR_CACHE); bool opt_cache_v1 = btrfs_test_opt(ctx, SPACE_CACHE); - bool no_space_cache = ctx->nospace_cache; - if ((no_space_cache && !opt_clear) || (opt_cache_v1 && !opt_clear)) { - btrfs_err(info, "cannot disable free space tree XX"); + if ((ctx->nospace_cache && !opt_clear) || (opt_cache_v1 && !opt_clear)) { + btrfs_err(info, "cannot disable free space tree"); return -EINVAL; } } @@ -2063,7 +2059,6 @@ int btrfs_apply_configuration(struct fs_context *fc, info->compress_type = ctx->compress_type; info->compress_level = ctx->compress_level; - info->pending_changes = ctx->pending_changes; info->mount_opt = ctx->mount_opt; return 0; @@ -2213,9 +2208,9 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) return 0; } -static int btrfs_test_super(struct super_block *s, void *data) +static int btrfs_test_super(struct super_block *s, struct fs_context *fc) { - struct btrfs_fs_info *p = data; + struct btrfs_fs_info *p = fc->s_fs_info; struct btrfs_fs_info *fs_info = btrfs_sb(s); return fs_info->fs_devices == p->fs_devices; @@ -2239,34 +2234,34 @@ static inline int is_subvolume_inode(struct inode *inode) return 0; } -static struct dentry *mount_subvol(const char *subvol_name, u64 subvol_objectid, - struct vfsmount *mnt) +static int mount_subvol(struct fs_context *fc) { + struct btrfs_fs_context *ctx = fc->fs_private; + struct vfsmount *mnt = ctx->root_mnt; struct dentry *root; int ret; - if (!subvol_name) { - if (!subvol_objectid) { + if (!ctx->subvol_name) { + char *subvol_name; + + if (!ctx->subvolid) { ret = get_default_subvol_objectid(btrfs_sb(mnt->mnt_sb), - &subvol_objectid); - if (ret) { - root = ERR_PTR(ret); - goto out; - } + &ctx->subvolid); + if (ret) + return ret; } subvol_name = btrfs_get_subvol_name_from_objectid( - btrfs_sb(mnt->mnt_sb), subvol_objectid); - if (IS_ERR(subvol_name)) { - root = ERR_CAST(subvol_name); - subvol_name = NULL; - goto out; - } + btrfs_sb(mnt->mnt_sb), + ctx->subvolid); + if (IS_ERR(subvol_name)) + return PTR_ERR(subvol_name); + ctx->subvol_name = subvol_name; } - root = mount_subtree(mnt, subvol_name); - /* mount_subtree() drops our reference on the vfsmount. */ - mnt = NULL; + root = mount_subtree(mnt, ctx->subvol_name); + /* mount_subtree() dropped our reference on the vfsmount. */ + ctx->root_mnt = NULL; if (!IS_ERR(root)) { struct super_block *s = root->d_sb; @@ -2277,10 +2272,10 @@ static struct dentry *mount_subvol(const char *subvol_name, u64 subvol_objectid, ret = 0; if (!is_subvolume_inode(root_inode)) { btrfs_err(fs_info, "'%s' is not a valid subvolume", - subvol_name); + ctx->subvol_name); ret = -EINVAL; } - if (subvol_objectid && root_objectid != subvol_objectid) { + if (ctx->subvolid && root_objectid != ctx->subvolid) { /* * This will also catch a race condition where a * subvolume which was passed by ID is renamed and @@ -2288,20 +2283,23 @@ static struct dentry *mount_subvol(const char *subvol_name, u64 subvol_objectid, */ btrfs_err(fs_info, "subvol '%s' does not match subvolid %llu", - subvol_name, subvol_objectid); + ctx->subvol_name, ctx->subvolid); ret = -EINVAL; } if (ret) { dput(root); - root = ERR_PTR(ret); deactivate_locked_super(s); + goto out; } + } else { + return PTR_ERR(root); } + fc->root = root; + ret = 0; + out: - mntput(mnt); - kfree(subvol_name); - return root; + return ret; } /* @@ -2310,27 +2308,20 @@ static struct dentry *mount_subvol(const char *subvol_name, u64 subvol_objectid, * Note: This is based on mount_bdev from fs/super.c with a few additions * for multiple device setup. Make sure to keep it in sync. */ -static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, - int flags, const char *device_name, void *data) +static int btrfs_root_get_tree(struct fs_context *fc) { - struct block_device *bdev = NULL; + struct block_device *bdev; struct super_block *s; + struct btrfs_fs_context *ctx = fc->fs_private; struct btrfs_device *device = NULL; struct btrfs_fs_devices *fs_devices = NULL; struct btrfs_fs_info *fs_info = NULL; - void *new_sec_opts = NULL; fmode_t mode = FMODE_READ; - int error = 0; + int error = 0, i; - if (!(flags & SB_RDONLY)) + if (!(fc->sb_flags & SB_RDONLY)) mode |= FMODE_WRITE; - if (data) { - error = security_sb_eat_lsm_opts(data, &new_sec_opts); - if (error) - return ERR_PTR(error); - } - /* * Setup a dummy root and fs_info for test/set super. This is because * we don't actually fill this stuff out until open_ctree, but we need @@ -2340,10 +2331,9 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, * superblock with our given fs_devices later on at sget() time. */ fs_info = kvzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL); - if (!fs_info) { - error = -ENOMEM; - goto error_sec_opts; - } + if (!fs_info) + return -ENOMEM; + btrfs_init_fs_info(fs_info); fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); @@ -2354,13 +2344,20 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, } mutex_lock(&uuid_mutex); - error = btrfs_parse_device_options(data, mode, fs_type); - if (error) { - mutex_unlock(&uuid_mutex); - goto error_fs_info; + + if (ctx->devices) { + for (i = 0; i < ctx->nr_devices; i++) { + device = btrfs_scan_one_device(ctx->devices[i], mode, + &btrfs_fs_type); + if (IS_ERR(device)) { + mutex_unlock(&uuid_mutex); + error = PTR_ERR(device); + goto error_fs_info; + } + } } - device = btrfs_scan_one_device(device_name, mode, fs_type); + device = btrfs_scan_one_device(fc->source, mode, &btrfs_fs_type); if (IS_ERR(device)) { mutex_unlock(&uuid_mutex); error = PTR_ERR(device); @@ -2370,53 +2367,49 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, fs_devices = device->fs_devices; fs_info->fs_devices = fs_devices; - error = btrfs_open_devices(fs_devices, mode, fs_type); + error = btrfs_open_devices(fs_devices, mode, &btrfs_fs_type); mutex_unlock(&uuid_mutex); if (error) goto error_fs_info; - if (!(flags & SB_RDONLY) && fs_devices->rw_devices == 0) { + + if (!(fc->sb_flags & SB_RDONLY) && fs_devices->rw_devices == 0) { error = -EACCES; goto error_close_devices; } bdev = fs_devices->latest_bdev; - s = sget(fs_type, btrfs_test_super, btrfs_set_super, flags | SB_NOSEC, - fs_info); + + fc->s_fs_info = fs_info; + s = sget_fc(fc, btrfs_test_super, set_anon_super_fc); if (IS_ERR(s)) { error = PTR_ERR(s); goto error_close_devices; } + /* sget_fc returned a previously allocated superblocl. */ if (s->s_root) { - btrfs_close_devices(fs_devices); - btrfs_free_fs_info(fs_info); - if ((flags ^ s->s_flags) & SB_RDONLY) + btrfs_close_devices(fs_info->fs_devices); + if ((fc->sb_flags ^ s->s_flags) & SB_RDONLY) error = -EBUSY; } else { snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev); - btrfs_sb(s)->bdev_holder = fs_type; - if (!strstr(crc32c_impl(), "generic")) - set_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags); - error = btrfs_fill_super(s, fs_devices, data); - } - if (!error) - error = security_sb_set_mnt_opts(s, new_sec_opts, 0, NULL); - security_free_mnt_opts(&new_sec_opts); - if (error) { - deactivate_locked_super(s); - return ERR_PTR(error); + error = btrfs_fill_super(fc, s, fs_devices); } - return dget(s->s_root); + if (error) + goto error_super; + + fc->root = dget(s->s_root); + return 0; +error_super: + deactivate_locked_super(s); error_close_devices: btrfs_close_devices(fs_devices); error_fs_info: - btrfs_free_fs_info(fs_info); -error_sec_opts: - security_free_mnt_opts(&new_sec_opts); - return ERR_PTR(error); + /*btrfs_free_fs_info(fs_info);*/ + return error; } /* @@ -2424,7 +2417,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, * btrfs_get_tree will be called recursively, but then will check for the * ctx->root being set and call btrfs_root_get_tree. */ -static int btrfs_mount_root_fc(struct fs_context *fc, unsigned int rdonly) +int btrfs_mount_root_fc(struct fs_context *fc, unsigned int rdonly) { struct btrfs_fs_context *ctx, *root_ctx; struct fs_context *root_fc; @@ -2460,81 +2453,76 @@ static int btrfs_mount_root_fc(struct fs_context *fc, unsigned int rdonly) return ret; } +static int btrfs_reconfigure_root_to_rw(struct fs_context *fc, + struct super_block *sb) +{ + int error; + struct fs_context root_fc = { + .purpose = FS_CONTEXT_FOR_RECONFIGURE, + .fs_type = sb->s_type, + .root = sb->s_root, + .log = fc->log, + .sb_flags = 0, + .sb_flags_mask = SB_RDONLY, + }; + + down_write(&sb->s_umount); + error = btrfs_reconfigure(&root_fc); + up_write(&sb->s_umount); + return error; +} + /* - * Mount function which is called by VFS layer. + * Mount function which is called by VFS layer after the argument parsing. * * In order to allow mounting a subvolume directly, btrfs uses mount_subtree() * which needs vfsmount* of device's root (/). This means device's root has to * be mounted internally in any case. * * Operation flow: - * 1. Parse subvol id related options for later use in mount_subvol(). - * - * 2. Mount device's root (/) by calling vfs_kern_mount(). + * 1. Mount device's root (/) by calling btrfs_mount_root_fc. * - * NOTE: vfs_kern_mount() is used by VFS to call btrfs_mount() in the - * first place. In order to avoid calling btrfs_mount() again, we use - * different file_system_type which is not registered to VFS by - * register_filesystem() (btrfs_root_fs_type). As a result, - * btrfs_mount_root() is called. The return value will be used by - * mount_subtree() in mount_subvol(). + * 2. btrfs_get_tree is called recursively by btrfs_mount_fc -> fc_mount -> + * btrfs_get_tree, because we use the same file_system_type for both root and + * subvol mounts. We avoid the infinite recursive calls by checking the + * ctx->root member being set, which shows that we are trying to mount the + * root fs. * * 3. Call mount_subvol() to get the dentry of subvolume. Since there is * "btrfs subvolume set-default", mount_subvol() is called always. */ -static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, - const char *device_name, void *data) +static int btrfs_get_tree(struct fs_context *fc) { - struct vfsmount *mnt_root; - struct dentry *root; - char *subvol_name = NULL; - u64 subvol_objectid = 0; - int error = 0; + struct btrfs_fs_context *ctx = fc->fs_private; + int error = btrfs_fc_validate(fc); - error = btrfs_parse_subvol_options(data, &subvol_name, - &subvol_objectid); - if (error) { - kfree(subvol_name); - return ERR_PTR(error); - } + if (error) + return error; - /* mount device's root (/) */ - mnt_root = vfs_kern_mount(&btrfs_root_fs_type, flags, device_name, data); - if (PTR_ERR_OR_ZERO(mnt_root) == -EBUSY) { - if (flags & SB_RDONLY) { - mnt_root = vfs_kern_mount(&btrfs_root_fs_type, - flags & ~SB_RDONLY, device_name, data); - } else { - mnt_root = vfs_kern_mount(&btrfs_root_fs_type, - flags | SB_RDONLY, device_name, data); - if (IS_ERR(mnt_root)) { - root = ERR_CAST(mnt_root); - kfree(subvol_name); - goto out; - } + if (!fc->source) + return invalf(fc, "No source specified"); - down_write(&mnt_root->mnt_sb->s_umount); - error = btrfs_remount(mnt_root->mnt_sb, &flags, NULL); - up_write(&mnt_root->mnt_sb->s_umount); - if (error < 0) { - root = ERR_PTR(error); - mntput(mnt_root); - kfree(subvol_name); - goto out; - } + if (ctx->root) + return btrfs_root_get_tree(fc); + + /* mount device's root (/) */ + error = btrfs_mount_root_fc(fc, fc->sb_flags & SB_RDONLY); + if (error == -EBUSY) { + /* + * If returned EBUSY, try again the mount inverting the rdonly + * argument of btrfs_mount_root. + */ + error = btrfs_mount_root_fc(fc, (fc->sb_flags & SB_RDONLY) ^ SB_RDONLY); + if (!error && !(fc->sb_flags & SB_RDONLY)) { + error = btrfs_reconfigure_root_to_rw(fc, + ctx->root_mnt->mnt_sb); } } - if (IS_ERR(mnt_root)) { - root = ERR_CAST(mnt_root); - kfree(subvol_name); - goto out; - } - /* mount_subvol() will free subvol_name and mnt_root */ - root = mount_subvol(subvol_name, subvol_objectid, mnt_root); + if (error < 0) + return error; -out: - return root; + return mount_subvol(fc); } static void btrfs_resize_thread_pool(struct btrfs_fs_info *fs_info, @@ -2598,8 +2586,16 @@ static inline void btrfs_remount_cleanup(struct btrfs_fs_info *fs_info, btrfs_discard_cleanup(fs_info); } -static int btrfs_remount(struct super_block *sb, int *flags, char *data) +/* + * Change the configuration of an active superblock according to the supplied + * parameters. Note that the parameter pointer (fc->fs_private) may be NULL in + * the case of umount detach, emergency remount R/O and get_tree remounting as + * R/W. + */ +int btrfs_reconfigure(struct fs_context *fc) { + struct btrfs_fs_context *ctx = fc->fs_private; + struct super_block *sb = fc->root->d_sb; struct btrfs_fs_info *fs_info = btrfs_sb(sb); struct btrfs_root *root = fs_info->tree_root; unsigned old_flags = sb->s_flags; @@ -2608,34 +2604,28 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) u64 old_max_inline = fs_info->max_inline; u32 old_thread_pool_size = fs_info->thread_pool_size; u32 old_metadata_ratio = fs_info->metadata_ratio; - int ret; + int ret = btrfs_fc_validate(fc); + + if (ret) + return ret; sync_filesystem(sb); set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); - - if (data) { - void *new_sec_opts = NULL; - - ret = security_sb_eat_lsm_opts(data, &new_sec_opts); - if (!ret) - ret = security_sb_remount(sb, new_sec_opts); - security_free_mnt_opts(&new_sec_opts); + if (ctx) { + ret = btrfs_apply_configuration(fc, sb); if (ret) goto restore; } - ret = btrfs_parse_options(fs_info, data, *flags); - if (ret) - goto restore; + btrfs_remount_begin(fs_info, old_opts, fc->sb_flags); + if (ctx && ctx->thread_pool_size) + btrfs_resize_thread_pool(fs_info, ctx->thread_pool_size, + old_thread_pool_size); - btrfs_remount_begin(fs_info, old_opts, *flags); - btrfs_resize_thread_pool(fs_info, - fs_info->thread_pool_size, old_thread_pool_size); - - if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb)) + if ((bool)(fc->sb_flags & SB_RDONLY) == sb_rdonly(sb)) goto out; - if (*flags & SB_RDONLY) { + if (fc->sb_flags & SB_RDONLY) { /* * this also happens on 'umount -rf' or on shutdown, when * the filesystem is busy. @@ -2735,7 +2725,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) * We need to set SB_I_VERSION here otherwise it'll get cleared by VFS, * since the absence of the flag means it can be toggled off by remount. */ - *flags |= SB_I_VERSION; + fc->sb_flags |= SB_I_VERSION; wake_up_process(fs_info->transaction_kthread); btrfs_remount_cleanup(fs_info, old_opts); @@ -3058,9 +3048,11 @@ static void btrfs_fc_free(struct fs_context *fc) } static const struct fs_context_operations btrfs_context_ops = { - .dup = btrfs_dup_fc, - .free = btrfs_fc_free, - .parse_param = btrfs_fc_parse_param, + .dup = btrfs_dup_fc, + .free = btrfs_fc_free, + .get_tree = btrfs_get_tree, + .parse_param = btrfs_fc_parse_param, + .reconfigure = btrfs_reconfigure, }; static int btrfs_init_fs_context(struct fs_context *fc) @@ -3072,7 +3064,6 @@ static int btrfs_init_fs_context(struct fs_context *fc) return -ENOMEM; /* currently default options */ - btrfs_set_opt(ctx->mount_opt, SPACE_CACHE); #ifdef CONFIG_BTRFS_FS_POSIX_ACL fc->sb_flags |= SB_POSIXACL; #endif @@ -3083,19 +3074,18 @@ static int btrfs_init_fs_context(struct fs_context *fc) return 0; } -static struct file_system_type btrfs_fs_type = { +struct file_system_type btrfs_fs_type = { .owner = THIS_MODULE, .name = "btrfs", - .mount = btrfs_mount, .parameters = btrfs_fs_parameters, + .init_fs_context = btrfs_init_fs_context, .kill_sb = btrfs_kill_super, .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA, -}; + }; static struct file_system_type btrfs_root_fs_type = { .owner = THIS_MODULE, .name = "btrfs", - .mount = btrfs_mount_root, .parameters = btrfs_fs_parameters, .kill_sb = btrfs_kill_super, .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA, @@ -3136,7 +3126,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, case BTRFS_IOC_SCAN_DEV: mutex_lock(&uuid_mutex); device = btrfs_scan_one_device(vol->name, FMODE_READ, - &btrfs_root_fs_type); + &btrfs_fs_type); ret = PTR_ERR_OR_ZERO(device); mutex_unlock(&uuid_mutex); break; @@ -3146,7 +3136,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, case BTRFS_IOC_DEVICES_READY: mutex_lock(&uuid_mutex); device = btrfs_scan_one_device(vol->name, FMODE_READ, - &btrfs_root_fs_type); + &btrfs_fs_type); if (IS_ERR(device)) { mutex_unlock(&uuid_mutex); ret = PTR_ERR(device); @@ -3237,7 +3227,6 @@ static const struct super_operations btrfs_super_ops = { .destroy_inode = btrfs_destroy_inode, .free_inode = btrfs_free_inode, .statfs = btrfs_statfs, - .remount_fs = btrfs_remount, .freeze_fs = btrfs_freeze, .unfreeze_fs = btrfs_unfreeze, }; diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index d7670e2a9f39..59ba27e82615 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2304,7 +2304,7 @@ static struct btrfs_device *btrfs_find_device_by_path( struct btrfs_device *device; ret = btrfs_get_bdev_and_sb(device_path, FMODE_READ, - fs_info->bdev_holder, 0, &bdev, &disk_super); + &btrfs_fs_type, 0, &bdev, &disk_super); if (ret) return ERR_PTR(ret); @@ -2516,7 +2516,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path return -EROFS; bdev = blkdev_get_by_path(device_path, FMODE_WRITE | FMODE_EXCL, - fs_info->bdev_holder); + &btrfs_fs_type); if (IS_ERR(bdev)) return PTR_ERR(bdev); @@ -6739,7 +6739,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info, if (IS_ERR(fs_devices)) return fs_devices; - ret = open_fs_devices(fs_devices, FMODE_READ, fs_info->bdev_holder); + ret = open_fs_devices(fs_devices, FMODE_READ, &btrfs_fs_type); if (ret) { free_fs_devices(fs_devices); fs_devices = ERR_PTR(ret); From patchwork Wed Aug 12 16:36:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcos Paulo de Souza X-Patchwork-Id: 11711077 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E7B6013A4 for ; Wed, 12 Aug 2020 17:24:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B6A3E20771 for ; Wed, 12 Aug 2020 17:24:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=mpdesouza.com header.i=@mpdesouza.com header.b="MtLUmwsh" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726531AbgHLRYY (ORCPT ); Wed, 12 Aug 2020 13:24:24 -0400 Received: from gateway20.websitewelcome.com ([192.185.60.19]:35109 "EHLO gateway20.websitewelcome.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725993AbgHLRYX (ORCPT ); Wed, 12 Aug 2020 13:24:23 -0400 X-Greylist: delayed 1501 seconds by postgrey-1.27 at vger.kernel.org; Wed, 12 Aug 2020 13:24:21 EDT Received: from cm13.websitewelcome.com (cm13.websitewelcome.com [100.42.49.6]) by gateway20.websitewelcome.com (Postfix) with ESMTP id EE345400DE5FF for ; Wed, 12 Aug 2020 10:14:25 -0500 (CDT) Received: from br540.hostgator.com.br ([108.179.252.180]) by cmsmtp with SMTP id 5tkik1ku1Xp2A5tkikP7vJ; Wed, 12 Aug 2020 11:37:24 -0500 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mpdesouza.com; s=default; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=/ZkWlRCSz6RjY6K+qOL9VKvjrSo/ErdxCvJO5GKxSYE=; b=MtLUmwshbBQosiiZnOPKez0E0N NEDEZJSdwyzifzwZuE2WIMp/8PBB1X8LsbgQie64xOTVg6UH0eAhOIszVE+BwFr+vI2lFrhO+GCxn D4KvBxZDPT7FxnPbvAwgeeIDv9tqmy+6LEr7uch7AX0Lu41dKJoxjzjTtiir3GXq7/PNmu33yHwFO oDlvBFJX2FMduZ5XITIe0HopRqPJ9FUpDkpb9bliB8YN35itZTDTGDidmxZhkTaEhEog53apNJpt4 c9uIeH2bZs8r0+cEdsNV947DWORSzurqlOqSFJIaqfdtlG38g8hGN3RLAFW7rOP57IF8cbTFM6w3R PQ2gC/vQ==; Received: from [179.185.221.211] (port=55300 helo=hephaestus.suse.de) by br540.hostgator.com.br with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1k5tkh-004J9r-UU; Wed, 12 Aug 2020 13:37:24 -0300 From: Marcos Paulo de Souza To: dsterba@suse.com, linux-btrfs@vger.kernel.org Cc: Marcos Paulo de Souza Subject: [RFC PATCH 8/8] btrfs: Remove leftover code from fscontext conversion Date: Wed, 12 Aug 2020 13:36:54 -0300 Message-Id: <20200812163654.17080-9-marcos@mpdesouza.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200812163654.17080-1-marcos@mpdesouza.com> References: <20200812163654.17080-1-marcos@mpdesouza.com> MIME-Version: 1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - br540.hostgator.com.br X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - mpdesouza.com X-BWhitelist: no X-Source-IP: 179.185.221.211 X-Source-L: No X-Exim-ID: 1k5tkh-004J9r-UU X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: (hephaestus.suse.de) [179.185.221.211]:55300 X-Source-Auth: marcos@mpdesouza.com X-Email-Count: 26 X-Source-Cap: bXBkZXNvNTM7bXBkZXNvNTM7YnI1NDAuaG9zdGdhdG9yLmNvbS5icg== X-Local-Domain: yes Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Marcos Paulo de Souza * Remove all Opt_no* options, since the fscontext have a flag_no version which also handles this option variation. * Remove all old parse_* function, since now btrfs_fc_parse_param handles all options. * Remove the btrfs_root_fs_type now that btrfs_fs_type handles both root fs and subvolumes. Signed-off-by: Marcos Paulo de Souza --- fs/btrfs/super.c | 784 +---------------------------------------------- 1 file changed, 14 insertions(+), 770 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index d9a0faea8c88..8e2feef075c9 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -55,16 +55,6 @@ static const struct super_operations btrfs_super_ops; -/* - * Types for mounting the default subvolume and a subvolume explicitly - * requested by subvol=/path. That way the callchain is straightforward and we - * don't have to play tricks with the mount options and recursive calls to - * btrfs_mount. - * - * The new btrfs_root_fs_type also servers as a tag for the bdev_holder. - */ -static struct file_system_type btrfs_root_fs_type; - static int btrfs_reconfigure(struct fs_context *fc); /* @@ -322,7 +312,7 @@ static void btrfs_put_super(struct super_block *sb) } enum { - Opt_acl, Opt_noacl, + Opt_acl, Opt_clear_cache, Opt_commit_interval, Opt_compress, @@ -332,28 +322,28 @@ enum { Opt_degraded, Opt_device, Opt_fatal_errors, - Opt_flushoncommit, Opt_noflushoncommit, - Opt_inode_cache, Opt_noinode_cache, + Opt_flushoncommit, + Opt_inode_cache, Opt_max_inline, - Opt_barrier, Opt_nobarrier, - Opt_datacow, Opt_nodatacow, - Opt_datasum, Opt_nodatasum, - Opt_defrag, Opt_nodefrag, - Opt_discard, Opt_nodiscard, + Opt_barrier, + Opt_datacow, + Opt_datasum, + Opt_defrag, + Opt_discard, Opt_discard_mode, Opt_norecovery, Opt_ratio, Opt_rescan_uuid_tree, Opt_skip_balance, - Opt_space_cache, Opt_no_space_cache, + Opt_space_cache, Opt_space_cache_version, - Opt_ssd, Opt_nossd, - Opt_ssd_spread, Opt_nossd_spread, + Opt_ssd, + Opt_ssd_spread, Opt_subvol, Opt_subvol_empty, Opt_subvolid, Opt_thread_pool, - Opt_treelog, Opt_notreelog, + Opt_treelog, Opt_user_subvol_rm_allowed, /* Rescue options */ @@ -368,10 +358,9 @@ enum { Opt_check_integrity, Opt_check_integrity_including_extent_data, Opt_check_integrity_print_mask, - Opt_enospc_debug, Opt_noenospc_debug, + Opt_enospc_debug, #ifdef CONFIG_BTRFS_DEBUG Opt_fragment, - Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all, #endif #ifdef CONFIG_BTRFS_FS_REF_VERIFY Opt_ref_verify, @@ -379,86 +368,6 @@ enum { Opt_err, }; -static const match_table_t tokens = { - {Opt_acl, "acl"}, - {Opt_noacl, "noacl"}, - {Opt_clear_cache, "clear_cache"}, - {Opt_commit_interval, "commit=%u"}, - {Opt_compress, "compress"}, - {Opt_compress_type, "compress=%s"}, - {Opt_compress_force, "compress-force"}, - {Opt_compress_force_type, "compress-force=%s"}, - {Opt_degraded, "degraded"}, - {Opt_device, "device=%s"}, - {Opt_fatal_errors, "fatal_errors=%s"}, - {Opt_flushoncommit, "flushoncommit"}, - {Opt_noflushoncommit, "noflushoncommit"}, - {Opt_inode_cache, "inode_cache"}, - {Opt_noinode_cache, "noinode_cache"}, - {Opt_max_inline, "max_inline=%s"}, - {Opt_barrier, "barrier"}, - {Opt_nobarrier, "nobarrier"}, - {Opt_datacow, "datacow"}, - {Opt_nodatacow, "nodatacow"}, - {Opt_datasum, "datasum"}, - {Opt_nodatasum, "nodatasum"}, - {Opt_defrag, "autodefrag"}, - {Opt_nodefrag, "noautodefrag"}, - {Opt_discard, "discard"}, - {Opt_discard_mode, "discard=%s"}, - {Opt_nodiscard, "nodiscard"}, - {Opt_norecovery, "norecovery"}, - {Opt_ratio, "metadata_ratio=%u"}, - {Opt_rescan_uuid_tree, "rescan_uuid_tree"}, - {Opt_skip_balance, "skip_balance"}, - {Opt_space_cache, "space_cache"}, - {Opt_no_space_cache, "nospace_cache"}, - {Opt_space_cache_version, "space_cache=%s"}, - {Opt_ssd, "ssd"}, - {Opt_nossd, "nossd"}, - {Opt_ssd_spread, "ssd_spread"}, - {Opt_nossd_spread, "nossd_spread"}, - {Opt_subvol, "subvol=%s"}, - {Opt_subvol_empty, "subvol="}, - {Opt_subvolid, "subvolid=%s"}, - {Opt_thread_pool, "thread_pool=%u"}, - {Opt_treelog, "treelog"}, - {Opt_notreelog, "notreelog"}, - {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, - - /* Rescue options */ - {Opt_rescue, "rescue=%s"}, - /* Deprecated, with alias rescue=nologreplay */ - {Opt_nologreplay, "nologreplay"}, - /* Deprecated, with alias rescue=usebackuproot */ - {Opt_usebackuproot, "usebackuproot"}, - - /* Deprecated options */ - {Opt_recovery, "recovery"}, - - /* Debugging options */ - {Opt_check_integrity, "check_int"}, - {Opt_check_integrity_including_extent_data, "check_int_data"}, - {Opt_check_integrity_print_mask, "check_int_print_mask=%u"}, - {Opt_enospc_debug, "enospc_debug"}, - {Opt_noenospc_debug, "noenospc_debug"}, -#ifdef CONFIG_BTRFS_DEBUG - {Opt_fragment_data, "fragment=data"}, - {Opt_fragment_metadata, "fragment=metadata"}, - {Opt_fragment_all, "fragment=all"}, -#endif -#ifdef CONFIG_BTRFS_FS_REF_VERIFY - {Opt_ref_verify, "ref_verify"}, -#endif - {Opt_err, NULL}, -}; - -static const match_table_t rescue_tokens = { - {Opt_usebackuproot, "usebackuproot"}, - {Opt_nologreplay, "nologreplay"}, - {Opt_err, NULL}, -}; - static const struct fs_parameter_spec btrfs_fs_parameters[] = { fsparam_flag_no("acl", Opt_acl), fsparam_flag_no("autodefrag", Opt_defrag), @@ -518,538 +427,6 @@ static const struct fs_parameter_spec btrfs_fs_parameters[] = { {} }; -static int parse_rescue_options(struct btrfs_fs_info *info, const char *options) -{ - char *opts; - char *orig; - char *p; - substring_t args[MAX_OPT_ARGS]; - int ret = 0; - - opts = kstrdup(options, GFP_KERNEL); - if (!opts) - return -ENOMEM; - orig = opts; - - while ((p = strsep(&opts, ":")) != NULL) { - int token; - - if (!*p) - continue; - token = match_token(p, rescue_tokens, args); - switch (token){ - case Opt_usebackuproot: - btrfs_info(info, - "trying to use backup root at mount time"); - btrfs_set_opt(info->mount_opt, USEBACKUPROOT); - break; - case Opt_nologreplay: - btrfs_set_and_info(info, NOLOGREPLAY, - "disabling log replay at mount time"); - break; - case Opt_err: - btrfs_info(info, "unrecognized rescue option '%s'", p); - ret = -EINVAL; - goto out; - default: - break; - } - - } -out: - kfree(orig); - return ret; -} - -/* - * Regular mount options parser. Everything that is needed only when - * reading in a new superblock is parsed here. - * XXX JDM: This needs to be cleaned up for remount. - */ -int btrfs_parse_options(struct btrfs_fs_info *info, char *options, - unsigned long new_flags) -{ - substring_t args[MAX_OPT_ARGS]; - char *p, *num; - u64 cache_gen; - int intarg; - int ret = 0; - char *compress_type; - bool compress_force = false; - enum btrfs_compression_type saved_compress_type; - int saved_compress_level; - bool saved_compress_force; - int no_compress = 0; - - cache_gen = btrfs_super_cache_generation(info->super_copy); - if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE)) - btrfs_set_opt(info->mount_opt, FREE_SPACE_TREE); - else if (cache_gen) - btrfs_set_opt(info->mount_opt, SPACE_CACHE); - - /* - * Even the options are empty, we still need to do extra check - * against new flags - */ - if (!options) - goto check; - - while ((p = strsep(&options, ",")) != NULL) { - int token; - if (!*p) - continue; - - token = match_token(p, tokens, args); - switch (token) { - case Opt_degraded: - btrfs_info(info, "allowing degraded mounts"); - btrfs_set_opt(info->mount_opt, DEGRADED); - break; - case Opt_subvol: - case Opt_subvol_empty: - case Opt_subvolid: - case Opt_device: - /* - * These are parsed by btrfs_parse_subvol_options or - * btrfs_parse_device_options and can be ignored here. - */ - break; - case Opt_nodatasum: - btrfs_set_and_info(info, NODATASUM, - "setting nodatasum"); - break; - case Opt_datasum: - if (btrfs_test_opt(info, NODATASUM)) { - if (btrfs_test_opt(info, NODATACOW)) - btrfs_info(info, - "setting datasum, datacow enabled"); - else - btrfs_info(info, "setting datasum"); - } - btrfs_clear_opt(info->mount_opt, NODATACOW); - btrfs_clear_opt(info->mount_opt, NODATASUM); - break; - case Opt_nodatacow: - if (!btrfs_test_opt(info, NODATACOW)) { - if (!btrfs_test_opt(info, COMPRESS) || - !btrfs_test_opt(info, FORCE_COMPRESS)) { - btrfs_info(info, - "setting nodatacow, compression disabled"); - } else { - btrfs_info(info, "setting nodatacow"); - } - } - btrfs_clear_opt(info->mount_opt, COMPRESS); - btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS); - btrfs_set_opt(info->mount_opt, NODATACOW); - btrfs_set_opt(info->mount_opt, NODATASUM); - break; - case Opt_datacow: - btrfs_clear_and_info(info, NODATACOW, - "setting datacow"); - break; - case Opt_compress_force: - case Opt_compress_force_type: - compress_force = true; - fallthrough; - case Opt_compress: - case Opt_compress_type: - saved_compress_type = btrfs_test_opt(info, - COMPRESS) ? - info->compress_type : BTRFS_COMPRESS_NONE; - saved_compress_force = - btrfs_test_opt(info, FORCE_COMPRESS); - saved_compress_level = info->compress_level; - if (token == Opt_compress || - token == Opt_compress_force || - strncmp(args[0].from, "zlib", 4) == 0) { - compress_type = "zlib"; - - info->compress_type = BTRFS_COMPRESS_ZLIB; - info->compress_level = BTRFS_ZLIB_DEFAULT_LEVEL; - /* - * args[0] contains uninitialized data since - * for these tokens we don't expect any - * parameter. - */ - if (token != Opt_compress && - token != Opt_compress_force) - info->compress_level = - btrfs_compress_str2level( - BTRFS_COMPRESS_ZLIB, - args[0].from + 4); - btrfs_set_opt(info->mount_opt, COMPRESS); - btrfs_clear_opt(info->mount_opt, NODATACOW); - btrfs_clear_opt(info->mount_opt, NODATASUM); - no_compress = 0; - } else if (strncmp(args[0].from, "lzo", 3) == 0) { - compress_type = "lzo"; - info->compress_type = BTRFS_COMPRESS_LZO; - btrfs_set_opt(info->mount_opt, COMPRESS); - btrfs_clear_opt(info->mount_opt, NODATACOW); - btrfs_clear_opt(info->mount_opt, NODATASUM); - btrfs_set_fs_incompat(info, COMPRESS_LZO); - no_compress = 0; - } else if (strncmp(args[0].from, "zstd", 4) == 0) { - compress_type = "zstd"; - info->compress_type = BTRFS_COMPRESS_ZSTD; - info->compress_level = - btrfs_compress_str2level( - BTRFS_COMPRESS_ZSTD, - args[0].from + 4); - btrfs_set_opt(info->mount_opt, COMPRESS); - btrfs_clear_opt(info->mount_opt, NODATACOW); - btrfs_clear_opt(info->mount_opt, NODATASUM); - btrfs_set_fs_incompat(info, COMPRESS_ZSTD); - no_compress = 0; - } else if (strncmp(args[0].from, "no", 2) == 0) { - compress_type = "no"; - info->compress_level = 0; - info->compress_type = 0; - btrfs_clear_opt(info->mount_opt, COMPRESS); - btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS); - compress_force = false; - no_compress++; - } else { - ret = -EINVAL; - goto out; - } - - if (compress_force) { - btrfs_set_opt(info->mount_opt, FORCE_COMPRESS); - } else { - /* - * If we remount from compress-force=xxx to - * compress=xxx, we need clear FORCE_COMPRESS - * flag, otherwise, there is no way for users - * to disable forcible compression separately. - */ - btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS); - } - if (no_compress == 1) { - btrfs_info(info, "use no compression"); - } else if ((info->compress_type != saved_compress_type) || - (compress_force != saved_compress_force) || - (info->compress_level != saved_compress_level)) { - btrfs_info(info, "%s %s compression, level %d", - (compress_force) ? "force" : "use", - compress_type, info->compress_level); - } - compress_force = false; - break; - case Opt_ssd: - btrfs_set_and_info(info, SSD, - "enabling ssd optimizations"); - btrfs_clear_opt(info->mount_opt, NOSSD); - break; - case Opt_ssd_spread: - btrfs_set_and_info(info, SSD, - "enabling ssd optimizations"); - btrfs_set_and_info(info, SSD_SPREAD, - "using spread ssd allocation scheme"); - btrfs_clear_opt(info->mount_opt, NOSSD); - break; - case Opt_nossd: - btrfs_set_opt(info->mount_opt, NOSSD); - btrfs_clear_and_info(info, SSD, - "not using ssd optimizations"); - fallthrough; - case Opt_nossd_spread: - btrfs_clear_and_info(info, SSD_SPREAD, - "not using spread ssd allocation scheme"); - break; - case Opt_barrier: - btrfs_clear_and_info(info, NOBARRIER, - "turning on barriers"); - break; - case Opt_nobarrier: - btrfs_set_and_info(info, NOBARRIER, - "turning off barriers"); - break; - case Opt_thread_pool: - ret = match_int(&args[0], &intarg); - if (ret) { - goto out; - } else if (intarg == 0) { - ret = -EINVAL; - goto out; - } - info->thread_pool_size = intarg; - break; - case Opt_max_inline: - num = match_strdup(&args[0]); - if (num) { - info->max_inline = memparse(num, NULL); - kfree(num); - - if (info->max_inline) { - info->max_inline = min_t(u64, - info->max_inline, - info->sectorsize); - } - btrfs_info(info, "max_inline at %llu", - info->max_inline); - } else { - ret = -ENOMEM; - goto out; - } - break; - case Opt_acl: -#ifdef CONFIG_BTRFS_FS_POSIX_ACL - info->sb->s_flags |= SB_POSIXACL; - break; -#else - btrfs_err(info, "support for ACL not compiled in!"); - ret = -EINVAL; - goto out; -#endif - case Opt_noacl: - info->sb->s_flags &= ~SB_POSIXACL; - break; - case Opt_notreelog: - btrfs_set_and_info(info, NOTREELOG, - "disabling tree log"); - break; - case Opt_treelog: - btrfs_clear_and_info(info, NOTREELOG, - "enabling tree log"); - break; - case Opt_norecovery: - case Opt_nologreplay: - btrfs_warn(info, - "'nologreplay' is deprecated, use 'rescue=nologreplay' instead"); - btrfs_set_and_info(info, NOLOGREPLAY, - "disabling log replay at mount time"); - break; - case Opt_flushoncommit: - btrfs_set_and_info(info, FLUSHONCOMMIT, - "turning on flush-on-commit"); - break; - case Opt_noflushoncommit: - btrfs_clear_and_info(info, FLUSHONCOMMIT, - "turning off flush-on-commit"); - break; - case Opt_ratio: - ret = match_int(&args[0], &intarg); - if (ret) - goto out; - info->metadata_ratio = intarg; - btrfs_info(info, "metadata ratio %u", - info->metadata_ratio); - break; - case Opt_discard: - case Opt_discard_mode: - if (token == Opt_discard || - strcmp(args[0].from, "sync") == 0) { - btrfs_clear_opt(info->mount_opt, DISCARD_ASYNC); - btrfs_set_and_info(info, DISCARD_SYNC, - "turning on sync discard"); - } else if (strcmp(args[0].from, "async") == 0) { - btrfs_clear_opt(info->mount_opt, DISCARD_SYNC); - btrfs_set_and_info(info, DISCARD_ASYNC, - "turning on async discard"); - } else { - ret = -EINVAL; - goto out; - } - break; - case Opt_nodiscard: - btrfs_clear_and_info(info, DISCARD_SYNC, - "turning off discard"); - btrfs_clear_and_info(info, DISCARD_ASYNC, - "turning off async discard"); - break; - case Opt_space_cache: - case Opt_space_cache_version: - if (token == Opt_space_cache || - strcmp(args[0].from, "v1") == 0) { - btrfs_clear_opt(info->mount_opt, - FREE_SPACE_TREE); - btrfs_set_and_info(info, SPACE_CACHE, - "enabling disk space caching"); - } else if (strcmp(args[0].from, "v2") == 0) { - btrfs_clear_opt(info->mount_opt, - SPACE_CACHE); - btrfs_set_and_info(info, FREE_SPACE_TREE, - "enabling free space tree"); - } else { - ret = -EINVAL; - goto out; - } - break; - case Opt_rescan_uuid_tree: - btrfs_set_opt(info->mount_opt, RESCAN_UUID_TREE); - break; - case Opt_no_space_cache: - if (btrfs_test_opt(info, SPACE_CACHE)) { - btrfs_clear_and_info(info, SPACE_CACHE, - "disabling disk space caching"); - } - if (btrfs_test_opt(info, FREE_SPACE_TREE)) { - btrfs_clear_and_info(info, FREE_SPACE_TREE, - "disabling free space tree"); - } - break; - case Opt_inode_cache: - btrfs_warn(info, - "the 'inode_cache' option is deprecated and will have no effect from 5.11"); - btrfs_set_pending_and_info(info, INODE_MAP_CACHE, - "enabling inode map caching"); - break; - case Opt_noinode_cache: - btrfs_clear_pending_and_info(info, INODE_MAP_CACHE, - "disabling inode map caching"); - break; - case Opt_clear_cache: - btrfs_set_and_info(info, CLEAR_CACHE, - "force clearing of disk cache"); - break; - case Opt_user_subvol_rm_allowed: - btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED); - break; - case Opt_enospc_debug: - btrfs_set_opt(info->mount_opt, ENOSPC_DEBUG); - break; - case Opt_noenospc_debug: - btrfs_clear_opt(info->mount_opt, ENOSPC_DEBUG); - break; - case Opt_defrag: - btrfs_set_and_info(info, AUTO_DEFRAG, - "enabling auto defrag"); - break; - case Opt_nodefrag: - btrfs_clear_and_info(info, AUTO_DEFRAG, - "disabling auto defrag"); - break; - case Opt_recovery: - case Opt_usebackuproot: - btrfs_warn(info, - "'%s' is deprecated, use 'rescue=usebackuproot' instead", - token == Opt_recovery ? "recovery" : - "usebackuproot"); - btrfs_info(info, - "trying to use backup root at mount time"); - btrfs_set_opt(info->mount_opt, USEBACKUPROOT); - break; - case Opt_skip_balance: - btrfs_set_opt(info->mount_opt, SKIP_BALANCE); - break; -#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY - case Opt_check_integrity_including_extent_data: - btrfs_info(info, - "enabling check integrity including extent data"); - btrfs_set_opt(info->mount_opt, - CHECK_INTEGRITY_INCLUDING_EXTENT_DATA); - btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY); - break; - case Opt_check_integrity: - btrfs_info(info, "enabling check integrity"); - btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY); - break; - case Opt_check_integrity_print_mask: - ret = match_int(&args[0], &intarg); - if (ret) - goto out; - info->check_integrity_print_mask = intarg; - btrfs_info(info, "check_integrity_print_mask 0x%x", - info->check_integrity_print_mask); - break; -#else - case Opt_check_integrity_including_extent_data: - case Opt_check_integrity: - case Opt_check_integrity_print_mask: - btrfs_err(info, - "support for check_integrity* not compiled in!"); - ret = -EINVAL; - goto out; -#endif - case Opt_fatal_errors: - if (strcmp(args[0].from, "panic") == 0) - btrfs_set_opt(info->mount_opt, - PANIC_ON_FATAL_ERROR); - else if (strcmp(args[0].from, "bug") == 0) - btrfs_clear_opt(info->mount_opt, - PANIC_ON_FATAL_ERROR); - else { - ret = -EINVAL; - goto out; - } - break; - case Opt_commit_interval: - intarg = 0; - ret = match_int(&args[0], &intarg); - if (ret) - goto out; - if (intarg == 0) { - btrfs_info(info, - "using default commit interval %us", - BTRFS_DEFAULT_COMMIT_INTERVAL); - intarg = BTRFS_DEFAULT_COMMIT_INTERVAL; - } else if (intarg > 300) { - btrfs_warn(info, "excessive commit interval %d", - intarg); - } - info->commit_interval = intarg; - break; - case Opt_rescue: - ret = parse_rescue_options(info, args[0].from); - if (ret < 0) - goto out; - break; -#ifdef CONFIG_BTRFS_DEBUG - case Opt_fragment_all: - btrfs_info(info, "fragmenting all space"); - btrfs_set_opt(info->mount_opt, FRAGMENT_DATA); - btrfs_set_opt(info->mount_opt, FRAGMENT_METADATA); - break; - case Opt_fragment_metadata: - btrfs_info(info, "fragmenting metadata"); - btrfs_set_opt(info->mount_opt, - FRAGMENT_METADATA); - break; - case Opt_fragment_data: - btrfs_info(info, "fragmenting data"); - btrfs_set_opt(info->mount_opt, FRAGMENT_DATA); - break; -#endif -#ifdef CONFIG_BTRFS_FS_REF_VERIFY - case Opt_ref_verify: - btrfs_info(info, "doing ref verification"); - btrfs_set_opt(info->mount_opt, REF_VERIFY); - break; -#endif - case Opt_err: - btrfs_err(info, "unrecognized mount option '%s'", p); - ret = -EINVAL; - goto out; - default: - break; - } - } -check: - /* - * Extra check for current option against current flag - */ - if (btrfs_test_opt(info, NOLOGREPLAY) && !(new_flags & SB_RDONLY)) { - btrfs_err(info, - "nologreplay must be used with ro mount option"); - ret = -EINVAL; - } -out: - if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE) && - !btrfs_test_opt(info, FREE_SPACE_TREE) && - !btrfs_test_opt(info, CLEAR_CACHE)) { - btrfs_err(info, "cannot disable free space tree"); - ret = -EINVAL; - - } - if (!ret && btrfs_test_opt(info, SPACE_CACHE)) - btrfs_info(info, "disk space caching is enabled"); - if (!ret && btrfs_test_opt(info, FREE_SPACE_TREE)) - btrfs_info(info, "using free space tree"); - return ret; -} - struct btrfs_flag_map { int bit; bool enabled; @@ -1499,123 +876,6 @@ static int btrfs_fc_parse_param(struct fs_context *fc, struct fs_parameter *para return 0; } -/* - * Parse mount options that are required early in the mount process. - * - * All other options will be parsed on much later in the mount process and - * only when we need to allocate a new super block. - */ -static int btrfs_parse_device_options(const char *options, fmode_t flags, - void *holder) -{ - substring_t args[MAX_OPT_ARGS]; - char *device_name, *opts, *orig, *p; - struct btrfs_device *device = NULL; - int error = 0; - - lockdep_assert_held(&uuid_mutex); - - if (!options) - return 0; - - /* - * strsep changes the string, duplicate it because btrfs_parse_options - * gets called later - */ - opts = kstrdup(options, GFP_KERNEL); - if (!opts) - return -ENOMEM; - orig = opts; - - while ((p = strsep(&opts, ",")) != NULL) { - int token; - - if (!*p) - continue; - - token = match_token(p, tokens, args); - if (token == Opt_device) { - device_name = match_strdup(&args[0]); - if (!device_name) { - error = -ENOMEM; - goto out; - } - device = btrfs_scan_one_device(device_name, flags, - &btrfs_fs_type); - kfree(device_name); - if (IS_ERR(device)) { - error = PTR_ERR(device); - goto out; - } - } - } - -out: - kfree(orig); - return error; -} - -/* - * Parse mount options that are related to subvolume id - * - * The value is later passed to mount_subvol() - */ -static int btrfs_parse_subvol_options(const char *options, char **subvol_name, - u64 *subvol_objectid) -{ - substring_t args[MAX_OPT_ARGS]; - char *opts, *orig, *p; - int error = 0; - u64 subvolid; - - if (!options) - return 0; - - /* - * strsep changes the string, duplicate it because - * btrfs_parse_device_options gets called later - */ - opts = kstrdup(options, GFP_KERNEL); - if (!opts) - return -ENOMEM; - orig = opts; - - while ((p = strsep(&opts, ",")) != NULL) { - int token; - if (!*p) - continue; - - token = match_token(p, tokens, args); - switch (token) { - case Opt_subvol: - kfree(*subvol_name); - *subvol_name = match_strdup(&args[0]); - if (!*subvol_name) { - error = -ENOMEM; - goto out; - } - break; - case Opt_subvolid: - error = match_u64(&args[0], &subvolid); - if (error) - goto out; - - /* we want the original fs_tree */ - if (subvolid == 0) - subvolid = BTRFS_FS_TREE_OBJECTID; - - *subvol_objectid = subvolid; - break; - default: - break; - } - } - -out: - kfree(orig); - return error; -} - char *btrfs_get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info, u64 subvol_objectid) { @@ -2042,7 +1302,7 @@ int btrfs_apply_configuration(struct fs_context *fc, if (btrfs_test_exp_opt(ctx, NOTREELOG)) btrfs_info(info, "%s tree log", - btrfs_opt_map[Opt_notreelog].enabled ? "enabling" + btrfs_opt_map[Opt_treelog].enabled ? "enabling" : "disabling"); #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY @@ -2216,14 +1476,6 @@ static int btrfs_test_super(struct super_block *s, struct fs_context *fc) return fs_info->fs_devices == p->fs_devices; } -static int btrfs_set_super(struct super_block *s, void *data) -{ - int err = set_anon_super(s, data); - if (!err) - s->s_fs_info = data; - return err; -} - /* * subvolumes are identified by ino 256 */ @@ -3081,14 +2333,6 @@ struct file_system_type btrfs_fs_type = { .init_fs_context = btrfs_init_fs_context, .kill_sb = btrfs_kill_super, .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA, - }; - -static struct file_system_type btrfs_root_fs_type = { - .owner = THIS_MODULE, - .name = "btrfs", - .parameters = btrfs_fs_parameters, - .kill_sb = btrfs_kill_super, - .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA, }; MODULE_ALIAS_FS("btrfs");