From: Anand Jain <anand.jain@oracle.com>
To: Qu Wenruo <wqu@suse.com>, linux-btrfs@vger.kernel.org
Subject: Re: [PATCH 2/7] btrfs-progs: cmds: add "btrfs tune set" subcommand group
Date: Thu, 21 Sep 2023 08:53:11 +0800 [thread overview]
Message-ID: <2adb8c79-d1d2-dffa-dd6b-5254d75c9c86@oracle.com> (raw)
In-Reply-To: <1c294f739f028da499cf7f57deb334f419979097.1693900169.git.wqu@suse.com>
On 05/09/2023 15:51, Qu Wenruo wrote:
> As the first step to convert btrfstune into "btrfs tune" subcommand
> group, this patch would add the following subcommand group:
>
> btrfs tune set <feature> [<device>]
>
> For now the following features are supported:
>
> - extref
> - skinny-metadata
> - no-holes
> All those are simple super block flags toggle.
>
> - list-all
> This acts the same way as "mkfs.btrfs -O list-all", the difference is
> it would only list the supported features.
> (In the future, there will be "btrfs tune clear" subcommand, which
> would support a different set of features).
>
With this patchset, the syntax is structured as follows:
$ btrfs tune --help
usage: btrfs tune <command> <args>
btrfs tune set <feature> [<device>]
Set/enable specified feature for the unmounted filesystem
btrfs tune clear <feature> [<device>]
Clear/disable specified feature for the unmounted filesystem
change various btrfs features
However, for consistency, I suggest the following syntax:
set:
$ btrfs tune <feature> /dev/sda
clear:
$ btrfs tune <feature> --clear /dev/sda
list:
$ btrfs tune --list-all
This syntax aligns with the:
$ btrfs device scan --forget
Thanks, Anand
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
> Documentation/btrfs-tune.rst | 40 ++++++
> Documentation/btrfs.rst | 5 +
> Documentation/conf.py | 1 +
> Documentation/man-index.rst | 1 +
> Makefile | 2 +-
> btrfs.c | 1 +
> cmds/commands.h | 1 +
> cmds/tune.c | 227 +++++++++++++++++++++++++++++++++++
> 8 files changed, 277 insertions(+), 1 deletion(-)
> create mode 100644 Documentation/btrfs-tune.rst
> create mode 100644 cmds/tune.c
>
> diff --git a/Documentation/btrfs-tune.rst b/Documentation/btrfs-tune.rst
> new file mode 100644
> index 000000000000..827c92eadb72
> --- /dev/null
> +++ b/Documentation/btrfs-tune.rst
> @@ -0,0 +1,40 @@
> +btrfs-tune(8)
> +==================
> +
> +SYNOPSIS
> +--------
> +
> +**btrfs tune** <subcommand> [<args>]
> +
> +DESCRIPTION
> +-----------
> +
> +:command:`btrfs tune` is used to tweak various btrfs features on a
> +unmounted filesystem.
> +
> +SUBCOMMAND
> +-----------
> +
> +set <feature> [<device>]
> + Set/enable a feature.
> +
> + If *feature* is `list-all`, all supported features would be listed, and
> + no *device* parameter is needed.
> +
> +EXIT STATUS
> +-----------
> +
> +**btrfs tune** returns a zero exit status if it succeeds. A non-zero value is
> +returned in case of failure.
> +
> +AVAILABILITY
> +------------
> +
> +**btrfs** is part of btrfs-progs. Please refer to the documentation at
> +`https://btrfs.readthedocs.io <https://btrfs.readthedocs.io>`_.
> +
> +SEE ALSO
> +--------
> +
> +:doc:`mkfs.btrfs`,
> +``mount(8)``
> diff --git a/Documentation/btrfs.rst b/Documentation/btrfs.rst
> index e878f158aaa1..5aea0d1a208c 100644
> --- a/Documentation/btrfs.rst
> +++ b/Documentation/btrfs.rst
> @@ -134,6 +134,10 @@ subvolume
> Create/delete/list/manage btrfs subvolume.
> See :doc:`btrfs-subvolume` for details.
>
> +tune
> + Change various btrfs features.
> + See :doc:`btrfs-tune` for details.
> +
> .. _man-btrfs8-standalone-tools:
>
> STANDALONE TOOLS
> @@ -150,6 +154,7 @@ btrfs-convert
> in-place conversion from ext2/3/4 filesystems to btrfs
> btrfstune
> tweak some filesystem properties on a unmounted filesystem
> + (will be replaced by `btrfs-tune`)
> btrfs-select-super
> rescue tool to overwrite primary superblock from a spare copy
> btrfs-find-root
> diff --git a/Documentation/conf.py b/Documentation/conf.py
> index 1025e10d7206..e0801bca4686 100644
> --- a/Documentation/conf.py
> +++ b/Documentation/conf.py
> @@ -66,6 +66,7 @@ man_pages = [
> ('btrfs-check', 'btrfs-check', 'check or repair a btrfs filesystem', '', 8),
> ('btrfs-balance', 'btrfs-balance', 'balance block groups on a btrfs filesystem', '', 8),
> ('btrfs-subvolume', 'btrfs-subvolume', 'manage btrfs subvolumes', '', 8),
> + ('btrfs-tune', 'btrfs-tune', 'tweak btrfs features', '', 8),
> ('btrfs-map-logical', 'btrfs-map-logical', 'map btrfs logical extent to physical extent', '', 8),
> ('btrfs', 'btrfs', 'a toolbox to manage btrfs filesystems', '', 8),
> ('mkfs.btrfs', 'mkfs.btrfs', 'create a btrfs filesystem', '', 8),
> diff --git a/Documentation/man-index.rst b/Documentation/man-index.rst
> index 36d45d2903ea..5fcd4cbc4bee 100644
> --- a/Documentation/man-index.rst
> +++ b/Documentation/man-index.rst
> @@ -28,6 +28,7 @@ Manual pages
> btrfs-select-super
> btrfs-send
> btrfs-subvolume
> + btrfs-tune
> btrfstune
> fsck.btrfs
> mkfs.btrfs
> diff --git a/Makefile b/Makefile
> index f4feb1fff8e1..9857daaa42ac 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -239,7 +239,7 @@ cmds_objects = cmds/subvolume.o cmds/subvolume-list.o \
> cmds/rescue-super-recover.o \
> cmds/property.o cmds/filesystem-usage.o cmds/inspect-dump-tree.o \
> cmds/inspect-dump-super.o cmds/inspect-tree-stats.o cmds/filesystem-du.o \
> - cmds/reflink.o \
> + cmds/reflink.o cmds/tune.o \
> mkfs/common.o check/mode-common.o check/mode-lowmem.o \
> check/clear-cache.o
>
> diff --git a/btrfs.c b/btrfs.c
> index 751f193ee2e0..c2dae0303ffe 100644
> --- a/btrfs.c
> +++ b/btrfs.c
> @@ -389,6 +389,7 @@ static const struct cmd_group btrfs_cmd_group = {
> &cmd_struct_scrub,
> &cmd_struct_send,
> &cmd_struct_subvolume,
> + &cmd_struct_tune,
>
> /* Help and version stay last */
> &cmd_struct_help,
> diff --git a/cmds/commands.h b/cmds/commands.h
> index 5ab7c881f634..aebacd718a7b 100644
> --- a/cmds/commands.h
> +++ b/cmds/commands.h
> @@ -151,5 +151,6 @@ DECLARE_COMMAND(qgroup);
> DECLARE_COMMAND(replace);
> DECLARE_COMMAND(restore);
> DECLARE_COMMAND(rescue);
> +DECLARE_COMMAND(tune);
>
> #endif
> diff --git a/cmds/tune.c b/cmds/tune.c
> new file mode 100644
> index 000000000000..92c7b9f1502c
> --- /dev/null
> +++ b/cmds/tune.c
> @@ -0,0 +1,227 @@
> +/*
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public
> + * License v2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public
> + * License along with this program; if not, write to the
> + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> + * Boston, MA 021110-1307, USA.
> + */
> +
> +#include <unistd.h>
> +#include "kerncompat.h"
> +#include "cmds/commands.h"
> +#include "common/help.h"
> +#include "common/fsfeatures.h"
> +#include "kernel-shared/messages.h"
> +#include "kernel-shared/disk-io.h"
> +#include "kernel-shared/transaction.h"
> +
> +static const char * const cmd_tune_set_usage[] = {
> + "btrfs tune set <feature> [<device>]",
> + "Set/enable specified feature for the unmounted filesystem",
> + "",
> + HELPINFO_INSERT_GLOBALS,
> + HELPINFO_INSERT_VERBOSE,
> + NULL,
> +};
> +
> +static const struct btrfs_feature set_features[] = {
> + {
> + .name = "extref",
> + .incompat_flag = BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF,
> + .sysfs_name = "extended_iref",
> + VERSION_TO_STRING2(compat, 3,7),
> + VERSION_TO_STRING2(safe, 3,12),
> + VERSION_TO_STRING2(default, 3,12),
> + .desc = "increased hardlink limit per file to 65536"
> + }, {
> + .name = "skinny-metadata",
> + .incompat_flag = BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA,
> + .sysfs_name = "skinny_metadata",
> + VERSION_TO_STRING2(compat, 3,10),
> + VERSION_TO_STRING2(safe, 3,18),
> + VERSION_TO_STRING2(default, 3,18),
> + .desc = "reduced-size metadata extent refs"
> + }, {
> + .name = "no-holes",
> + .incompat_flag = BTRFS_FEATURE_INCOMPAT_NO_HOLES,
> + .sysfs_name = "no_holes",
> + VERSION_TO_STRING2(compat, 3,14),
> + VERSION_TO_STRING2(safe, 4,0),
> + VERSION_TO_STRING2(default, 5,15),
> + .desc = "no explicit hole extents for files"
> + },
> + /* Keep this one last */
> + {
> + .name = "list-all",
> + .runtime_flag = BTRFS_FEATURE_RUNTIME_LIST_ALL,
> + .sysfs_name = NULL,
> + VERSION_NULL(compat),
> + VERSION_NULL(safe),
> + VERSION_NULL(default),
> + .desc = NULL
> + }
> +};
> +
> +static void list_all_features(const char *prefix,
> + const struct btrfs_feature *features,
> + int nr_features)
> +{
> + /* We should have at least one empty feature. */
> + ASSERT(nr_features > 1);
> +
> + printf("features available to %s:\n", prefix);
> + for (int i = 0; i < nr_features - 1; i++) {
> + const struct btrfs_feature *feat = features + i;
> + const char *sep = "";
> +
> + fprintf(stderr, "%-20s- %s (", feat->name, feat->desc);
> + if (feat->compat_ver) {
> + fprintf(stderr, "compat=%s", feat->compat_str);
> + sep = ", ";
> + }
> + if (feat->safe_ver) {
> + fprintf(stderr, "%ssafe=%s", sep, feat->safe_str);
> + sep = ", ";
> + }
> + if (feat->default_ver)
> + fprintf(stderr, "%sdefault=%s", sep, feat->default_str);
> + fprintf(stderr, ")\n");
> + }
> +}
> +
> +static int check_features(const char *name, const struct btrfs_feature *features,
> + int nr_features)
> +{
> + bool found = false;
> +
> + for (int i = 0; i < nr_features; i++) {
> + const struct btrfs_feature *feat = features + i;
> +
> + if (!strcmp(feat->name, name)) {
> + found = true;
> + break;
> + }
> + }
> + if (found)
> + return 0;
> + return -EINVAL;
> +}
> +
> +static int set_super_incompat_flags(struct btrfs_fs_info *fs_info, u64 flags)
> +{
> + struct btrfs_root *root = fs_info->tree_root;
> + struct btrfs_trans_handle *trans;
> + struct btrfs_super_block *disk_super;
> + u64 super_flags;
> + int ret;
> +
> + disk_super = fs_info->super_copy;
> + super_flags = btrfs_super_incompat_flags(disk_super);
> + super_flags |= flags;
> + trans = btrfs_start_transaction(root, 1);
> + BUG_ON(IS_ERR(trans));
> + btrfs_set_super_incompat_flags(disk_super, super_flags);
> + ret = btrfs_commit_transaction(trans, root);
> +
> + return ret;
> +}
> +
> +static int cmd_tune_set(const struct cmd_struct *cmd, int argc, char **argv)
> +{
> + struct btrfs_fs_info *fs_info;
> + struct open_ctree_args oca = { 0 };
> + char *feature;
> + char *path;
> + int ret = 0;
> +
> + optind = 0;
> + while (1) {
> + int c = getopt(argc, argv, "");
> + if (c < 0)
> + break;
> +
> + switch (c) {
> + default:
> + usage_unknown_option(cmd, argv);
> + }
> + }
> +
> + if (check_argc_min(argc - optind, 1))
> + return 1;
> +
> + feature = argv[optind];
> +
> + if (check_features(feature, set_features, ARRAY_SIZE(set_features))) {
> + error("Unknown feature to set: %s", feature);
> + return 1;
> + }
> + if (!strcmp(feature, "list-all")) {
> + list_all_features("set", set_features, ARRAY_SIZE(set_features));
> + return 0;
> + }
> +
> + if (check_argc_exact(argc - optind, 2))
> + return 1;
> +
> + path = argv[optind + 1];
> + oca.flags = OPEN_CTREE_WRITES;
> + oca.filename = path;
> + fs_info = open_ctree_fs_info(&oca);
> + if (!fs_info) {
> + error("failed to open btrfs");
> + ret = -EIO;
> + goto out;
> + }
> + /*
> + * For those 3 features, we only need to update the superblock to add
> + * the new feature flags.
> + */
> + if (!strcmp(feature, "extref") ||
> + !strcmp(feature, "skinny-metadata") ||
> + !strcmp(feature, "no-holes")) {
> + u64 incompat_flags = 0;
> +
> + if (!strcmp(feature, "extref"))
> + incompat_flags |= BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF;
> + if (!strcmp(feature, "skinny-metadata"))
> + incompat_flags |= BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA;
> + if (!strcmp(feature, "no-holes"))
> + incompat_flags |= BTRFS_FEATURE_INCOMPAT_NO_HOLES;
> + ret = set_super_incompat_flags(fs_info, incompat_flags);
> + if (ret < 0) {
> + errno = -ret;
> + error("failed to set feature '%s': %m", feature);
> + }
> + goto out;
> + }
> +
> +out:
> + if (fs_info)
> + close_ctree_fs_info(fs_info);
> + return !!ret;
> +}
> +
> +static DEFINE_SIMPLE_COMMAND(tune_set, "set");
> +
> +static const char * const tune_cmd_group_usage[] = {
> + "btrfs tune <command> <args>",
> + NULL,
> +};
> +
> +static const char tune_cmd_group_info[] = "change various btrfs features";
> +
> +static const struct cmd_group tune_cmd_group = {
> + tune_cmd_group_usage, tune_cmd_group_info, {
> + &cmd_struct_tune_set,
> + NULL
> + }
> +};
> +DEFINE_GROUP_COMMAND_TOKEN(tune);
next prev parent reply other threads:[~2023-09-21 0:53 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-05 7:51 [PATCH 0/7] btrfs-progs: cmds/tune: add set/clear features Qu Wenruo
2023-09-05 7:51 ` [PATCH 1/7] btrfs-progs: export btrfs_feature structure Qu Wenruo
2023-09-21 0:32 ` Anand Jain
2023-09-21 21:35 ` Qu Wenruo
2023-09-05 7:51 ` [PATCH 2/7] btrfs-progs: cmds: add "btrfs tune set" subcommand group Qu Wenruo
2023-09-21 0:53 ` Anand Jain [this message]
2023-09-21 2:13 ` Qu Wenruo
2023-10-13 17:47 ` David Sterba
2023-10-30 8:26 ` Anand Jain
2023-09-05 7:51 ` [PATCH 3/7] btrfs-progs: cmds/tune: add set support for free-space-tree feature Qu Wenruo
2023-09-05 7:51 ` [PATCH 4/7] btrfs-progs: cmds/tune: add set support for block-group-tree feature Qu Wenruo
2023-09-05 7:51 ` [PATCH 5/7] btrfs-progs: cmds/tune: add set support for seeding device Qu Wenruo
2023-09-05 7:51 ` [PATCH 6/7] btrfs-progs: cmds/tune: add "btrfs tune clear" subcommand Qu Wenruo
2023-09-05 7:51 ` [PATCH 7/7] btrfs-progs: tests/cli: add a test case for "btrfs tune" subcommand Qu Wenruo
2023-09-20 23:03 ` [PATCH 0/7] btrfs-progs: cmds/tune: add set/clear features Qu Wenruo
2023-09-21 22:33 ` waxhead
2023-09-21 22:53 ` Qu Wenruo
2023-10-13 17:55 ` David Sterba
2023-10-13 18:50 ` David Sterba
2023-10-13 20:53 ` Qu Wenruo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2adb8c79-d1d2-dffa-dd6b-5254d75c9c86@oracle.com \
--to=anand.jain@oracle.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=wqu@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).