@@ -21,6 +21,13 @@ set <feature> [<device>]
If *feature* is `list-all`, all supported features would be listed, and
no *device* parameter is needed.
+clear <feature> [<device>]
+ Set/enable a feature.
+
+ If *feature* is `list-all`, all supported features would be listed, and
+ no *device* parameter is needed. And the listed features may be different
+ compared to the ones from `btrfs tune set list-all`.
+
EXIT STATUS
-----------
@@ -321,6 +321,116 @@ out:
static DEFINE_SIMPLE_COMMAND(tune_set, "set");
+static const struct btrfs_feature clear_features[] = {
+ {
+ .name = "block-group-tree",
+ .compat_ro_flag = BTRFS_FEATURE_COMPAT_RO_BLOCK_GROUP_TREE,
+ .sysfs_name = "block_group_tree",
+ VERSION_TO_STRING2(compat, 6,1),
+ VERSION_NULL(safe),
+ VERSION_NULL(default),
+ .desc = "block group tree to reduce mount time"
+ }, {
+ .name = "seed",
+ .sysfs_name = NULL,
+ VERSION_TO_STRING3(compat, 2,6,29),
+ VERSION_NULL(safe),
+ VERSION_NULL(default),
+ .desc = "seeding device support"
+ },
+ /* 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 int cmd_tune_clear(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, "f");
+ 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, clear_features, ARRAY_SIZE(clear_features))) {
+ error("Unknown feature to clear: %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;
+ }
+ if (!strcmp(feature, "seed")) {
+ ret = update_seeding_flag(fs_info->tree_root, path, 0, 0);
+ goto out;
+ }
+ if (!strcmp(feature, "block-group-tree")) {
+ if (!btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE)) {
+ error("filesystem doesn't have block-group-tree feature");
+ ret = -EINVAL;
+ goto out;
+ }
+ ret = convert_to_extent_tree(fs_info);
+ if (ret < 0) {
+ error("failed to convert the filesystem from block group tree feature");
+ goto out;
+ }
+ goto out;
+ }
+out:
+ if (fs_info)
+ close_ctree_fs_info(fs_info);
+ return !!ret;
+}
+
+static const char * const cmd_tune_clear_usage[] = {
+ "btrfs tune clear <feature> [<device>]",
+ "Clear/disable specified feature for the unmounted filesystem",
+ "",
+ HELPINFO_INSERT_GLOBALS,
+ HELPINFO_INSERT_VERBOSE,
+ NULL,
+};
+
+static DEFINE_SIMPLE_COMMAND(tune_clear, "clear");
+
static const char * const tune_cmd_group_usage[] = {
"btrfs tune <command> <args>",
NULL,
@@ -331,6 +441,7 @@ 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,
+ &cmd_struct_tune_clear,
NULL
}
};
This new "btrfs tune clear" subcommand is mostly the same as "btrfs tune set", but with much less features supported: - seed - block-group-tree For the features in "btrfs tune set" but not in "btrfs tune clear", they are mostly default features now, and we won't support disabling those features anymore. Signed-off-by: Qu Wenruo <wqu@suse.com> --- Documentation/btrfs-tune.rst | 7 +++ cmds/tune.c | 111 +++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+)