mirror of
https://github.com/kdave/btrfs-progs
synced 2025-02-16 09:46:55 +00:00
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
|
||||
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
|
||||
Allow dangerous changes, e.g. clear the seeding flag or change fsid.
|
||||
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
|
||||
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/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) \
|
||||
$(mkfs_objects) $(image_objects) $(tune_objects) $(libbtrfsutil_objects)
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
*/
|
||||
#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_block_group *bg_cache;
|
||||
@ -99,7 +99,7 @@ int do_clear_free_space_cache(struct btrfs_fs_info *fs_info, int clear_version)
|
||||
warning(
|
||||
"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) {
|
||||
error("failed to clear free space cache");
|
||||
ret = 1;
|
||||
|
@ -21,6 +21,7 @@ struct btrfs_fs_info;
|
||||
struct btrfs_root;
|
||||
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 validate_free_space_cache(struct btrfs_root *root, struct task_ctx *task_ctx);
|
||||
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/transaction.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/open-utils.h"
|
||||
#include "common/parse-utils.h"
|
||||
@ -38,6 +40,7 @@
|
||||
#include "common/box.h"
|
||||
#include "cmds/commands.h"
|
||||
#include "tune/tune.h"
|
||||
#include "check/clear-cache.h"
|
||||
|
||||
static char *device;
|
||||
static int force = 0;
|
||||
@ -60,6 +63,36 @@ static int set_super_incompat_flags(struct btrfs_root *root, u64 flags)
|
||||
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[] = {
|
||||
"btrfstune [options] 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)"),
|
||||
OPTLINE("--convert-from-block-group-tree",
|
||||
"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:",
|
||||
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;
|
||||
bool to_extent_tree = false;
|
||||
bool to_bg_tree = false;
|
||||
bool to_fst = false;
|
||||
int csum_type = -1;
|
||||
char *new_fsid_str = NULL;
|
||||
int ret;
|
||||
@ -119,13 +154,16 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
|
||||
while(1) {
|
||||
enum { GETOPT_VAL_CSUM = GETOPT_VAL_FIRST,
|
||||
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[] = {
|
||||
{ "help", no_argument, NULL, GETOPT_VAL_HELP},
|
||||
{ "convert-to-block-group-tree", no_argument, NULL,
|
||||
GETOPT_VAL_ENABLE_BLOCK_GROUP_TREE},
|
||||
{ "convert-from-block-group-tree", no_argument, NULL,
|
||||
GETOPT_VAL_DISABLE_BLOCK_GROUP_TREE},
|
||||
{ "convert-to-free-space-tree", no_argument, NULL,
|
||||
GETOPT_VAL_ENABLE_FREE_SPACE_TREE},
|
||||
#if EXPERIMENTAL
|
||||
{ "csum", required_argument, NULL, GETOPT_VAL_CSUM },
|
||||
#endif
|
||||
@ -175,6 +213,9 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
|
||||
case GETOPT_VAL_DISABLE_BLOCK_GROUP_TREE:
|
||||
to_extent_tree = true;
|
||||
break;
|
||||
case GETOPT_VAL_ENABLE_FREE_SPACE_TREE:
|
||||
to_fst = true;
|
||||
break;
|
||||
#if EXPERIMENTAL
|
||||
case GETOPT_VAL_CSUM:
|
||||
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) &&
|
||||
!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");
|
||||
usage(&tune_cmd, 1);
|
||||
return 1;
|
||||
@ -269,6 +310,17 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
|
||||
}
|
||||
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_bg_tree) {
|
||||
error("option --convert-to-block-group-tree conflicts with --convert-from-block-group-tree");
|
||||
|
Loading…
Reference in New Issue
Block a user