From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 2/7] btrfs-progs: cmds: add "btrfs tune set" subcommand group
Date: Tue, 5 Sep 2023 15:51:44 +0800 [thread overview]
Message-ID: <1c294f739f028da499cf7f57deb334f419979097.1693900169.git.wqu@suse.com> (raw)
In-Reply-To: <cover.1693900169.git.wqu@suse.com>
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).
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);
--
2.42.0
next prev parent reply other threads:[~2023-09-05 16:03 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 ` Qu Wenruo [this message]
2023-09-21 0:53 ` [PATCH 2/7] btrfs-progs: cmds: add "btrfs tune set" subcommand group Anand Jain
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=1c294f739f028da499cf7f57deb334f419979097.1693900169.git.wqu@suse.com \
--to=wqu@suse.com \
--cc=linux-btrfs@vger.kernel.org \
/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).