* [PATCH 0/2] btrfs: fix incorrect barrier usage in relocation
@ 2026-06-12 12:13 fdmanana
2026-06-12 12:13 ` [PATCH 1/2] btrfs: fix reloc root cleanup in merge_reloc_roots() fdmanana
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: fdmanana @ 2026-06-12 12:13 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
Sashiko recently detected we are not correctly using memory barriers
in the relocation code, and these patches address that. Details in
the change logs.
Filipe Manana (2):
btrfs: fix reloc root cleanup in merge_reloc_roots()
btrfs: fix memory barrier order in reloc_root_is_dead()
fs/btrfs/relocation.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
--
2.47.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] btrfs: fix reloc root cleanup in merge_reloc_roots()
2026-06-12 12:13 [PATCH 0/2] btrfs: fix incorrect barrier usage in relocation fdmanana
@ 2026-06-12 12:13 ` fdmanana
2026-06-12 12:13 ` [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead() fdmanana
2026-06-12 17:28 ` [PATCH 0/2] btrfs: fix incorrect barrier usage in relocation Boris Burkov
2 siblings, 0 replies; 7+ messages in thread
From: fdmanana @ 2026-06-12 12:13 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
If the root we got has zero root refs in its root item, we are resetting
the root's ->reloc_root without using barriers like we do everywhere else.
Sashiko complained about this while reviewing another patch, and it's
correct (see the Link tag below).
Also, we should not clear BTRFS_ROOT_DEAD_RELOC_TREE from the root unless
the root points to the reloc root we have.
Fix this by using clear_reloc_root(), which issues the memory barrier
after setting the root's ->reloc_root to NULL and before clearing the bit
BTRFS_ROOT_DEAD_RELOC_TREE from the root.
Link: https://sashiko.dev/#/patchset/cf84f1a217c719e25b6b69e4298dd7afd36c9427.1781194426.git.fdmanana%40suse.com
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/relocation.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 74687c75f763..6b5a59cb21bb 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -1950,11 +1950,10 @@ void merge_reloc_roots(struct reloc_control *rc)
} else {
if (!IS_ERR(root)) {
if (root->reloc_root == reloc_root) {
- root->reloc_root = NULL;
+ clear_reloc_root(root);
+ /* Drop the ref for root->reloc_root. */
btrfs_put_root(reloc_root);
}
- clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE,
- &root->state);
btrfs_put_root(root);
}
--
2.47.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead()
2026-06-12 12:13 [PATCH 0/2] btrfs: fix incorrect barrier usage in relocation fdmanana
2026-06-12 12:13 ` [PATCH 1/2] btrfs: fix reloc root cleanup in merge_reloc_roots() fdmanana
@ 2026-06-12 12:13 ` fdmanana
2026-06-12 19:13 ` kernel test robot
2026-06-12 20:45 ` kernel test robot
2026-06-12 17:28 ` [PATCH 0/2] btrfs: fix incorrect barrier usage in relocation Boris Burkov
2 siblings, 2 replies; 7+ messages in thread
From: fdmanana @ 2026-06-12 12:13 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
When we set a root's reloc_root to NULL, we do it like this:
static void clear_reloc_root(struct btrfs_root *root)
{
root->reloc_root = NULL;
/*
* Need barrier to ensure clear_bit() only happens after
* root->reloc_root = NULL. Pairs with have_reloc_root().
*/
smp_wmb();
clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
}
So that a NULL reloc_root is always seen before seeing that the bit
BTRFS_ROOT_DEAD_RELOC_TREE was cleared.
But on the read side we have:
static bool reloc_root_is_dead(const struct btrfs_root *root)
{
smp_rmb();
if (test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state))
return true;
return false;
}
And then callers of reloc_root_is_dead() access root->reloc_root.
Because the read memory barrier is placed before testing the bit, the CPU
is completely free to speculatively reorder those two loads. It can read
root->reloc_root before it actually checks the dead tree bit.
Sashiko reported this as an existing problem in another patch review, see
the link in the Link tag below.
Fix this by moving the read memory barrier to happen after testing the bit
and update the comment to reflect current reality.
Link: https://sashiko.dev/#/patchset/cf84f1a217c719e25b6b69e4298dd7afd36c9427.1781194426.git.fdmanana%40suse.com
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/relocation.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 6b5a59cb21bb..00993505c9c3 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -339,14 +339,15 @@ static struct btrfs_backref_node *walk_down_backref(
static bool reloc_root_is_dead(const struct btrfs_root *root)
{
+ if (test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state))
+ return true;
/*
- * Pair with set_bit/clear_bit in clean_dirty_subvols and
- * btrfs_update_reloc_root. We need to see the updated bit before
- * trying to access reloc_root
+ * Pairs with set_bit/clear_bit in clear_reloc_root() and
+ * btrfs_update_reloc_root(). We need to see the updated bit before
+ * trying to access root->reloc_root in our callers.
*/
smp_rmb();
- if (test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state))
- return true;
+
return false;
}
--
2.47.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] btrfs: fix incorrect barrier usage in relocation
2026-06-12 12:13 [PATCH 0/2] btrfs: fix incorrect barrier usage in relocation fdmanana
2026-06-12 12:13 ` [PATCH 1/2] btrfs: fix reloc root cleanup in merge_reloc_roots() fdmanana
2026-06-12 12:13 ` [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead() fdmanana
@ 2026-06-12 17:28 ` Boris Burkov
2 siblings, 0 replies; 7+ messages in thread
From: Boris Burkov @ 2026-06-12 17:28 UTC (permalink / raw)
To: fdmanana; +Cc: linux-btrfs
On Fri, Jun 12, 2026 at 01:13:55PM +0100, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
>
> Sashiko recently detected we are not correctly using memory barriers
> in the relocation code, and these patches address that. Details in
> the change logs.
Reviewed-by: Boris Burkov <boris@bur.io>
>
> Filipe Manana (2):
> btrfs: fix reloc root cleanup in merge_reloc_roots()
> btrfs: fix memory barrier order in reloc_root_is_dead()
>
> fs/btrfs/relocation.c | 16 ++++++++--------
> 1 file changed, 8 insertions(+), 8 deletions(-)
>
> --
> 2.47.2
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead()
2026-06-12 12:13 ` [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead() fdmanana
@ 2026-06-12 19:13 ` kernel test robot
2026-06-12 19:24 ` Filipe Manana
2026-06-12 20:45 ` kernel test robot
1 sibling, 1 reply; 7+ messages in thread
From: kernel test robot @ 2026-06-12 19:13 UTC (permalink / raw)
To: fdmanana, linux-btrfs; +Cc: llvm, oe-kbuild-all
Hi Filipe,
kernel test robot noticed the following build errors:
[auto build test ERROR on kdave/for-next]
[also build test ERROR on linus/master v7.1-rc7 next-20260611]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/fdmanana-kernel-org/btrfs-fix-reloc-root-cleanup-in-merge_reloc_roots/20260612-202603
base: https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
patch link: https://lore.kernel.org/r/62602395bf1488aa81645ea59e22405d6c06d3f7.1781263239.git.fdmanana%40suse.com
patch subject: [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead()
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20260612/202606122155.6ncF2GHC-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project f43d6834093b19baf79beda8c0337ab020ac5f17)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260612/202606122155.6ncF2GHC-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606122155.6ncF2GHC-lkp@intel.com/
All errors (new ones prefixed by >>):
>> fs/btrfs/relocation.c:1928:6: error: call to undeclared function 'clear_reloc_root'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
1928 | clear_reloc_root(root);
| ^
fs/btrfs/relocation.c:1928:6: note: did you mean 'create_reloc_root'?
fs/btrfs/relocation.c:631:27: note: 'create_reloc_root' declared here
631 | static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
| ^
1 error generated.
vim +/clear_reloc_root +1928 fs/btrfs/relocation.c
1867
1868 static noinline_for_stack
1869 void merge_reloc_roots(struct reloc_control *rc)
1870 {
1871 struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
1872 struct btrfs_root *root;
1873 struct btrfs_root *reloc_root;
1874 LIST_HEAD(reloc_roots);
1875 bool found = false;
1876 int ret = 0;
1877 again:
1878 root = rc->extent_root;
1879
1880 /*
1881 * this serializes us with btrfs_record_root_in_transaction,
1882 * we have to make sure nobody is in the middle of
1883 * adding their roots to the list while we are
1884 * doing this splice
1885 */
1886 mutex_lock(&fs_info->reloc_mutex);
1887 list_splice_init(&rc->reloc_roots, &reloc_roots);
1888 mutex_unlock(&fs_info->reloc_mutex);
1889
1890 while (!list_empty(&reloc_roots)) {
1891 found = true;
1892 reloc_root = list_first_entry(&reloc_roots, struct btrfs_root, root_list);
1893
1894 root = btrfs_get_fs_root(fs_info, reloc_root->root_key.offset,
1895 false);
1896 if (btrfs_root_refs(&reloc_root->root_item) > 0) {
1897 if (WARN_ON(IS_ERR(root))) {
1898 /*
1899 * For recovery we read the fs roots on mount,
1900 * and if we didn't find the root then we marked
1901 * the reloc root as a garbage root. For normal
1902 * relocation obviously the root should exist in
1903 * memory. However there's no reason we can't
1904 * handle the error properly here just in case.
1905 */
1906 ret = PTR_ERR(root);
1907 goto out;
1908 }
1909 if (WARN_ON(root->reloc_root != reloc_root)) {
1910 /*
1911 * This can happen if on-disk metadata has some
1912 * corruption, e.g. bad reloc tree key offset.
1913 */
1914 ret = -EINVAL;
1915 goto out;
1916 }
1917 ret = merge_reloc_root(rc, root);
1918 btrfs_put_root(root);
1919 if (ret) {
1920 if (list_empty(&reloc_root->root_list))
1921 list_add_tail(&reloc_root->root_list,
1922 &reloc_roots);
1923 goto out;
1924 }
1925 } else {
1926 if (!IS_ERR(root)) {
1927 if (root->reloc_root == reloc_root) {
> 1928 clear_reloc_root(root);
1929 /* Drop the ref for root->reloc_root. */
1930 btrfs_put_root(reloc_root);
1931 }
1932 btrfs_put_root(root);
1933 }
1934
1935 list_del_init(&reloc_root->root_list);
1936 /* Don't forget to queue this reloc root for cleanup */
1937 list_add_tail(&reloc_root->reloc_dirty_list,
1938 &rc->dirty_subvol_roots);
1939 }
1940 }
1941
1942 if (found) {
1943 found = false;
1944 goto again;
1945 }
1946 out:
1947 if (ret) {
1948 btrfs_handle_fs_error(fs_info, ret, NULL);
1949 free_reloc_roots(&reloc_roots);
1950
1951 /* new reloc root may be added */
1952 mutex_lock(&fs_info->reloc_mutex);
1953 list_splice_init(&rc->reloc_roots, &reloc_roots);
1954 mutex_unlock(&fs_info->reloc_mutex);
1955 free_reloc_roots(&reloc_roots);
1956 }
1957
1958 /*
1959 * We used to have
1960 *
1961 * BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root));
1962 *
1963 * here, but it's wrong. If we fail to start the transaction in
1964 * prepare_to_merge() we will have only 0 ref reloc roots, none of which
1965 * have actually been removed from the reloc_root_tree rb tree. This is
1966 * fine because we're bailing here, and we hold a reference on the root
1967 * for the list that holds it, so these roots will be cleaned up when we
1968 * do the reloc_dirty_list afterwards. Meanwhile the root->reloc_root
1969 * will be cleaned up on unmount.
1970 *
1971 * The remaining nodes will be cleaned up by put_reloc_control().
1972 */
1973 }
1974
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead()
2026-06-12 19:13 ` kernel test robot
@ 2026-06-12 19:24 ` Filipe Manana
0 siblings, 0 replies; 7+ messages in thread
From: Filipe Manana @ 2026-06-12 19:24 UTC (permalink / raw)
To: kernel test robot; +Cc: linux-btrfs, llvm, oe-kbuild-all
On Fri, Jun 12, 2026 at 8:13 PM kernel test robot <lkp@intel.com> wrote:
>
> Hi Filipe,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on kdave/for-next]
> [also build test ERROR on linus/master v7.1-rc7 next-20260611]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/fdmanana-kernel-org/btrfs-fix-reloc-root-cleanup-in-merge_reloc_roots/20260612-202603
> base: https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
> patch link: https://lore.kernel.org/r/62602395bf1488aa81645ea59e22405d6c06d3f7.1781263239.git.fdmanana%40suse.com
> patch subject: [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead()
> config: x86_64-kexec (https://download.01.org/0day-ci/archive/20260612/202606122155.6ncF2GHC-lkp@intel.com/config)
> compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project f43d6834093b19baf79beda8c0337ab020ac5f17)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260612/202606122155.6ncF2GHC-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202606122155.6ncF2GHC-lkp@intel.com/
>
> All errors (new ones prefixed by >>):
>
> >> fs/btrfs/relocation.c:1928:6: error: call to undeclared function 'clear_reloc_root'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
> 1928 | clear_reloc_root(root);
> | ^
> fs/btrfs/relocation.c:1928:6: note: did you mean 'create_reloc_root'?
> fs/btrfs/relocation.c:631:27: note: 'create_reloc_root' declared here
> 631 | static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
> | ^
> 1 error generated.
This is because it depends on a patch that is in the giithub for-next
branch but not yet in Linus' tree or linux-next:
https://lore.kernel.org/linux-btrfs/cf84f1a217c719e25b6b69e4298dd7afd36c9427.1781194426.git.fdmanana@suse.com/
https://github.com/btrfs/linux/commits/for-next/
>
>
> vim +/clear_reloc_root +1928 fs/btrfs/relocation.c
>
> 1867
> 1868 static noinline_for_stack
> 1869 void merge_reloc_roots(struct reloc_control *rc)
> 1870 {
> 1871 struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
> 1872 struct btrfs_root *root;
> 1873 struct btrfs_root *reloc_root;
> 1874 LIST_HEAD(reloc_roots);
> 1875 bool found = false;
> 1876 int ret = 0;
> 1877 again:
> 1878 root = rc->extent_root;
> 1879
> 1880 /*
> 1881 * this serializes us with btrfs_record_root_in_transaction,
> 1882 * we have to make sure nobody is in the middle of
> 1883 * adding their roots to the list while we are
> 1884 * doing this splice
> 1885 */
> 1886 mutex_lock(&fs_info->reloc_mutex);
> 1887 list_splice_init(&rc->reloc_roots, &reloc_roots);
> 1888 mutex_unlock(&fs_info->reloc_mutex);
> 1889
> 1890 while (!list_empty(&reloc_roots)) {
> 1891 found = true;
> 1892 reloc_root = list_first_entry(&reloc_roots, struct btrfs_root, root_list);
> 1893
> 1894 root = btrfs_get_fs_root(fs_info, reloc_root->root_key.offset,
> 1895 false);
> 1896 if (btrfs_root_refs(&reloc_root->root_item) > 0) {
> 1897 if (WARN_ON(IS_ERR(root))) {
> 1898 /*
> 1899 * For recovery we read the fs roots on mount,
> 1900 * and if we didn't find the root then we marked
> 1901 * the reloc root as a garbage root. For normal
> 1902 * relocation obviously the root should exist in
> 1903 * memory. However there's no reason we can't
> 1904 * handle the error properly here just in case.
> 1905 */
> 1906 ret = PTR_ERR(root);
> 1907 goto out;
> 1908 }
> 1909 if (WARN_ON(root->reloc_root != reloc_root)) {
> 1910 /*
> 1911 * This can happen if on-disk metadata has some
> 1912 * corruption, e.g. bad reloc tree key offset.
> 1913 */
> 1914 ret = -EINVAL;
> 1915 goto out;
> 1916 }
> 1917 ret = merge_reloc_root(rc, root);
> 1918 btrfs_put_root(root);
> 1919 if (ret) {
> 1920 if (list_empty(&reloc_root->root_list))
> 1921 list_add_tail(&reloc_root->root_list,
> 1922 &reloc_roots);
> 1923 goto out;
> 1924 }
> 1925 } else {
> 1926 if (!IS_ERR(root)) {
> 1927 if (root->reloc_root == reloc_root) {
> > 1928 clear_reloc_root(root);
> 1929 /* Drop the ref for root->reloc_root. */
> 1930 btrfs_put_root(reloc_root);
> 1931 }
> 1932 btrfs_put_root(root);
> 1933 }
> 1934
> 1935 list_del_init(&reloc_root->root_list);
> 1936 /* Don't forget to queue this reloc root for cleanup */
> 1937 list_add_tail(&reloc_root->reloc_dirty_list,
> 1938 &rc->dirty_subvol_roots);
> 1939 }
> 1940 }
> 1941
> 1942 if (found) {
> 1943 found = false;
> 1944 goto again;
> 1945 }
> 1946 out:
> 1947 if (ret) {
> 1948 btrfs_handle_fs_error(fs_info, ret, NULL);
> 1949 free_reloc_roots(&reloc_roots);
> 1950
> 1951 /* new reloc root may be added */
> 1952 mutex_lock(&fs_info->reloc_mutex);
> 1953 list_splice_init(&rc->reloc_roots, &reloc_roots);
> 1954 mutex_unlock(&fs_info->reloc_mutex);
> 1955 free_reloc_roots(&reloc_roots);
> 1956 }
> 1957
> 1958 /*
> 1959 * We used to have
> 1960 *
> 1961 * BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root));
> 1962 *
> 1963 * here, but it's wrong. If we fail to start the transaction in
> 1964 * prepare_to_merge() we will have only 0 ref reloc roots, none of which
> 1965 * have actually been removed from the reloc_root_tree rb tree. This is
> 1966 * fine because we're bailing here, and we hold a reference on the root
> 1967 * for the list that holds it, so these roots will be cleaned up when we
> 1968 * do the reloc_dirty_list afterwards. Meanwhile the root->reloc_root
> 1969 * will be cleaned up on unmount.
> 1970 *
> 1971 * The remaining nodes will be cleaned up by put_reloc_control().
> 1972 */
> 1973 }
> 1974
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead()
2026-06-12 12:13 ` [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead() fdmanana
2026-06-12 19:13 ` kernel test robot
@ 2026-06-12 20:45 ` kernel test robot
1 sibling, 0 replies; 7+ messages in thread
From: kernel test robot @ 2026-06-12 20:45 UTC (permalink / raw)
To: fdmanana, linux-btrfs; +Cc: oe-kbuild-all
Hi Filipe,
kernel test robot noticed the following build errors:
[auto build test ERROR on kdave/for-next]
[also build test ERROR on linus/master v7.1-rc7 next-20260612]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/fdmanana-kernel-org/btrfs-fix-reloc-root-cleanup-in-merge_reloc_roots/20260612-202603
base: https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
patch link: https://lore.kernel.org/r/62602395bf1488aa81645ea59e22405d6c06d3f7.1781263239.git.fdmanana%40suse.com
patch subject: [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead()
config: x86_64-rhel-9.4 (https://download.01.org/0day-ci/archive/20260612/202606122213.j2TtzMBn-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260612/202606122213.j2TtzMBn-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606122213.j2TtzMBn-lkp@intel.com/
All errors (new ones prefixed by >>):
fs/btrfs/relocation.c: In function 'merge_reloc_roots':
>> fs/btrfs/relocation.c:1928:41: error: implicit declaration of function 'clear_reloc_root'; did you mean 'create_reloc_root'? [-Wimplicit-function-declaration]
1928 | clear_reloc_root(root);
| ^~~~~~~~~~~~~~~~
| create_reloc_root
vim +1928 fs/btrfs/relocation.c
1867
1868 static noinline_for_stack
1869 void merge_reloc_roots(struct reloc_control *rc)
1870 {
1871 struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
1872 struct btrfs_root *root;
1873 struct btrfs_root *reloc_root;
1874 LIST_HEAD(reloc_roots);
1875 bool found = false;
1876 int ret = 0;
1877 again:
1878 root = rc->extent_root;
1879
1880 /*
1881 * this serializes us with btrfs_record_root_in_transaction,
1882 * we have to make sure nobody is in the middle of
1883 * adding their roots to the list while we are
1884 * doing this splice
1885 */
1886 mutex_lock(&fs_info->reloc_mutex);
1887 list_splice_init(&rc->reloc_roots, &reloc_roots);
1888 mutex_unlock(&fs_info->reloc_mutex);
1889
1890 while (!list_empty(&reloc_roots)) {
1891 found = true;
1892 reloc_root = list_first_entry(&reloc_roots, struct btrfs_root, root_list);
1893
1894 root = btrfs_get_fs_root(fs_info, reloc_root->root_key.offset,
1895 false);
1896 if (btrfs_root_refs(&reloc_root->root_item) > 0) {
1897 if (WARN_ON(IS_ERR(root))) {
1898 /*
1899 * For recovery we read the fs roots on mount,
1900 * and if we didn't find the root then we marked
1901 * the reloc root as a garbage root. For normal
1902 * relocation obviously the root should exist in
1903 * memory. However there's no reason we can't
1904 * handle the error properly here just in case.
1905 */
1906 ret = PTR_ERR(root);
1907 goto out;
1908 }
1909 if (WARN_ON(root->reloc_root != reloc_root)) {
1910 /*
1911 * This can happen if on-disk metadata has some
1912 * corruption, e.g. bad reloc tree key offset.
1913 */
1914 ret = -EINVAL;
1915 goto out;
1916 }
1917 ret = merge_reloc_root(rc, root);
1918 btrfs_put_root(root);
1919 if (ret) {
1920 if (list_empty(&reloc_root->root_list))
1921 list_add_tail(&reloc_root->root_list,
1922 &reloc_roots);
1923 goto out;
1924 }
1925 } else {
1926 if (!IS_ERR(root)) {
1927 if (root->reloc_root == reloc_root) {
> 1928 clear_reloc_root(root);
1929 /* Drop the ref for root->reloc_root. */
1930 btrfs_put_root(reloc_root);
1931 }
1932 btrfs_put_root(root);
1933 }
1934
1935 list_del_init(&reloc_root->root_list);
1936 /* Don't forget to queue this reloc root for cleanup */
1937 list_add_tail(&reloc_root->reloc_dirty_list,
1938 &rc->dirty_subvol_roots);
1939 }
1940 }
1941
1942 if (found) {
1943 found = false;
1944 goto again;
1945 }
1946 out:
1947 if (ret) {
1948 btrfs_handle_fs_error(fs_info, ret, NULL);
1949 free_reloc_roots(&reloc_roots);
1950
1951 /* new reloc root may be added */
1952 mutex_lock(&fs_info->reloc_mutex);
1953 list_splice_init(&rc->reloc_roots, &reloc_roots);
1954 mutex_unlock(&fs_info->reloc_mutex);
1955 free_reloc_roots(&reloc_roots);
1956 }
1957
1958 /*
1959 * We used to have
1960 *
1961 * BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root));
1962 *
1963 * here, but it's wrong. If we fail to start the transaction in
1964 * prepare_to_merge() we will have only 0 ref reloc roots, none of which
1965 * have actually been removed from the reloc_root_tree rb tree. This is
1966 * fine because we're bailing here, and we hold a reference on the root
1967 * for the list that holds it, so these roots will be cleaned up when we
1968 * do the reloc_dirty_list afterwards. Meanwhile the root->reloc_root
1969 * will be cleaned up on unmount.
1970 *
1971 * The remaining nodes will be cleaned up by put_reloc_control().
1972 */
1973 }
1974
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-06-12 20:46 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-12 12:13 [PATCH 0/2] btrfs: fix incorrect barrier usage in relocation fdmanana
2026-06-12 12:13 ` [PATCH 1/2] btrfs: fix reloc root cleanup in merge_reloc_roots() fdmanana
2026-06-12 12:13 ` [PATCH 2/2] btrfs: fix memory barrier order in reloc_root_is_dead() fdmanana
2026-06-12 19:13 ` kernel test robot
2026-06-12 19:24 ` Filipe Manana
2026-06-12 20:45 ` kernel test robot
2026-06-12 17:28 ` [PATCH 0/2] btrfs: fix incorrect barrier usage in relocation Boris Burkov
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.