btrfs-progs: tune: add --convert-to-free-space-tree option
From the very beginning of free-space-tree feature, we allow mount option "space_cache=v2" to convert the filesystem to the new feature. But this is not the proper practice for new features (no matter if it's incompat or compat_ro). This is already making the clear_cache/space_cache mount option more complex. Thus this patch introduces the proper way to enable free-space-tree, and I hope one day we can deprecate the "space_cache=" mount option. Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
6fc223f0a0
commit
d4f4d7b76e
|
@ -37,6 +37,11 @@ OPTIONS
|
||||||
Convert block groups tracked in standalone block group tree back to
|
Convert block groups tracked in standalone block group tree back to
|
||||||
extent tree and remove 'block-group-tree' feature bit from the filesystem.
|
extent tree and remove 'block-group-tree' feature bit from the filesystem.
|
||||||
|
|
||||||
|
--convert-to-free-space-tree
|
||||||
|
(since kernel 4.5)
|
||||||
|
|
||||||
|
Convert to free-space-tree feature (v2 of space cache).
|
||||||
|
|
||||||
-f
|
-f
|
||||||
Allow dangerous changes, e.g. clear the seeding flag or change fsid.
|
Allow dangerous changes, e.g. clear the seeding flag or change fsid.
|
||||||
Make sure that you are aware of the dangers.
|
Make sure that you are aware of the dangers.
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -250,7 +250,7 @@ convert_objects = convert/main.o convert/common.o convert/source-fs.o \
|
||||||
mkfs_objects = mkfs/main.o mkfs/common.o mkfs/rootdir.o
|
mkfs_objects = mkfs/main.o mkfs/common.o mkfs/rootdir.o
|
||||||
image_objects = image/main.o image/sanitize.o
|
image_objects = image/main.o image/sanitize.o
|
||||||
tune_objects = tune/main.o tune/seeding.o tune/change-uuid.o tune/change-metadata-uuid.o \
|
tune_objects = tune/main.o tune/seeding.o tune/change-uuid.o tune/change-metadata-uuid.o \
|
||||||
tune/convert-bgt.o tune/change-csum.o
|
tune/convert-bgt.o tune/change-csum.o check/clear-cache.o
|
||||||
all_objects = $(objects) $(cmds_objects) $(libbtrfs_objects) $(convert_objects) \
|
all_objects = $(objects) $(cmds_objects) $(libbtrfs_objects) $(convert_objects) \
|
||||||
$(mkfs_objects) $(image_objects) $(tune_objects) $(libbtrfsutil_objects)
|
$(mkfs_objects) $(image_objects) $(tune_objects) $(libbtrfsutil_objects)
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
*/
|
*/
|
||||||
#define NR_BLOCK_GROUP_CLUSTER (16)
|
#define NR_BLOCK_GROUP_CLUSTER (16)
|
||||||
|
|
||||||
static int clear_free_space_cache(struct btrfs_fs_info *fs_info)
|
int btrfs_clear_v1_cache(struct btrfs_fs_info *fs_info)
|
||||||
{
|
{
|
||||||
struct btrfs_trans_handle *trans;
|
struct btrfs_trans_handle *trans;
|
||||||
struct btrfs_block_group *bg_cache;
|
struct btrfs_block_group *bg_cache;
|
||||||
|
@ -99,7 +99,7 @@ int do_clear_free_space_cache(struct btrfs_fs_info *fs_info, int clear_version)
|
||||||
warning(
|
warning(
|
||||||
"free space cache v2 detected, use --clear-space-cache v2, proceeding with clearing v1");
|
"free space cache v2 detected, use --clear-space-cache v2, proceeding with clearing v1");
|
||||||
|
|
||||||
ret = clear_free_space_cache(fs_info);
|
ret = btrfs_clear_v1_cache(fs_info);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
error("failed to clear free space cache");
|
error("failed to clear free space cache");
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
|
@ -21,6 +21,7 @@ struct btrfs_fs_info;
|
||||||
struct btrfs_root;
|
struct btrfs_root;
|
||||||
struct task_ctx;
|
struct task_ctx;
|
||||||
|
|
||||||
|
int btrfs_clear_v1_cache(struct btrfs_fs_info *fs_info);
|
||||||
int do_clear_free_space_cache(struct btrfs_fs_info *fs_info, int clear_version);
|
int do_clear_free_space_cache(struct btrfs_fs_info *fs_info, int clear_version);
|
||||||
int validate_free_space_cache(struct btrfs_root *root, struct task_ctx *task_ctx);
|
int validate_free_space_cache(struct btrfs_root *root, struct task_ctx *task_ctx);
|
||||||
int truncate_free_ino_items(struct btrfs_root *root);
|
int truncate_free_ino_items(struct btrfs_root *root);
|
||||||
|
|
56
tune/main.c
56
tune/main.c
|
@ -28,6 +28,8 @@
|
||||||
#include "kernel-shared/disk-io.h"
|
#include "kernel-shared/disk-io.h"
|
||||||
#include "kernel-shared/transaction.h"
|
#include "kernel-shared/transaction.h"
|
||||||
#include "kernel-shared/volumes.h"
|
#include "kernel-shared/volumes.h"
|
||||||
|
#include "kernel-shared/free-space-cache.h"
|
||||||
|
#include "kernel-shared/free-space-tree.h"
|
||||||
#include "common/utils.h"
|
#include "common/utils.h"
|
||||||
#include "common/open-utils.h"
|
#include "common/open-utils.h"
|
||||||
#include "common/parse-utils.h"
|
#include "common/parse-utils.h"
|
||||||
|
@ -38,6 +40,7 @@
|
||||||
#include "common/box.h"
|
#include "common/box.h"
|
||||||
#include "cmds/commands.h"
|
#include "cmds/commands.h"
|
||||||
#include "tune/tune.h"
|
#include "tune/tune.h"
|
||||||
|
#include "check/clear-cache.h"
|
||||||
|
|
||||||
static char *device;
|
static char *device;
|
||||||
static int force = 0;
|
static int force = 0;
|
||||||
|
@ -60,6 +63,36 @@ static int set_super_incompat_flags(struct btrfs_root *root, u64 flags)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int convert_to_fst(struct btrfs_fs_info *fs_info)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* We may have invalid old v2 cache, clear them first. */
|
||||||
|
if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
|
||||||
|
ret = btrfs_clear_free_space_tree(fs_info);
|
||||||
|
if (ret < 0) {
|
||||||
|
errno = -ret;
|
||||||
|
error("failed to clear stale v2 free space cache: %m");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = btrfs_clear_v1_cache(fs_info);
|
||||||
|
if (ret < 0) {
|
||||||
|
errno = -ret;
|
||||||
|
error("failed to clear v1 free space cache: %m");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = btrfs_create_free_space_tree(fs_info);
|
||||||
|
if (ret < 0) {
|
||||||
|
errno = -ret;
|
||||||
|
error("failed to create free space tree: %m");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
pr_verbose(LOG_DEFAULT, "Converted to free space tree feature\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static const char * const tune_usage[] = {
|
static const char * const tune_usage[] = {
|
||||||
"btrfstune [options] device",
|
"btrfstune [options] device",
|
||||||
"Tune settings of filesystem features on an unmounted device",
|
"Tune settings of filesystem features on an unmounted device",
|
||||||
|
@ -74,6 +107,7 @@ static const char * const tune_usage[] = {
|
||||||
"the separate block-group-tree instead of extent tree (sets the incompat bit)"),
|
"the separate block-group-tree instead of extent tree (sets the incompat bit)"),
|
||||||
OPTLINE("--convert-from-block-group-tree",
|
OPTLINE("--convert-from-block-group-tree",
|
||||||
"convert the block group tree back to extent tree (remove the incompat bit)"),
|
"convert the block group tree back to extent tree (remove the incompat bit)"),
|
||||||
|
OPTLINE("--convert-to-free-space-tree", "convert filesystem to use free space tree (v2 cache)"),
|
||||||
"",
|
"",
|
||||||
"UUID changes:",
|
"UUID changes:",
|
||||||
OPTLINE("-u", "rewrite fsid, use a random one"),
|
OPTLINE("-u", "rewrite fsid, use a random one"),
|
||||||
|
@ -108,6 +142,7 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
|
||||||
int change_metadata_uuid = 0;
|
int change_metadata_uuid = 0;
|
||||||
bool to_extent_tree = false;
|
bool to_extent_tree = false;
|
||||||
bool to_bg_tree = false;
|
bool to_bg_tree = false;
|
||||||
|
bool to_fst = false;
|
||||||
int csum_type = -1;
|
int csum_type = -1;
|
||||||
char *new_fsid_str = NULL;
|
char *new_fsid_str = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -119,13 +154,16 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
|
||||||
while(1) {
|
while(1) {
|
||||||
enum { GETOPT_VAL_CSUM = GETOPT_VAL_FIRST,
|
enum { GETOPT_VAL_CSUM = GETOPT_VAL_FIRST,
|
||||||
GETOPT_VAL_ENABLE_BLOCK_GROUP_TREE,
|
GETOPT_VAL_ENABLE_BLOCK_GROUP_TREE,
|
||||||
GETOPT_VAL_DISABLE_BLOCK_GROUP_TREE };
|
GETOPT_VAL_DISABLE_BLOCK_GROUP_TREE,
|
||||||
|
GETOPT_VAL_ENABLE_FREE_SPACE_TREE };
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{ "help", no_argument, NULL, GETOPT_VAL_HELP},
|
{ "help", no_argument, NULL, GETOPT_VAL_HELP},
|
||||||
{ "convert-to-block-group-tree", no_argument, NULL,
|
{ "convert-to-block-group-tree", no_argument, NULL,
|
||||||
GETOPT_VAL_ENABLE_BLOCK_GROUP_TREE},
|
GETOPT_VAL_ENABLE_BLOCK_GROUP_TREE},
|
||||||
{ "convert-from-block-group-tree", no_argument, NULL,
|
{ "convert-from-block-group-tree", no_argument, NULL,
|
||||||
GETOPT_VAL_DISABLE_BLOCK_GROUP_TREE},
|
GETOPT_VAL_DISABLE_BLOCK_GROUP_TREE},
|
||||||
|
{ "convert-to-free-space-tree", no_argument, NULL,
|
||||||
|
GETOPT_VAL_ENABLE_FREE_SPACE_TREE},
|
||||||
#if EXPERIMENTAL
|
#if EXPERIMENTAL
|
||||||
{ "csum", required_argument, NULL, GETOPT_VAL_CSUM },
|
{ "csum", required_argument, NULL, GETOPT_VAL_CSUM },
|
||||||
#endif
|
#endif
|
||||||
|
@ -175,6 +213,9 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
|
||||||
case GETOPT_VAL_DISABLE_BLOCK_GROUP_TREE:
|
case GETOPT_VAL_DISABLE_BLOCK_GROUP_TREE:
|
||||||
to_extent_tree = true;
|
to_extent_tree = true;
|
||||||
break;
|
break;
|
||||||
|
case GETOPT_VAL_ENABLE_FREE_SPACE_TREE:
|
||||||
|
to_fst = true;
|
||||||
|
break;
|
||||||
#if EXPERIMENTAL
|
#if EXPERIMENTAL
|
||||||
case GETOPT_VAL_CSUM:
|
case GETOPT_VAL_CSUM:
|
||||||
btrfs_warn_experimental(
|
btrfs_warn_experimental(
|
||||||
|
@ -200,7 +241,7 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
if (!super_flags && !seeding_flag && !(random_fsid || new_fsid_str) &&
|
if (!super_flags && !seeding_flag && !(random_fsid || new_fsid_str) &&
|
||||||
!change_metadata_uuid && csum_type == -1 && !to_bg_tree &&
|
!change_metadata_uuid && csum_type == -1 && !to_bg_tree &&
|
||||||
!to_extent_tree) {
|
!to_extent_tree && !to_fst) {
|
||||||
error("at least one option should be specified");
|
error("at least one option should be specified");
|
||||||
usage(&tune_cmd, 1);
|
usage(&tune_cmd, 1);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -269,6 +310,17 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if (to_fst) {
|
||||||
|
if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE_VALID)) {
|
||||||
|
error("filesystem already has free-space-tree feature");
|
||||||
|
ret = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
ret = convert_to_fst(root->fs_info);
|
||||||
|
if (ret < 0)
|
||||||
|
error("failed to convert the filesystem to free-space-tree feature");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (to_extent_tree) {
|
if (to_extent_tree) {
|
||||||
if (to_bg_tree) {
|
if (to_bg_tree) {
|
||||||
error("option --convert-to-block-group-tree conflicts with --convert-from-block-group-tree");
|
error("option --convert-to-block-group-tree conflicts with --convert-from-block-group-tree");
|
||||||
|
|
Loading…
Reference in a new issue