* [PATCH 0/3] btrfs-progs: add the ability to enable fst for btrfstune
@ 2023-05-02 1:01 Qu Wenruo
2023-05-02 1:01 ` [PATCH 1/3] btrfs-progs: make check/clear-cache.c to be separate from check/main.c Qu Wenruo
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Qu Wenruo @ 2023-05-02 1:01 UTC (permalink / raw)
To: linux-btrfs
At the beginning of free space tree feature, it's enabled by
"space_cache=v2" mount option.
However this introduced some problems:
- Lack of proper v1 cache clearing in the past
In the past we didn't properly clear v1 cache before enabling v2.
- More and more complex v2 cache dependency
Extent tree v2 and bgt all depend on v2 cache, but we have some
mount options like clear_cache can screw this up.
Instead introducing some mount options to tinkering the filesystem
features (either compat_ro or incompat), we should always go through
btrfstune to enable new features (just like what we did in bgt).
This allows us to move the heavy lifting and proper checks into
btrfs-progs.
Although it's already late, it's still better than never, thus this
patchset introduce the --convert-to-free-space-tree feature to
btrfstune.
Unlike bgt, v1 cache is going to fade out soon, thus no rollback
functionality provided.
I hope we can deprecate the "space_cache=" mount option soon.
Qu Wenruo (3):
btrfs-progs: make check/clear-cache.c to be separate from check/main.c
btrfs-progs: tune: add --convert-to-free-space-tree option
btrfs-progs: misc-tests: add test case to verify btrfstune
--convert-to-free-space-tree option
Documentation/btrfstune.rst | 5 ++
Makefile | 2 +-
check/clear-cache.c | 84 ++++++++++---------
check/clear-cache.h | 9 +-
check/main.c | 6 +-
.../057-btrfstune-free-space-tree/test.sh | 21 +++++
tune/main.c | 57 ++++++++++++-
7 files changed, 135 insertions(+), 49 deletions(-)
create mode 100755 tests/misc-tests/057-btrfstune-free-space-tree/test.sh
--
2.39.2
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/3] btrfs-progs: make check/clear-cache.c to be separate from check/main.c
2023-05-02 1:01 [PATCH 0/3] btrfs-progs: add the ability to enable fst for btrfstune Qu Wenruo
@ 2023-05-02 1:01 ` Qu Wenruo
2023-05-02 1:01 ` [PATCH 2/3] btrfs-progs: tune: add --convert-to-free-space-tree option Qu Wenruo
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Qu Wenruo @ 2023-05-02 1:01 UTC (permalink / raw)
To: linux-btrfs
Currently check/clear-cache.c still uses a lot of global variables like
gfs_info and g_task_ctx, which are only implemented in check/main.c.
Since we have separated clear-cache code into its own c and header files,
we should not utilize those global variables.
Or it would lead to compiling errors for any tools which only has
check/clear-cache.o linked:
/usr/bin/ld: check/clear-cache.o: in function `clear_free_space_cache':
/home/adam/btrfs/btrfs-progs/check/clear-cache.c:46: undefined reference to `gfs_info'
/usr/bin/ld: /home/adam/btrfs/btrfs-progs/check/clear-cache.c:56: undefined reference to `gfs_info'
/usr/bin/ld: /home/adam/btrfs/btrfs-progs/check/clear-cache.c:67: undefined reference to `gfs_info'
/usr/bin/ld: /home/adam/btrfs/btrfs-progs/check/clear-cache.c:73: undefined reference to `gfs_info'
/usr/bin/ld: /home/adam/btrfs/btrfs-progs/check/clear-cache.c:84: undefined reference to `gfs_info'
/usr/bin/ld: check/clear-cache.o:/home/adam/btrfs/btrfs-progs/check/clear-cache.c:85: more undefined references to `gfs_info' follow
/usr/bin/ld: check/clear-cache.o: in function `check_space_cache':
/home/adam/btrfs/btrfs-progs/check/clear-cache.c:357: undefined reference to `g_task_ctx'
/usr/bin/ld: /home/adam/btrfs/btrfs-progs/check/clear-cache.c:357: undefined reference to `g_task_ctx'
/usr/bin/ld: /home/adam/btrfs/btrfs-progs/check/clear-cache.c:358: undefined reference to `gfs_info'
/usr/bin/ld: /home/adam/btrfs/btrfs-progs/check/clear-cache.c:365: undefined reference to `gfs_info'
/usr/bin/ld: /home/adam/btrfs/btrfs-progs/check/clear-cache.c:373: undefined reference to `gfs_info'
/usr/bin/ld: /home/adam/btrfs/btrfs-progs/check/clear-cache.c:374: undefined reference to `gfs_info'
/usr/bin/ld: /home/adam/btrfs/btrfs-progs/check/clear-cache.c:382: undefined reference to `gfs_info'
/usr/bin/ld: check/clear-cache.o:/home/adam/btrfs/btrfs-progs/check/clear-cache.c:383: more undefined references to `gfs_info' follow
collect2: error: ld returned 1 exit status
This provides the basis for later clear cache usage out of check realm.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
check/clear-cache.c | 84 ++++++++++++++++++++++++---------------------
check/clear-cache.h | 8 +++--
check/main.c | 6 ++--
3 files changed, 52 insertions(+), 46 deletions(-)
diff --git a/check/clear-cache.c b/check/clear-cache.c
index 0a3001a4a6aa..772d920fd397 100644
--- a/check/clear-cache.c
+++ b/check/clear-cache.c
@@ -35,7 +35,7 @@
*/
#define NR_BLOCK_GROUP_CLUSTER (16)
-static int clear_free_space_cache(void)
+static int clear_free_space_cache(struct btrfs_fs_info *fs_info)
{
struct btrfs_trans_handle *trans;
struct btrfs_block_group *bg_cache;
@@ -43,7 +43,7 @@ static int clear_free_space_cache(void)
u64 current = 0;
int ret = 0;
- trans = btrfs_start_transaction(gfs_info->tree_root, 0);
+ trans = btrfs_start_transaction(fs_info->tree_root, 0);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
errno = -ret;
@@ -53,7 +53,7 @@ static int clear_free_space_cache(void)
/* Clear all free space cache inodes and its extent data */
while (1) {
- bg_cache = btrfs_lookup_first_block_group(gfs_info, current);
+ bg_cache = btrfs_lookup_first_block_group(fs_info, current);
if (!bg_cache)
break;
ret = btrfs_clear_free_space_cache(trans, bg_cache);
@@ -64,13 +64,13 @@ static int clear_free_space_cache(void)
nr_handled++;
if (nr_handled == NR_BLOCK_GROUP_CLUSTER) {
- ret = btrfs_commit_transaction(trans, gfs_info->tree_root);
+ ret = btrfs_commit_transaction(trans, fs_info->tree_root);
if (ret < 0) {
errno = -ret;
error_msg(ERROR_MSG_START_TRANS, "%m");
return ret;
}
- trans = btrfs_start_transaction(gfs_info->tree_root, 0);
+ trans = btrfs_start_transaction(fs_info->tree_root, 0);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
errno = -ret;
@@ -81,8 +81,8 @@ static int clear_free_space_cache(void)
current = bg_cache->start + bg_cache->length;
}
- btrfs_set_super_cache_generation(gfs_info->super_copy, (u64)-1);
- ret = btrfs_commit_transaction(trans, gfs_info->tree_root);
+ btrfs_set_super_cache_generation(fs_info->super_copy, (u64)-1);
+ ret = btrfs_commit_transaction(trans, fs_info->tree_root);
if (ret < 0) {
errno = -ret;
error_msg(ERROR_MSG_START_TRANS, "%m");
@@ -90,16 +90,17 @@ static int clear_free_space_cache(void)
return ret;
}
-int do_clear_free_space_cache(int clear_version)
+int do_clear_free_space_cache(struct btrfs_fs_info *fs_info,
+ int clear_version)
{
int ret = 0;
if (clear_version == 1) {
- if (btrfs_fs_compat_ro(gfs_info, FREE_SPACE_TREE))
+ if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))
warning(
"free space cache v2 detected, use --clear-space-cache v2, proceeding with clearing v1");
- ret = clear_free_space_cache();
+ ret = clear_free_space_cache(fs_info);
if (ret) {
error("failed to clear free space cache");
ret = 1;
@@ -107,13 +108,13 @@ int do_clear_free_space_cache(int clear_version)
printf("Free space cache cleared\n");
}
} else if (clear_version == 2) {
- if (!btrfs_fs_compat_ro(gfs_info, FREE_SPACE_TREE)) {
+ if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
printf("no free space cache v2 to clear\n");
ret = 0;
goto close_out;
}
printf("Clear free space cache v2\n");
- ret = btrfs_clear_free_space_tree(gfs_info);
+ ret = btrfs_clear_free_space_tree(fs_info);
if (ret) {
error("failed to clear free space cache v2: %d", ret);
ret = 1;
@@ -127,6 +128,7 @@ close_out:
static int check_free_space_tree(struct btrfs_root *root)
{
+ struct btrfs_fs_info *fs_info = root->fs_info;
struct btrfs_key key = { 0 };
struct btrfs_path path;
int ret = 0;
@@ -158,7 +160,7 @@ static int check_free_space_tree(struct btrfs_root *root)
goto out;
}
- bg = btrfs_lookup_first_block_group(gfs_info, key.objectid);
+ bg = btrfs_lookup_first_block_group(fs_info, key.objectid);
if (!bg) {
fprintf(stderr,
"We have a space info key for a block group that doesn't exist\n");
@@ -187,7 +189,7 @@ static int check_free_space_trees(struct btrfs_root *root)
};
int ret = 0;
- free_space_root = btrfs_global_root(gfs_info, &key);
+ free_space_root = btrfs_global_root(root->fs_info, &key);
while (1) {
ret = check_free_space_tree(free_space_root);
if (ret)
@@ -214,7 +216,7 @@ static int check_cache_range(struct btrfs_root *root,
for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
bytenr = btrfs_sb_offset(i);
- ret = btrfs_rmap_block(gfs_info,
+ ret = btrfs_rmap_block(root->fs_info,
cache->start, bytenr,
&logical, &nr, &stripe_len);
if (ret)
@@ -340,8 +342,9 @@ static int verify_space_cache(struct btrfs_root *root,
return ret;
}
-static int check_space_cache(struct btrfs_root *root)
+static int check_space_cache(struct btrfs_root *root, struct task_ctx *task_ctx)
{
+ struct btrfs_fs_info *fs_info = root->fs_info;
struct extent_io_tree used;
struct btrfs_block_group *cache;
u64 start = BTRFS_SUPER_INFO_OFFSET + BTRFS_SUPER_INFO_SIZE;
@@ -349,20 +352,20 @@ static int check_space_cache(struct btrfs_root *root)
int error = 0;
extent_io_tree_init(&used);
- ret = btrfs_mark_used_blocks(gfs_info, &used);
+ ret = btrfs_mark_used_blocks(fs_info, &used);
if (ret)
return ret;
while (1) {
- g_task_ctx.item_count++;
- cache = btrfs_lookup_first_block_group(gfs_info, start);
+ task_ctx->item_count++;
+ cache = btrfs_lookup_first_block_group(fs_info, start);
if (!cache)
break;
start = cache->start + cache->length;
if (!cache->free_space_ctl) {
if (btrfs_init_free_space_ctl(cache,
- gfs_info->sectorsize)) {
+ fs_info->sectorsize)) {
ret = -ENOMEM;
break;
}
@@ -370,8 +373,8 @@ static int check_space_cache(struct btrfs_root *root)
btrfs_remove_free_space_cache(cache);
}
- if (btrfs_fs_compat_ro(gfs_info, FREE_SPACE_TREE)) {
- ret = exclude_super_stripes(gfs_info, cache);
+ if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
+ ret = exclude_super_stripes(fs_info, cache);
if (ret) {
errno = -ret;
fprintf(stderr,
@@ -379,8 +382,8 @@ static int check_space_cache(struct btrfs_root *root)
error++;
continue;
}
- ret = load_free_space_tree(gfs_info, cache);
- free_excluded_extents(gfs_info, cache);
+ ret = load_free_space_tree(fs_info, cache);
+ free_excluded_extents(fs_info, cache);
if (ret < 0) {
errno = -ret;
fprintf(stderr,
@@ -390,7 +393,7 @@ static int check_space_cache(struct btrfs_root *root)
}
error += ret;
} else {
- ret = load_free_space_cache(gfs_info, cache);
+ ret = load_free_space_cache(fs_info, cache);
if (ret < 0)
error++;
if (ret <= 0)
@@ -409,33 +412,34 @@ static int check_space_cache(struct btrfs_root *root)
}
-int validate_free_space_cache(struct btrfs_root *root)
+int validate_free_space_cache(struct btrfs_root *root, struct task_ctx *task_ctx)
{
+ struct btrfs_fs_info *fs_info = root->fs_info;
int ret;
/*
* If cache generation is between 0 and -1ULL, sb generation must be
* equal to sb cache generation or the v1 space caches are outdated.
*/
- if (btrfs_super_cache_generation(gfs_info->super_copy) != -1ULL &&
- btrfs_super_cache_generation(gfs_info->super_copy) != 0 &&
- btrfs_super_generation(gfs_info->super_copy) !=
- btrfs_super_cache_generation(gfs_info->super_copy)) {
+ if (btrfs_super_cache_generation(fs_info->super_copy) != -1ULL &&
+ btrfs_super_cache_generation(fs_info->super_copy) != 0 &&
+ btrfs_super_generation(fs_info->super_copy) !=
+ btrfs_super_cache_generation(fs_info->super_copy)) {
printf(
"cache and super generation don't match, space cache will be invalidated\n");
return 0;
}
- ret = check_space_cache(root);
- if (!ret && btrfs_fs_compat_ro(gfs_info, FREE_SPACE_TREE))
+ ret = check_space_cache(root, task_ctx);
+ if (!ret && btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))
ret = check_free_space_trees(root);
- if (ret && btrfs_fs_compat_ro(gfs_info, FREE_SPACE_TREE) &&
+ if (ret && btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
opt_check_repair) {
- ret = do_clear_free_space_cache(2);
+ ret = do_clear_free_space_cache(fs_info, 2);
if (ret)
goto out;
- ret = btrfs_create_free_space_tree(gfs_info);
+ ret = btrfs_create_free_space_tree(fs_info);
if (ret)
error("couldn't repair freespace tree");
}
@@ -539,7 +543,7 @@ out:
return ret;
}
-int clear_ino_cache_items(void)
+int clear_ino_cache_items(struct btrfs_fs_info *fs_info)
{
int ret;
struct btrfs_path path;
@@ -550,7 +554,7 @@ int clear_ino_cache_items(void)
key.offset = 0;
btrfs_init_path(&path);
- ret = btrfs_search_slot(NULL, gfs_info->tree_root, &key, &path, 0, 0);
+ ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, &path, 0, 0);
if (ret < 0)
return ret;
@@ -563,7 +567,7 @@ int clear_ino_cache_items(void)
struct btrfs_root *root;
found_key.offset = (u64)-1;
- root = btrfs_read_fs_root(gfs_info, &found_key);
+ root = btrfs_read_fs_root(fs_info, &found_key);
if (IS_ERR(root))
goto next;
ret = truncate_free_ino_items(root);
@@ -586,12 +590,12 @@ next:
if (key.objectid == BTRFS_FS_TREE_OBJECTID) {
key.objectid = BTRFS_FIRST_FREE_OBJECTID;
btrfs_release_path(&path);
- ret = btrfs_search_slot(NULL, gfs_info->tree_root, &key,
+ ret = btrfs_search_slot(NULL, fs_info->tree_root, &key,
&path, 0, 0);
if (ret < 0)
return ret;
} else {
- ret = btrfs_next_item(gfs_info->tree_root, &path);
+ ret = btrfs_next_item(fs_info->tree_root, &path);
if (ret < 0) {
goto out;
} else if (ret > 0) {
diff --git a/check/clear-cache.h b/check/clear-cache.h
index b8b71a89df93..78845e8d9557 100644
--- a/check/clear-cache.h
+++ b/check/clear-cache.h
@@ -17,11 +17,13 @@
#ifndef __BTRFS_CHECK_CLEAR_CACHE_H__
#define __BTRFS_CHECK_CLEAR_CACHE_H__
+struct btrfs_fs_info;
struct btrfs_root;
+struct task_ctx;
-int do_clear_free_space_cache(int clear_version);
-int validate_free_space_cache(struct btrfs_root *root);
+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);
-int clear_ino_cache_items(void);
+int clear_ino_cache_items(struct btrfs_fs_info *fs_info);
#endif
diff --git a/check/main.c b/check/main.c
index 523d800fae2f..1a09701dd898 100644
--- a/check/main.c
+++ b/check/main.c
@@ -10237,13 +10237,13 @@ static int cmd_check(const struct cmd_struct *cmd, int argc, char **argv)
}
if (clear_space_cache) {
- ret = do_clear_free_space_cache(clear_space_cache);
+ ret = do_clear_free_space_cache(gfs_info, clear_space_cache);
err |= !!ret;
goto close_out;
}
if (clear_ino_cache) {
- ret = clear_ino_cache_items();
+ ret = clear_ino_cache_items(gfs_info);
err = ret;
goto close_out;
}
@@ -10409,7 +10409,7 @@ static int cmd_check(const struct cmd_struct *cmd, int argc, char **argv)
task_start(g_task_ctx.info, &g_task_ctx.start_time, &g_task_ctx.item_count);
}
- ret = validate_free_space_cache(root);
+ ret = validate_free_space_cache(root, &g_task_ctx);
task_stop(g_task_ctx.info);
err |= !!ret;
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] btrfs-progs: tune: add --convert-to-free-space-tree option
2023-05-02 1:01 [PATCH 0/3] btrfs-progs: add the ability to enable fst for btrfstune Qu Wenruo
2023-05-02 1:01 ` [PATCH 1/3] btrfs-progs: make check/clear-cache.c to be separate from check/main.c Qu Wenruo
@ 2023-05-02 1:01 ` Qu Wenruo
2023-05-02 1:01 ` [PATCH 3/3] btrfs-progs: misc-tests: add test case to verify btrfstune " Qu Wenruo
2023-05-02 18:25 ` [PATCH 0/3] btrfs-progs: add the ability to enable fst for btrfstune David Sterba
3 siblings, 0 replies; 5+ messages in thread
From: Qu Wenruo @ 2023-05-02 1:01 UTC (permalink / raw)
To: linux-btrfs
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>
---
Documentation/btrfstune.rst | 5 ++++
Makefile | 2 +-
check/clear-cache.c | 4 +--
check/clear-cache.h | 1 +
tune/main.c | 57 +++++++++++++++++++++++++++++++++++--
5 files changed, 64 insertions(+), 5 deletions(-)
diff --git a/Documentation/btrfstune.rst b/Documentation/btrfstune.rst
index d3543a47012e..9907c0535e4e 100644
--- a/Documentation/btrfstune.rst
+++ b/Documentation/btrfstune.rst
@@ -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 cache feature (v2 space cache).
+
-f
Allow dangerous changes, e.g. clear the seeding flag or change fsid.
Make sure that you are aware of the dangers.
diff --git a/Makefile b/Makefile
index 4b0a869b6ca5..b03367f26158 100644
--- a/Makefile
+++ b/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)
diff --git a/check/clear-cache.c b/check/clear-cache.c
index 772d920fd397..8d06640cb826 100644
--- a/check/clear-cache.c
+++ b/check/clear-cache.c
@@ -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;
@@ -100,7 +100,7 @@ int do_clear_free_space_cache(struct btrfs_fs_info *fs_info,
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;
diff --git a/check/clear-cache.h b/check/clear-cache.h
index 78845e8d9557..1cdf49051244 100644
--- a/check/clear-cache.h
+++ b/check/clear-cache.h
@@ -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);
diff --git a/tune/main.c b/tune/main.c
index 891bea14ee5e..55ecae784ada 100644
--- a/tune/main.c
+++ b/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;
+ }
+ printf("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",
@@ -75,6 +108,8 @@ static const char * const tune_usage[] = {
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"),
OPTLINE("-U UUID", "rewrite fsid to UUID"),
@@ -108,6 +143,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 +155,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 +214,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 +242,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 +311,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");
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] btrfs-progs: misc-tests: add test case to verify btrfstune --convert-to-free-space-tree option
2023-05-02 1:01 [PATCH 0/3] btrfs-progs: add the ability to enable fst for btrfstune Qu Wenruo
2023-05-02 1:01 ` [PATCH 1/3] btrfs-progs: make check/clear-cache.c to be separate from check/main.c Qu Wenruo
2023-05-02 1:01 ` [PATCH 2/3] btrfs-progs: tune: add --convert-to-free-space-tree option Qu Wenruo
@ 2023-05-02 1:01 ` Qu Wenruo
2023-05-02 18:25 ` [PATCH 0/3] btrfs-progs: add the ability to enable fst for btrfstune David Sterba
3 siblings, 0 replies; 5+ messages in thread
From: Qu Wenruo @ 2023-05-02 1:01 UTC (permalink / raw)
To: linux-btrfs
The new test case would create a fs without free space tree, then
popluate it, convert to free-space-tree feature, and make sure
everything is fine.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
.../057-btrfstune-free-space-tree/test.sh | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100755 tests/misc-tests/057-btrfstune-free-space-tree/test.sh
diff --git a/tests/misc-tests/057-btrfstune-free-space-tree/test.sh b/tests/misc-tests/057-btrfstune-free-space-tree/test.sh
new file mode 100755
index 000000000000..c69f99cfbd38
--- /dev/null
+++ b/tests/misc-tests/057-btrfstune-free-space-tree/test.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# test btrfstune --convert-to-free-space-tree option
+
+source "$TEST_TOP/common" || exit
+source "$TEST_TOP/common.convert" || exit
+
+check_prereq mkfs.btrfs
+check_prereq btrfstune
+check_prereq btrfs
+
+setup_root_helper
+prepare_test_dev
+
+run_check_mkfs_test_dev -O ^free-space-tree
+run_check_mount_test_dev
+populate_fs
+run_check_umount_test_dev
+
+run_check $SUDO_HELPER "$TOP/btrfstune" --convert-to-free-space-tree $TEST_DEV
+
+run_check "$TOP/btrfs" check "$TEST_DEV"
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 0/3] btrfs-progs: add the ability to enable fst for btrfstune
2023-05-02 1:01 [PATCH 0/3] btrfs-progs: add the ability to enable fst for btrfstune Qu Wenruo
` (2 preceding siblings ...)
2023-05-02 1:01 ` [PATCH 3/3] btrfs-progs: misc-tests: add test case to verify btrfstune " Qu Wenruo
@ 2023-05-02 18:25 ` David Sterba
3 siblings, 0 replies; 5+ messages in thread
From: David Sterba @ 2023-05-02 18:25 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs
On Tue, May 02, 2023 at 09:01:43AM +0800, Qu Wenruo wrote:
> At the beginning of free space tree feature, it's enabled by
> "space_cache=v2" mount option.
>
> However this introduced some problems:
>
> - Lack of proper v1 cache clearing in the past
> In the past we didn't properly clear v1 cache before enabling v2.
>
> - More and more complex v2 cache dependency
> Extent tree v2 and bgt all depend on v2 cache, but we have some
> mount options like clear_cache can screw this up.
>
> Instead introducing some mount options to tinkering the filesystem
> features (either compat_ro or incompat), we should always go through
> btrfstune to enable new features (just like what we did in bgt).
>
> This allows us to move the heavy lifting and proper checks into
> btrfs-progs.
>
> Although it's already late, it's still better than never, thus this
> patchset introduce the --convert-to-free-space-tree feature to
> btrfstune.
>
> Unlike bgt, v1 cache is going to fade out soon, thus no rollback
> functionality provided.
Agreed.
> I hope we can deprecate the "space_cache=" mount option soon.
Yes, that would be desirable as the mount option wouldn't make much
sense and it's a mkfs-feature so we don't need to reflect that in mount
options that should be for the run time.
We can drop the space_cache from showing among options once we get rid
of the v1 code. There's no scheduled version for that but it could be
done if somebody wants. We have the conversion working and with the
btrfstune also available it should be complete.
>
> Qu Wenruo (3):
> btrfs-progs: make check/clear-cache.c to be separate from check/main.c
Right now we have the --clear-space-cache as an option for 'btrfs check'
but it will also make less sense over time. For such one-shot options
it's better to move it to the 'rescue' group. With a separate
clear-cache.c it's going to be easier. The existing 'check' option need
to stay for compatibility.
> btrfs-progs: tune: add --convert-to-free-space-tree option
> btrfs-progs: misc-tests: add test case to verify btrfstune
> --convert-to-free-space-tree option
Added to devel, thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-05-02 18:31 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-02 1:01 [PATCH 0/3] btrfs-progs: add the ability to enable fst for btrfstune Qu Wenruo
2023-05-02 1:01 ` [PATCH 1/3] btrfs-progs: make check/clear-cache.c to be separate from check/main.c Qu Wenruo
2023-05-02 1:01 ` [PATCH 2/3] btrfs-progs: tune: add --convert-to-free-space-tree option Qu Wenruo
2023-05-02 1:01 ` [PATCH 3/3] btrfs-progs: misc-tests: add test case to verify btrfstune " Qu Wenruo
2023-05-02 18:25 ` [PATCH 0/3] btrfs-progs: add the ability to enable fst for btrfstune David Sterba
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.