Re: [PATCH] btrfs: clear free space tree state on rebuild failure
From: Qu Wenruo
Date: Tue Sep 15 2026 - 18:16:51 EST
在 2026/9/16 00:18, Guanghui Yang 写道:
btrfs_rebuild_free_space_tree() sets
BTRFS_FS_CREATING_FREE_SPACE_TREE and
BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED before rebuilding the free space
tree. Several error paths return without clearing these flags.
This leaves the flags set on the live filesystem and affects delayed
reference processing and free-space caching.
What kind of effect?
Clear both flags on all
free space tree rebuild failure paths.
Fixes: 1d6a4fc85717 ("btrfs: make clear_cache mount option to rebuild FST without disabling it")
Cc: stable@xxxxxxxxxxxxxxx # 6.4+
Assisted-by: Codex:gpt-5
Tested: make -j$(nproc) fs/btrfs/free-space-tree.o
That's not helpful, you should run the full fstests instead.
Signed-off-by: Guanghui Yang <3497809730@xxxxxx>
---
fs/btrfs/free-space-tree.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
index 1b3d82ae3de8..1410da2766a9 100644
--- a/fs/btrfs/free-space-tree.c
+++ b/fs/btrfs/free-space-tree.c
@@ -1353,7 +1353,7 @@ int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info)
if (unlikely(ret)) {
btrfs_abort_transaction(trans, ret);
btrfs_end_transaction(trans);
- return ret;
+ goto out_clear;
}
node = rb_first_cached(&fs_info->block_group_cache_tree);
@@ -1371,14 +1371,16 @@ int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info)
if (unlikely(ret)) {
btrfs_abort_transaction(trans, ret);
btrfs_end_transaction(trans);
- return ret;
+ goto out_clear;
}
next:
if (btrfs_should_end_transaction(trans)) {
btrfs_end_transaction(trans);
trans = btrfs_start_transaction(free_space_root, 1);
- if (IS_ERR(trans))
- return PTR_ERR(trans);
+ if (IS_ERR(trans)) {
+ ret = PTR_ERR(trans);
+ goto out_clear;
+ }
}
node = rb_next(node);
}
@@ -1390,6 +1392,11 @@ int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info)
ret = btrfs_commit_transaction(trans);
clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
return ret;
+
+out_clear:
+ clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
+ clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
The free space tree is not properly rebuilt, thus we can not trust it anymore.
Why you want to clear the UNTRUSTED flag?
+ return ret;
}
static int __add_block_group_free_space(struct btrfs_trans_handle *trans,
base-commit: 587858367581b9c55c3690f4e63382ad622719d4