linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] Minor cleanups in relocation.c
@ 2023-09-22 11:07 David Sterba
  2023-09-22 11:07 ` [PATCH 1/8] btrfs: relocation: use more natural types for tree_block bitfields David Sterba
                   ` (7 more replies)
  0 siblings, 8 replies; 29+ messages in thread
From: David Sterba @ 2023-09-22 11:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Various type cleanups in relocation.c, on-stack variable to replace
frequent allocation in build_backref_tree().

David Sterba (8):
  btrfs: relocation: use more natural types for tree_block bitfields
  btrfs: relocation: use enum for stages
  btrfs: relocation: switch bitfields to bool in reloc_control
  btrfs: relocation: open code mapping_tree_init
  btrfs: switch btrfs_backref_cache::is_reloc to bool
  btrfs: relocation: return bool from btrfs_should_ignore_reloc_root
  btrfs: relocation: use on-stack iterator in build_backref_tree
  btrfs: relocation: constify parameters where possible

 fs/btrfs/backref.c    |  28 ++++-----
 fs/btrfs/backref.h    |  15 ++---
 fs/btrfs/relocation.c | 139 ++++++++++++++++++++----------------------
 fs/btrfs/relocation.h |   9 +--
 4 files changed, 87 insertions(+), 104 deletions(-)

-- 
2.41.0


^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 1/8] btrfs: relocation: use more natural types for tree_block bitfields
  2023-09-22 11:07 [PATCH 0/8] Minor cleanups in relocation.c David Sterba
@ 2023-09-22 11:07 ` David Sterba
  2023-09-22 12:28   ` Johannes Thumshirn
  2023-09-22 22:28   ` Qu Wenruo
  2023-09-22 11:07 ` [PATCH 2/8] btrfs: relocation: use enum for stages David Sterba
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 29+ messages in thread
From: David Sterba @ 2023-09-22 11:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

We don't need to use bitfields for tree_block::level and
tree_block::key_ready, there's enough padding in the structure for
proper types.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/relocation.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 6e8e14d1aeaa..9ff3572a8451 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -111,8 +111,8 @@ struct tree_block {
 	}; /* Use rb_simple_node for search/insert */
 	u64 owner;
 	struct btrfs_key key;
-	unsigned int level:8;
-	unsigned int key_ready:1;
+	u8 level;
+	bool key_ready;
 };
 
 #define MAX_EXTENTS 128
@@ -2664,7 +2664,7 @@ static int get_tree_block_key(struct btrfs_fs_info *fs_info,
 	else
 		btrfs_node_key_to_cpu(eb, &block->key, 0);
 	free_extent_buffer(eb);
-	block->key_ready = 1;
+	block->key_ready = true;
 	return 0;
 }
 
@@ -3313,7 +3313,7 @@ static int add_tree_block(struct reloc_control *rc,
 	block->key.objectid = rc->extent_root->fs_info->nodesize;
 	block->key.offset = generation;
 	block->level = level;
-	block->key_ready = 0;
+	block->key_ready = false;
 	block->owner = owner;
 
 	rb_node = rb_simple_insert(blocks, block->bytenr, &block->rb_node);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 2/8] btrfs: relocation: use enum for stages
  2023-09-22 11:07 [PATCH 0/8] Minor cleanups in relocation.c David Sterba
  2023-09-22 11:07 ` [PATCH 1/8] btrfs: relocation: use more natural types for tree_block bitfields David Sterba
@ 2023-09-22 11:07 ` David Sterba
  2023-09-22 12:29   ` Johannes Thumshirn
  2023-09-22 22:29   ` Qu Wenruo
  2023-09-22 11:07 ` [PATCH 3/8] btrfs: relocation: switch bitfields to bool in reloc_control David Sterba
                   ` (5 subsequent siblings)
  7 siblings, 2 replies; 29+ messages in thread
From: David Sterba @ 2023-09-22 11:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Add an enum type for data relocation stages.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/relocation.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 9ff3572a8451..3afe499f00b1 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -125,6 +125,12 @@ struct file_extent_cluster {
 	u64 owning_root;
 };
 
+/* Stages of data relocation. */
+enum reloc_stage {
+	MOVE_DATA_EXTENTS,
+	UPDATE_DATA_PTRS
+};
+
 struct reloc_control {
 	/* block group to relocate */
 	struct btrfs_block_group *block_group;
@@ -156,16 +162,12 @@ struct reloc_control {
 	u64 search_start;
 	u64 extents_found;
 
-	unsigned int stage:8;
+	enum reloc_stage stage;
 	unsigned int create_reloc_tree:1;
 	unsigned int merge_reloc_tree:1;
 	unsigned int found_file_extent:1;
 };
 
-/* stages of data relocation */
-#define MOVE_DATA_EXTENTS	0
-#define UPDATE_DATA_PTRS	1
-
 static void mark_block_processed(struct reloc_control *rc,
 				 struct btrfs_backref_node *node)
 {
@@ -4054,7 +4056,7 @@ static void describe_relocation(struct btrfs_fs_info *fs_info,
 		   block_group->start, buf);
 }
 
-static const char *stage_to_string(int stage)
+static const char *stage_to_string(enum reloc_stage stage)
 {
 	if (stage == MOVE_DATA_EXTENTS)
 		return "move data extents";
@@ -4170,7 +4172,7 @@ int btrfs_relocate_block_group(struct btrfs_fs_info *fs_info, u64 group_start)
 	WARN_ON(ret && ret != -EAGAIN);
 
 	while (1) {
-		int finishes_stage;
+		enum reloc_stage finishes_stage;
 
 		mutex_lock(&fs_info->cleaner_mutex);
 		ret = relocate_block_group(rc);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 3/8] btrfs: relocation: switch bitfields to bool in reloc_control
  2023-09-22 11:07 [PATCH 0/8] Minor cleanups in relocation.c David Sterba
  2023-09-22 11:07 ` [PATCH 1/8] btrfs: relocation: use more natural types for tree_block bitfields David Sterba
  2023-09-22 11:07 ` [PATCH 2/8] btrfs: relocation: use enum for stages David Sterba
@ 2023-09-22 11:07 ` David Sterba
  2023-09-22 12:30   ` Johannes Thumshirn
  2023-09-22 22:30   ` Qu Wenruo
  2023-09-22 11:07 ` [PATCH 4/8] btrfs: relocation: open code mapping_tree_init David Sterba
                   ` (4 subsequent siblings)
  7 siblings, 2 replies; 29+ messages in thread
From: David Sterba @ 2023-09-22 11:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Use bool types for the indicators instead of bitfields. The structure
size slightly grows but the new types are placed within the padding.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/relocation.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 3afe499f00b1..87ac8528032c 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -163,9 +163,9 @@ struct reloc_control {
 	u64 extents_found;
 
 	enum reloc_stage stage;
-	unsigned int create_reloc_tree:1;
-	unsigned int merge_reloc_tree:1;
-	unsigned int found_file_extent:1;
+	bool create_reloc_tree;
+	bool merge_reloc_tree;
+	bool found_file_extent;
 };
 
 static void mark_block_processed(struct reloc_control *rc,
@@ -1902,7 +1902,7 @@ int prepare_to_merge(struct reloc_control *rc, int err)
 		}
 	}
 
-	rc->merge_reloc_tree = 1;
+	rc->merge_reloc_tree = true;
 
 	while (!list_empty(&rc->reloc_roots)) {
 		reloc_root = list_entry(rc->reloc_roots.next,
@@ -3659,7 +3659,7 @@ int prepare_to_relocate(struct reloc_control *rc)
 	if (ret)
 		return ret;
 
-	rc->create_reloc_tree = 1;
+	rc->create_reloc_tree = true;
 	set_reloc_control(rc);
 
 	trans = btrfs_join_transaction(rc->extent_root);
@@ -3786,7 +3786,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
 
 		if (rc->stage == MOVE_DATA_EXTENTS &&
 		    (flags & BTRFS_EXTENT_FLAG_DATA)) {
-			rc->found_file_extent = 1;
+			rc->found_file_extent = true;
 			ret = relocate_data_extent(rc->data_inode,
 						   &key, &rc->cluster);
 			if (ret < 0) {
@@ -3823,7 +3823,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
 			err = ret;
 	}
 
-	rc->create_reloc_tree = 0;
+	rc->create_reloc_tree = false;
 	set_reloc_control(rc);
 
 	btrfs_backref_release_cache(&rc->backref_cache);
@@ -3841,7 +3841,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
 
 	merge_reloc_roots(rc);
 
-	rc->merge_reloc_tree = 0;
+	rc->merge_reloc_tree = false;
 	unset_reloc_control(rc);
 	btrfs_block_rsv_release(fs_info, rc->block_rsv, (u64)-1, NULL);
 
@@ -4355,7 +4355,7 @@ int btrfs_recover_relocation(struct btrfs_fs_info *fs_info)
 		goto out_unset;
 	}
 
-	rc->merge_reloc_tree = 1;
+	rc->merge_reloc_tree = true;
 
 	while (!list_empty(&reloc_roots)) {
 		reloc_root = list_entry(reloc_roots.next,
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 4/8] btrfs: relocation: open code mapping_tree_init
  2023-09-22 11:07 [PATCH 0/8] Minor cleanups in relocation.c David Sterba
                   ` (2 preceding siblings ...)
  2023-09-22 11:07 ` [PATCH 3/8] btrfs: relocation: switch bitfields to bool in reloc_control David Sterba
@ 2023-09-22 11:07 ` David Sterba
  2023-09-22 12:31   ` Johannes Thumshirn
  2023-09-22 22:31   ` Qu Wenruo
  2023-09-22 11:07 ` [PATCH 5/8] btrfs: switch btrfs_backref_cache::is_reloc to bool David Sterba
                   ` (3 subsequent siblings)
  7 siblings, 2 replies; 29+ messages in thread
From: David Sterba @ 2023-09-22 11:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

There's only one user of mapping_tree_init, we don't need a helper for
the simple initialization.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/relocation.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 87ac8528032c..3e662cadecaf 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -183,13 +183,6 @@ static void mark_block_processed(struct reloc_control *rc,
 	node->processed = 1;
 }
 
-
-static void mapping_tree_init(struct mapping_tree *tree)
-{
-	tree->rb_root = RB_ROOT;
-	spin_lock_init(&tree->lock);
-}
-
 /*
  * walk up backref nodes until reach node presents tree root
  */
@@ -4024,7 +4017,8 @@ static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info)
 	INIT_LIST_HEAD(&rc->reloc_roots);
 	INIT_LIST_HEAD(&rc->dirty_subvol_roots);
 	btrfs_backref_init_cache(fs_info, &rc->backref_cache, 1);
-	mapping_tree_init(&rc->reloc_root_tree);
+	rc->reloc_root_tree.rb_root = RB_ROOT;
+	spin_lock_init(&rc->reloc_root_tree.lock);
 	extent_io_tree_init(fs_info, &rc->processed_blocks, IO_TREE_RELOC_BLOCKS);
 	return rc;
 }
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 5/8] btrfs: switch btrfs_backref_cache::is_reloc to bool
  2023-09-22 11:07 [PATCH 0/8] Minor cleanups in relocation.c David Sterba
                   ` (3 preceding siblings ...)
  2023-09-22 11:07 ` [PATCH 4/8] btrfs: relocation: open code mapping_tree_init David Sterba
@ 2023-09-22 11:07 ` David Sterba
  2023-09-22 12:31   ` Johannes Thumshirn
  2023-09-22 22:31   ` Qu Wenruo
  2023-09-22 11:07 ` [PATCH 6/8] btrfs: relocation: return bool from btrfs_should_ignore_reloc_root David Sterba
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 29+ messages in thread
From: David Sterba @ 2023-09-22 11:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

The btrfs_backref_cache::is_reloc is an indicator variable and should
use a bool type.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/backref.c    | 2 +-
 fs/btrfs/backref.h    | 4 ++--
 fs/btrfs/relocation.c | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 0cde873bdee2..0dc91bf654b5 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -3001,7 +3001,7 @@ int btrfs_backref_iter_next(struct btrfs_backref_iter *iter)
 }
 
 void btrfs_backref_init_cache(struct btrfs_fs_info *fs_info,
-			      struct btrfs_backref_cache *cache, int is_reloc)
+			      struct btrfs_backref_cache *cache, bool is_reloc)
 {
 	int i;
 
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
index 3b077d10bbc0..83a9a34e948e 100644
--- a/fs/btrfs/backref.h
+++ b/fs/btrfs/backref.h
@@ -440,11 +440,11 @@ struct btrfs_backref_cache {
 	 * Reloction backref cache require more info for reloc root compared
 	 * to generic backref cache.
 	 */
-	unsigned int is_reloc;
+	bool is_reloc;
 };
 
 void btrfs_backref_init_cache(struct btrfs_fs_info *fs_info,
-			      struct btrfs_backref_cache *cache, int is_reloc);
+			      struct btrfs_backref_cache *cache, bool is_reloc);
 struct btrfs_backref_node *btrfs_backref_alloc_node(
 		struct btrfs_backref_cache *cache, u64 bytenr, int level);
 struct btrfs_backref_edge *btrfs_backref_alloc_edge(
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 3e662cadecaf..75463377f418 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -4016,7 +4016,7 @@ static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info)
 
 	INIT_LIST_HEAD(&rc->reloc_roots);
 	INIT_LIST_HEAD(&rc->dirty_subvol_roots);
-	btrfs_backref_init_cache(fs_info, &rc->backref_cache, 1);
+	btrfs_backref_init_cache(fs_info, &rc->backref_cache, true);
 	rc->reloc_root_tree.rb_root = RB_ROOT;
 	spin_lock_init(&rc->reloc_root_tree.lock);
 	extent_io_tree_init(fs_info, &rc->processed_blocks, IO_TREE_RELOC_BLOCKS);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 6/8] btrfs: relocation: return bool from btrfs_should_ignore_reloc_root
  2023-09-22 11:07 [PATCH 0/8] Minor cleanups in relocation.c David Sterba
                   ` (4 preceding siblings ...)
  2023-09-22 11:07 ` [PATCH 5/8] btrfs: switch btrfs_backref_cache::is_reloc to bool David Sterba
@ 2023-09-22 11:07 ` David Sterba
  2023-09-22 12:36   ` Johannes Thumshirn
  2023-09-22 22:32   ` Qu Wenruo
  2023-09-22 11:07 ` [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree David Sterba
  2023-09-22 11:07 ` [PATCH 8/8] btrfs: relocation: constify parameters where possible David Sterba
  7 siblings, 2 replies; 29+ messages in thread
From: David Sterba @ 2023-09-22 11:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

btrfs_should_ignore_reloc_root() is a predicate so it should return
bool.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/relocation.c | 19 +++++++++----------
 fs/btrfs/relocation.h |  2 +-
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 75463377f418..d1dcbb15baa7 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -325,31 +325,30 @@ static bool have_reloc_root(struct btrfs_root *root)
 	return true;
 }
 
-int btrfs_should_ignore_reloc_root(struct btrfs_root *root)
+bool btrfs_should_ignore_reloc_root(struct btrfs_root *root)
 {
 	struct btrfs_root *reloc_root;
 
 	if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
-		return 0;
+		return false;
 
 	/* This root has been merged with its reloc tree, we can ignore it */
 	if (reloc_root_is_dead(root))
-		return 1;
+		return true;
 
 	reloc_root = root->reloc_root;
 	if (!reloc_root)
-		return 0;
+		return false;
 
 	if (btrfs_header_generation(reloc_root->commit_root) ==
 	    root->fs_info->running_transaction->transid)
-		return 0;
+		return false;
 	/*
-	 * if there is reloc tree and it was created in previous
-	 * transaction backref lookup can find the reloc tree,
-	 * so backref node for the fs tree root is useless for
-	 * relocation.
+	 * If there is reloc tree and it was created in previous transaction
+	 * backref lookup can find the reloc tree, so backref node for the fs
+	 * tree root is useless for relocation.
 	 */
-	return 1;
+	return true;
 }
 
 /*
diff --git a/fs/btrfs/relocation.h b/fs/btrfs/relocation.h
index 77d69f6ae967..af749c780b4e 100644
--- a/fs/btrfs/relocation.h
+++ b/fs/btrfs/relocation.h
@@ -18,7 +18,7 @@ int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
 			      struct btrfs_pending_snapshot *pending);
 int btrfs_should_cancel_balance(struct btrfs_fs_info *fs_info);
 struct btrfs_root *find_reloc_root(struct btrfs_fs_info *fs_info, u64 bytenr);
-int btrfs_should_ignore_reloc_root(struct btrfs_root *root);
+bool btrfs_should_ignore_reloc_root(struct btrfs_root *root);
 u64 btrfs_get_reloc_bg_bytenr(struct btrfs_fs_info *fs_info);
 
 #endif
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree
  2023-09-22 11:07 [PATCH 0/8] Minor cleanups in relocation.c David Sterba
                   ` (5 preceding siblings ...)
  2023-09-22 11:07 ` [PATCH 6/8] btrfs: relocation: return bool from btrfs_should_ignore_reloc_root David Sterba
@ 2023-09-22 11:07 ` David Sterba
  2023-09-22 12:46   ` Johannes Thumshirn
                     ` (2 more replies)
  2023-09-22 11:07 ` [PATCH 8/8] btrfs: relocation: constify parameters where possible David Sterba
  7 siblings, 3 replies; 29+ messages in thread
From: David Sterba @ 2023-09-22 11:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

build_backref_tree() is called in a loop by relocate_tree_blocks()
for each relocated block. The iterator is allocated and freed repeatedly
while we could simply use an on-stack variable to avoid the allocation
and remove one more failure case. The stack grows by 48 bytes.

This was the only use of btrfs_backref_iter_alloc() so it's changed to
be an initializer and btrfs_backref_iter_free() can be removed
completely.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/backref.c    | 26 ++++++++++----------------
 fs/btrfs/backref.h    | 11 ++---------
 fs/btrfs/relocation.c | 12 ++++++------
 3 files changed, 18 insertions(+), 31 deletions(-)

diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 0dc91bf654b5..691b20b47065 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -2828,26 +2828,20 @@ void free_ipath(struct inode_fs_paths *ipath)
 	kfree(ipath);
 }
 
-struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_info)
+int btrfs_backref_iter_init(struct btrfs_fs_info *fs_info,
+			    struct btrfs_backref_iter *iter)
 {
-	struct btrfs_backref_iter *ret;
-
-	ret = kzalloc(sizeof(*ret), GFP_NOFS);
-	if (!ret)
-		return NULL;
-
-	ret->path = btrfs_alloc_path();
-	if (!ret->path) {
-		kfree(ret);
-		return NULL;
-	}
+	memset(iter, 0, sizeof(struct btrfs_backref_iter));
+	iter->path = btrfs_alloc_path();
+	if (!iter->path)
+		return -ENOMEM;
 
 	/* Current backref iterator only supports iteration in commit root */
-	ret->path->search_commit_root = 1;
-	ret->path->skip_locking = 1;
-	ret->fs_info = fs_info;
+	iter->path->search_commit_root = 1;
+	iter->path->skip_locking = 1;
+	iter->fs_info = fs_info;
 
-	return ret;
+	return 0;
 }
 
 int btrfs_backref_iter_start(struct btrfs_backref_iter *iter, u64 bytenr)
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
index 83a9a34e948e..24fabbd2a80a 100644
--- a/fs/btrfs/backref.h
+++ b/fs/btrfs/backref.h
@@ -269,15 +269,8 @@ struct btrfs_backref_iter {
 	u32 end_ptr;
 };
 
-struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_info);
-
-static inline void btrfs_backref_iter_free(struct btrfs_backref_iter *iter)
-{
-	if (!iter)
-		return;
-	btrfs_free_path(iter->path);
-	kfree(iter);
-}
+int btrfs_backref_iter_init(struct btrfs_fs_info *fs_info,
+			    struct btrfs_backref_iter *iter);
 
 static inline struct extent_buffer *btrfs_backref_get_eb(
 		struct btrfs_backref_iter *iter)
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index d1dcbb15baa7..6a31e73c3df7 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -464,7 +464,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
 			struct reloc_control *rc, struct btrfs_key *node_key,
 			int level, u64 bytenr)
 {
-	struct btrfs_backref_iter *iter;
+	struct btrfs_backref_iter iter;
 	struct btrfs_backref_cache *cache = &rc->backref_cache;
 	/* For searching parent of TREE_BLOCK_REF */
 	struct btrfs_path *path;
@@ -474,9 +474,9 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
 	int ret;
 	int err = 0;
 
-	iter = btrfs_backref_iter_alloc(rc->extent_root->fs_info);
-	if (!iter)
-		return ERR_PTR(-ENOMEM);
+	ret = btrfs_backref_iter_init(rc->extent_root->fs_info, &iter);
+	if (ret < 0)
+		return ERR_PTR(ret);
 	path = btrfs_alloc_path();
 	if (!path) {
 		err = -ENOMEM;
@@ -494,7 +494,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
 
 	/* Breadth-first search to build backref cache */
 	do {
-		ret = btrfs_backref_add_tree_node(cache, path, iter, node_key,
+		ret = btrfs_backref_add_tree_node(cache, path, &iter, node_key,
 						  cur);
 		if (ret < 0) {
 			err = ret;
@@ -522,7 +522,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
 	if (handle_useless_nodes(rc, node))
 		node = NULL;
 out:
-	btrfs_backref_iter_free(iter);
+	btrfs_backref_iter_release(&iter);
 	btrfs_free_path(path);
 	if (err) {
 		btrfs_backref_error_cleanup(cache, node);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 8/8] btrfs: relocation: constify parameters where possible
  2023-09-22 11:07 [PATCH 0/8] Minor cleanups in relocation.c David Sterba
                   ` (6 preceding siblings ...)
  2023-09-22 11:07 ` [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree David Sterba
@ 2023-09-22 11:07 ` David Sterba
  2023-09-22 12:43   ` Johannes Thumshirn
  7 siblings, 1 reply; 29+ messages in thread
From: David Sterba @ 2023-09-22 11:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Lots of the functions in relocation.c don't change pointer parameters
but lack the annotations. Add them and reformat according to current
coding style if needed.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/relocation.c | 56 +++++++++++++++++++++----------------------
 fs/btrfs/relocation.h |  9 +++----
 2 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 6a31e73c3df7..903621a65244 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -295,7 +295,7 @@ static int update_backref_cache(struct btrfs_trans_handle *trans,
 	return 1;
 }
 
-static bool reloc_root_is_dead(struct btrfs_root *root)
+static bool reloc_root_is_dead(const struct btrfs_root *root)
 {
 	/*
 	 * Pair with set_bit/clear_bit in clean_dirty_subvols and
@@ -316,7 +316,7 @@ static bool reloc_root_is_dead(struct btrfs_root *root)
  * from no reloc root.  But btrfs_should_ignore_reloc_root() below is a
  * special case.
  */
-static bool have_reloc_root(struct btrfs_root *root)
+static bool have_reloc_root(const struct btrfs_root *root)
 {
 	if (reloc_root_is_dead(root))
 		return false;
@@ -325,7 +325,7 @@ static bool have_reloc_root(struct btrfs_root *root)
 	return true;
 }
 
-bool btrfs_should_ignore_reloc_root(struct btrfs_root *root)
+bool btrfs_should_ignore_reloc_root(const struct btrfs_root *root)
 {
 	struct btrfs_root *reloc_root;
 
@@ -541,7 +541,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
  */
 static int clone_backref_node(struct btrfs_trans_handle *trans,
 			      struct reloc_control *rc,
-			      struct btrfs_root *src,
+			      const struct btrfs_root *src,
 			      struct btrfs_root *dest)
 {
 	struct btrfs_root *reloc_root = src->reloc_root;
@@ -1181,9 +1181,9 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
 	return ret;
 }
 
-static noinline_for_stack
-int memcmp_node_keys(struct extent_buffer *eb, int slot,
-		     struct btrfs_path *path, int level)
+static noinline_for_stack int memcmp_node_keys(const struct extent_buffer *eb,
+					       int slot, const struct btrfs_path *path,
+					       int level)
 {
 	struct btrfs_disk_key key1;
 	struct btrfs_disk_key key2;
@@ -1515,8 +1515,8 @@ int walk_down_reloc_tree(struct btrfs_root *root, struct btrfs_path *path,
  * [min_key, max_key)
  */
 static int invalidate_extent_cache(struct btrfs_root *root,
-				   struct btrfs_key *min_key,
-				   struct btrfs_key *max_key)
+				   const struct btrfs_key *min_key,
+				   const struct btrfs_key *max_key)
 {
 	struct btrfs_fs_info *fs_info = root->fs_info;
 	struct inode *inode = NULL;
@@ -2828,7 +2828,7 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
 
 static noinline_for_stack int prealloc_file_extent_cluster(
 				struct btrfs_inode *inode,
-				struct file_extent_cluster *cluster)
+				const struct file_extent_cluster *cluster)
 {
 	u64 alloc_hint = 0;
 	u64 start;
@@ -2963,7 +2963,7 @@ static noinline_for_stack int setup_relocation_extent_mapping(struct inode *inod
 /*
  * Allow error injection to test balance/relocation cancellation
  */
-noinline int btrfs_should_cancel_balance(struct btrfs_fs_info *fs_info)
+noinline int btrfs_should_cancel_balance(const struct btrfs_fs_info *fs_info)
 {
 	return atomic_read(&fs_info->balance_cancel_req) ||
 		atomic_read(&fs_info->reloc_cancel_req) ||
@@ -2971,7 +2971,7 @@ noinline int btrfs_should_cancel_balance(struct btrfs_fs_info *fs_info)
 }
 ALLOW_ERROR_INJECTION(btrfs_should_cancel_balance, TRUE);
 
-static u64 get_cluster_boundary_end(struct file_extent_cluster *cluster,
+static u64 get_cluster_boundary_end(const struct file_extent_cluster *cluster,
 				    int cluster_nr)
 {
 	/* Last extent, use cluster end directly */
@@ -2983,7 +2983,7 @@ static u64 get_cluster_boundary_end(struct file_extent_cluster *cluster,
 }
 
 static int relocate_one_page(struct inode *inode, struct file_ra_state *ra,
-			     struct file_extent_cluster *cluster,
+			     const struct file_extent_cluster *cluster,
 			     int *cluster_nr, unsigned long page_index)
 {
 	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
@@ -3118,7 +3118,7 @@ static int relocate_one_page(struct inode *inode, struct file_ra_state *ra,
 }
 
 static int relocate_file_extent_cluster(struct inode *inode,
-					struct file_extent_cluster *cluster)
+					const struct file_extent_cluster *cluster)
 {
 	u64 offset = BTRFS_I(inode)->index_cnt;
 	unsigned long index;
@@ -3156,9 +3156,9 @@ static int relocate_file_extent_cluster(struct inode *inode,
 	return ret;
 }
 
-static noinline_for_stack
-int relocate_data_extent(struct inode *inode, struct btrfs_key *extent_key,
-			 struct file_extent_cluster *cluster)
+static noinline_for_stack int relocate_data_extent(struct inode *inode,
+				const struct btrfs_key *extent_key,
+				struct file_extent_cluster *cluster)
 {
 	int ret;
 	struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -3222,7 +3222,7 @@ int relocate_data_extent(struct inode *inode, struct btrfs_key *extent_key,
  * the major work is getting the generation and level of the block
  */
 static int add_tree_block(struct reloc_control *rc,
-			  struct btrfs_key *extent_key,
+			  const struct btrfs_key *extent_key,
 			  struct btrfs_path *path,
 			  struct rb_root *blocks)
 {
@@ -3473,11 +3473,10 @@ static int delete_v1_space_cache(struct extent_buffer *leaf,
 /*
  * helper to find all tree blocks that reference a given data extent
  */
-static noinline_for_stack
-int add_data_references(struct reloc_control *rc,
-			struct btrfs_key *extent_key,
-			struct btrfs_path *path,
-			struct rb_root *blocks)
+static noinline_for_stack int add_data_references(struct reloc_control *rc,
+						  const struct btrfs_key *extent_key,
+						  struct btrfs_path *path,
+						  struct rb_root *blocks)
 {
 	struct btrfs_backref_walk_ctx ctx = { 0 };
 	struct ulist_iterator leaf_uiter;
@@ -3918,9 +3917,9 @@ static void delete_orphan_inode(struct btrfs_trans_handle *trans,
  * helper to create inode for data relocation.
  * the inode is in data relocation tree and its link count is 0
  */
-static noinline_for_stack
-struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
-				 struct btrfs_block_group *group)
+static noinline_for_stack struct inode *create_reloc_inode(
+					struct btrfs_fs_info *fs_info,
+					const struct btrfs_block_group *group)
 {
 	struct inode *inode = NULL;
 	struct btrfs_trans_handle *trans;
@@ -4467,7 +4466,8 @@ int btrfs_reloc_clone_csums(struct btrfs_ordered_extent *ordered)
 }
 
 int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
-			  struct btrfs_root *root, struct extent_buffer *buf,
+			  struct btrfs_root *root,
+			  const struct extent_buffer *buf,
 			  struct extent_buffer *cow)
 {
 	struct btrfs_fs_info *fs_info = root->fs_info;
@@ -4606,7 +4606,7 @@ int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
  *
  * Return U64_MAX if no running relocation.
  */
-u64 btrfs_get_reloc_bg_bytenr(struct btrfs_fs_info *fs_info)
+u64 btrfs_get_reloc_bg_bytenr(const struct btrfs_fs_info *fs_info)
 {
 	u64 logical = U64_MAX;
 
diff --git a/fs/btrfs/relocation.h b/fs/btrfs/relocation.h
index af749c780b4e..5fb60f2deb53 100644
--- a/fs/btrfs/relocation.h
+++ b/fs/btrfs/relocation.h
@@ -10,15 +10,16 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
 int btrfs_recover_relocation(struct btrfs_fs_info *fs_info);
 int btrfs_reloc_clone_csums(struct btrfs_ordered_extent *ordered);
 int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
-			  struct btrfs_root *root, struct extent_buffer *buf,
+			  struct btrfs_root *root,
+			  const struct extent_buffer *buf,
 			  struct extent_buffer *cow);
 void btrfs_reloc_pre_snapshot(struct btrfs_pending_snapshot *pending,
 			      u64 *bytes_to_reserve);
 int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
 			      struct btrfs_pending_snapshot *pending);
-int btrfs_should_cancel_balance(struct btrfs_fs_info *fs_info);
+int btrfs_should_cancel_balance(const struct btrfs_fs_info *fs_info);
 struct btrfs_root *find_reloc_root(struct btrfs_fs_info *fs_info, u64 bytenr);
-bool btrfs_should_ignore_reloc_root(struct btrfs_root *root);
-u64 btrfs_get_reloc_bg_bytenr(struct btrfs_fs_info *fs_info);
+bool btrfs_should_ignore_reloc_root(const struct btrfs_root *root);
+u64 btrfs_get_reloc_bg_bytenr(const struct btrfs_fs_info *fs_info);
 
 #endif
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/8] btrfs: relocation: use more natural types for tree_block bitfields
  2023-09-22 11:07 ` [PATCH 1/8] btrfs: relocation: use more natural types for tree_block bitfields David Sterba
@ 2023-09-22 12:28   ` Johannes Thumshirn
  2023-09-22 22:28   ` Qu Wenruo
  1 sibling, 0 replies; 29+ messages in thread
From: Johannes Thumshirn @ 2023-09-22 12:28 UTC (permalink / raw)
  To: David Sterba, linux-btrfs@vger.kernel.org

Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/8] btrfs: relocation: use enum for stages
  2023-09-22 11:07 ` [PATCH 2/8] btrfs: relocation: use enum for stages David Sterba
@ 2023-09-22 12:29   ` Johannes Thumshirn
  2023-09-22 22:29   ` Qu Wenruo
  1 sibling, 0 replies; 29+ messages in thread
From: Johannes Thumshirn @ 2023-09-22 12:29 UTC (permalink / raw)
  To: David Sterba, linux-btrfs@vger.kernel.org

Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/8] btrfs: relocation: switch bitfields to bool in reloc_control
  2023-09-22 11:07 ` [PATCH 3/8] btrfs: relocation: switch bitfields to bool in reloc_control David Sterba
@ 2023-09-22 12:30   ` Johannes Thumshirn
  2023-09-22 22:30   ` Qu Wenruo
  1 sibling, 0 replies; 29+ messages in thread
From: Johannes Thumshirn @ 2023-09-22 12:30 UTC (permalink / raw)
  To: David Sterba, linux-btrfs@vger.kernel.org

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 4/8] btrfs: relocation: open code mapping_tree_init
  2023-09-22 11:07 ` [PATCH 4/8] btrfs: relocation: open code mapping_tree_init David Sterba
@ 2023-09-22 12:31   ` Johannes Thumshirn
  2023-09-22 22:31   ` Qu Wenruo
  1 sibling, 0 replies; 29+ messages in thread
From: Johannes Thumshirn @ 2023-09-22 12:31 UTC (permalink / raw)
  To: David Sterba, linux-btrfs@vger.kernel.org

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 5/8] btrfs: switch btrfs_backref_cache::is_reloc to bool
  2023-09-22 11:07 ` [PATCH 5/8] btrfs: switch btrfs_backref_cache::is_reloc to bool David Sterba
@ 2023-09-22 12:31   ` Johannes Thumshirn
  2023-09-22 22:31   ` Qu Wenruo
  1 sibling, 0 replies; 29+ messages in thread
From: Johannes Thumshirn @ 2023-09-22 12:31 UTC (permalink / raw)
  To: David Sterba, linux-btrfs@vger.kernel.org

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 6/8] btrfs: relocation: return bool from btrfs_should_ignore_reloc_root
  2023-09-22 11:07 ` [PATCH 6/8] btrfs: relocation: return bool from btrfs_should_ignore_reloc_root David Sterba
@ 2023-09-22 12:36   ` Johannes Thumshirn
  2023-09-22 18:35     ` David Sterba
  2023-09-22 22:32   ` Qu Wenruo
  1 sibling, 1 reply; 29+ messages in thread
From: Johannes Thumshirn @ 2023-09-22 12:36 UTC (permalink / raw)
  To: David Sterba, linux-btrfs@vger.kernel.org

On 22.09.23 13:14, David Sterba wrote:
> btrfs_should_ignore_reloc_root() is a predicate so it should return
> bool.

Btw both callsites also check for btrfs_backref_cache::is_reloc, so 
maybe that check can be merged into btrfs_should_ignore_reloc_root() as 
well?

Anyways,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 8/8] btrfs: relocation: constify parameters where possible
  2023-09-22 11:07 ` [PATCH 8/8] btrfs: relocation: constify parameters where possible David Sterba
@ 2023-09-22 12:43   ` Johannes Thumshirn
  0 siblings, 0 replies; 29+ messages in thread
From: Johannes Thumshirn @ 2023-09-22 12:43 UTC (permalink / raw)
  To: David Sterba, linux-btrfs@vger.kernel.org

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree
  2023-09-22 11:07 ` [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree David Sterba
@ 2023-09-22 12:46   ` Johannes Thumshirn
  2023-09-22 22:35   ` Qu Wenruo
  2023-10-04 12:35   ` Filipe Manana
  2 siblings, 0 replies; 29+ messages in thread
From: Johannes Thumshirn @ 2023-09-22 12:46 UTC (permalink / raw)
  To: David Sterba, linux-btrfs@vger.kernel.org

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 6/8] btrfs: relocation: return bool from btrfs_should_ignore_reloc_root
  2023-09-22 12:36   ` Johannes Thumshirn
@ 2023-09-22 18:35     ` David Sterba
  0 siblings, 0 replies; 29+ messages in thread
From: David Sterba @ 2023-09-22 18:35 UTC (permalink / raw)
  To: Johannes Thumshirn; +Cc: David Sterba, linux-btrfs@vger.kernel.org

On Fri, Sep 22, 2023 at 12:36:31PM +0000, Johannes Thumshirn wrote:
> On 22.09.23 13:14, David Sterba wrote:
> > btrfs_should_ignore_reloc_root() is a predicate so it should return
> > bool.
> 
> Btw both callsites also check for btrfs_backref_cache::is_reloc, so 
> maybe that check can be merged into btrfs_should_ignore_reloc_root() as 
> well?

The helper is related to the root, for the is_reloc it would also have
to take the cache which looks like a separate thing. I think it would
obscure the condition.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/8] btrfs: relocation: use more natural types for tree_block bitfields
  2023-09-22 11:07 ` [PATCH 1/8] btrfs: relocation: use more natural types for tree_block bitfields David Sterba
  2023-09-22 12:28   ` Johannes Thumshirn
@ 2023-09-22 22:28   ` Qu Wenruo
  1 sibling, 0 replies; 29+ messages in thread
From: Qu Wenruo @ 2023-09-22 22:28 UTC (permalink / raw)
  To: David Sterba, linux-btrfs



On 2023/9/22 20:37, David Sterba wrote:
> We don't need to use bitfields for tree_block::level and
> tree_block::key_ready, there's enough padding in the structure for
> proper types.
>
> Signed-off-by: David Sterba <dsterba@suse.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>   fs/btrfs/relocation.c | 8 ++++----
>   1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index 6e8e14d1aeaa..9ff3572a8451 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -111,8 +111,8 @@ struct tree_block {
>   	}; /* Use rb_simple_node for search/insert */
>   	u64 owner;
>   	struct btrfs_key key;
> -	unsigned int level:8;
> -	unsigned int key_ready:1;
> +	u8 level;
> +	bool key_ready;
>   };
>
>   #define MAX_EXTENTS 128
> @@ -2664,7 +2664,7 @@ static int get_tree_block_key(struct btrfs_fs_info *fs_info,
>   	else
>   		btrfs_node_key_to_cpu(eb, &block->key, 0);
>   	free_extent_buffer(eb);
> -	block->key_ready = 1;
> +	block->key_ready = true;
>   	return 0;
>   }
>
> @@ -3313,7 +3313,7 @@ static int add_tree_block(struct reloc_control *rc,
>   	block->key.objectid = rc->extent_root->fs_info->nodesize;
>   	block->key.offset = generation;
>   	block->level = level;
> -	block->key_ready = 0;
> +	block->key_ready = false;
>   	block->owner = owner;
>
>   	rb_node = rb_simple_insert(blocks, block->bytenr, &block->rb_node);

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/8] btrfs: relocation: use enum for stages
  2023-09-22 11:07 ` [PATCH 2/8] btrfs: relocation: use enum for stages David Sterba
  2023-09-22 12:29   ` Johannes Thumshirn
@ 2023-09-22 22:29   ` Qu Wenruo
  2023-09-25 13:44     ` David Sterba
  1 sibling, 1 reply; 29+ messages in thread
From: Qu Wenruo @ 2023-09-22 22:29 UTC (permalink / raw)
  To: David Sterba, linux-btrfs



On 2023/9/22 20:37, David Sterba wrote:
> Add an enum type for data relocation stages.
>
> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
>   fs/btrfs/relocation.c | 16 +++++++++-------
>   1 file changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index 9ff3572a8451..3afe499f00b1 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -125,6 +125,12 @@ struct file_extent_cluster {
>   	u64 owning_root;
>   };
>
> +/* Stages of data relocation. */
> +enum reloc_stage {
> +	MOVE_DATA_EXTENTS,
> +	UPDATE_DATA_PTRS
> +};
> +
>   struct reloc_control {
>   	/* block group to relocate */
>   	struct btrfs_block_group *block_group;
> @@ -156,16 +162,12 @@ struct reloc_control {
>   	u64 search_start;
>   	u64 extents_found;
>
> -	unsigned int stage:8;
> +	enum reloc_stage stage;

Wouldn't this cause extra hole?

Thanks,
Qu
>   	unsigned int create_reloc_tree:1;
>   	unsigned int merge_reloc_tree:1;
>   	unsigned int found_file_extent:1;
>   };
>
> -/* stages of data relocation */
> -#define MOVE_DATA_EXTENTS	0
> -#define UPDATE_DATA_PTRS	1
> -
>   static void mark_block_processed(struct reloc_control *rc,
>   				 struct btrfs_backref_node *node)
>   {
> @@ -4054,7 +4056,7 @@ static void describe_relocation(struct btrfs_fs_info *fs_info,
>   		   block_group->start, buf);
>   }
>
> -static const char *stage_to_string(int stage)
> +static const char *stage_to_string(enum reloc_stage stage)
>   {
>   	if (stage == MOVE_DATA_EXTENTS)
>   		return "move data extents";
> @@ -4170,7 +4172,7 @@ int btrfs_relocate_block_group(struct btrfs_fs_info *fs_info, u64 group_start)
>   	WARN_ON(ret && ret != -EAGAIN);
>
>   	while (1) {
> -		int finishes_stage;
> +		enum reloc_stage finishes_stage;
>
>   		mutex_lock(&fs_info->cleaner_mutex);
>   		ret = relocate_block_group(rc);

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/8] btrfs: relocation: switch bitfields to bool in reloc_control
  2023-09-22 11:07 ` [PATCH 3/8] btrfs: relocation: switch bitfields to bool in reloc_control David Sterba
  2023-09-22 12:30   ` Johannes Thumshirn
@ 2023-09-22 22:30   ` Qu Wenruo
  1 sibling, 0 replies; 29+ messages in thread
From: Qu Wenruo @ 2023-09-22 22:30 UTC (permalink / raw)
  To: David Sterba, linux-btrfs



On 2023/9/22 20:37, David Sterba wrote:
> Use bool types for the indicators instead of bitfields. The structure
> size slightly grows but the new types are placed within the padding.
>
> Signed-off-by: David Sterba <dsterba@suse.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>   fs/btrfs/relocation.c | 18 +++++++++---------
>   1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index 3afe499f00b1..87ac8528032c 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -163,9 +163,9 @@ struct reloc_control {
>   	u64 extents_found;
>
>   	enum reloc_stage stage;
> -	unsigned int create_reloc_tree:1;
> -	unsigned int merge_reloc_tree:1;
> -	unsigned int found_file_extent:1;
> +	bool create_reloc_tree;
> +	bool merge_reloc_tree;
> +	bool found_file_extent;
>   };
>
>   static void mark_block_processed(struct reloc_control *rc,
> @@ -1902,7 +1902,7 @@ int prepare_to_merge(struct reloc_control *rc, int err)
>   		}
>   	}
>
> -	rc->merge_reloc_tree = 1;
> +	rc->merge_reloc_tree = true;
>
>   	while (!list_empty(&rc->reloc_roots)) {
>   		reloc_root = list_entry(rc->reloc_roots.next,
> @@ -3659,7 +3659,7 @@ int prepare_to_relocate(struct reloc_control *rc)
>   	if (ret)
>   		return ret;
>
> -	rc->create_reloc_tree = 1;
> +	rc->create_reloc_tree = true;
>   	set_reloc_control(rc);
>
>   	trans = btrfs_join_transaction(rc->extent_root);
> @@ -3786,7 +3786,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
>
>   		if (rc->stage == MOVE_DATA_EXTENTS &&
>   		    (flags & BTRFS_EXTENT_FLAG_DATA)) {
> -			rc->found_file_extent = 1;
> +			rc->found_file_extent = true;
>   			ret = relocate_data_extent(rc->data_inode,
>   						   &key, &rc->cluster);
>   			if (ret < 0) {
> @@ -3823,7 +3823,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
>   			err = ret;
>   	}
>
> -	rc->create_reloc_tree = 0;
> +	rc->create_reloc_tree = false;
>   	set_reloc_control(rc);
>
>   	btrfs_backref_release_cache(&rc->backref_cache);
> @@ -3841,7 +3841,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
>
>   	merge_reloc_roots(rc);
>
> -	rc->merge_reloc_tree = 0;
> +	rc->merge_reloc_tree = false;
>   	unset_reloc_control(rc);
>   	btrfs_block_rsv_release(fs_info, rc->block_rsv, (u64)-1, NULL);
>
> @@ -4355,7 +4355,7 @@ int btrfs_recover_relocation(struct btrfs_fs_info *fs_info)
>   		goto out_unset;
>   	}
>
> -	rc->merge_reloc_tree = 1;
> +	rc->merge_reloc_tree = true;
>
>   	while (!list_empty(&reloc_roots)) {
>   		reloc_root = list_entry(reloc_roots.next,

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 4/8] btrfs: relocation: open code mapping_tree_init
  2023-09-22 11:07 ` [PATCH 4/8] btrfs: relocation: open code mapping_tree_init David Sterba
  2023-09-22 12:31   ` Johannes Thumshirn
@ 2023-09-22 22:31   ` Qu Wenruo
  1 sibling, 0 replies; 29+ messages in thread
From: Qu Wenruo @ 2023-09-22 22:31 UTC (permalink / raw)
  To: David Sterba, linux-btrfs



On 2023/9/22 20:37, David Sterba wrote:
> There's only one user of mapping_tree_init, we don't need a helper for
> the simple initialization.
>
> Signed-off-by: David Sterba <dsterba@suse.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>   fs/btrfs/relocation.c | 10 ++--------
>   1 file changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index 87ac8528032c..3e662cadecaf 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -183,13 +183,6 @@ static void mark_block_processed(struct reloc_control *rc,
>   	node->processed = 1;
>   }
>
> -
> -static void mapping_tree_init(struct mapping_tree *tree)
> -{
> -	tree->rb_root = RB_ROOT;
> -	spin_lock_init(&tree->lock);
> -}
> -
>   /*
>    * walk up backref nodes until reach node presents tree root
>    */
> @@ -4024,7 +4017,8 @@ static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info)
>   	INIT_LIST_HEAD(&rc->reloc_roots);
>   	INIT_LIST_HEAD(&rc->dirty_subvol_roots);
>   	btrfs_backref_init_cache(fs_info, &rc->backref_cache, 1);
> -	mapping_tree_init(&rc->reloc_root_tree);
> +	rc->reloc_root_tree.rb_root = RB_ROOT;
> +	spin_lock_init(&rc->reloc_root_tree.lock);
>   	extent_io_tree_init(fs_info, &rc->processed_blocks, IO_TREE_RELOC_BLOCKS);
>   	return rc;
>   }

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 5/8] btrfs: switch btrfs_backref_cache::is_reloc to bool
  2023-09-22 11:07 ` [PATCH 5/8] btrfs: switch btrfs_backref_cache::is_reloc to bool David Sterba
  2023-09-22 12:31   ` Johannes Thumshirn
@ 2023-09-22 22:31   ` Qu Wenruo
  1 sibling, 0 replies; 29+ messages in thread
From: Qu Wenruo @ 2023-09-22 22:31 UTC (permalink / raw)
  To: David Sterba, linux-btrfs



On 2023/9/22 20:37, David Sterba wrote:
> The btrfs_backref_cache::is_reloc is an indicator variable and should
> use a bool type.
>
> Signed-off-by: David Sterba <dsterba@suse.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>   fs/btrfs/backref.c    | 2 +-
>   fs/btrfs/backref.h    | 4 ++--
>   fs/btrfs/relocation.c | 2 +-
>   3 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
> index 0cde873bdee2..0dc91bf654b5 100644
> --- a/fs/btrfs/backref.c
> +++ b/fs/btrfs/backref.c
> @@ -3001,7 +3001,7 @@ int btrfs_backref_iter_next(struct btrfs_backref_iter *iter)
>   }
>
>   void btrfs_backref_init_cache(struct btrfs_fs_info *fs_info,
> -			      struct btrfs_backref_cache *cache, int is_reloc)
> +			      struct btrfs_backref_cache *cache, bool is_reloc)
>   {
>   	int i;
>
> diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
> index 3b077d10bbc0..83a9a34e948e 100644
> --- a/fs/btrfs/backref.h
> +++ b/fs/btrfs/backref.h
> @@ -440,11 +440,11 @@ struct btrfs_backref_cache {
>   	 * Reloction backref cache require more info for reloc root compared
>   	 * to generic backref cache.
>   	 */
> -	unsigned int is_reloc;
> +	bool is_reloc;
>   };
>
>   void btrfs_backref_init_cache(struct btrfs_fs_info *fs_info,
> -			      struct btrfs_backref_cache *cache, int is_reloc);
> +			      struct btrfs_backref_cache *cache, bool is_reloc);
>   struct btrfs_backref_node *btrfs_backref_alloc_node(
>   		struct btrfs_backref_cache *cache, u64 bytenr, int level);
>   struct btrfs_backref_edge *btrfs_backref_alloc_edge(
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index 3e662cadecaf..75463377f418 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -4016,7 +4016,7 @@ static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info)
>
>   	INIT_LIST_HEAD(&rc->reloc_roots);
>   	INIT_LIST_HEAD(&rc->dirty_subvol_roots);
> -	btrfs_backref_init_cache(fs_info, &rc->backref_cache, 1);
> +	btrfs_backref_init_cache(fs_info, &rc->backref_cache, true);
>   	rc->reloc_root_tree.rb_root = RB_ROOT;
>   	spin_lock_init(&rc->reloc_root_tree.lock);
>   	extent_io_tree_init(fs_info, &rc->processed_blocks, IO_TREE_RELOC_BLOCKS);

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 6/8] btrfs: relocation: return bool from btrfs_should_ignore_reloc_root
  2023-09-22 11:07 ` [PATCH 6/8] btrfs: relocation: return bool from btrfs_should_ignore_reloc_root David Sterba
  2023-09-22 12:36   ` Johannes Thumshirn
@ 2023-09-22 22:32   ` Qu Wenruo
  1 sibling, 0 replies; 29+ messages in thread
From: Qu Wenruo @ 2023-09-22 22:32 UTC (permalink / raw)
  To: David Sterba, linux-btrfs



On 2023/9/22 20:37, David Sterba wrote:
> btrfs_should_ignore_reloc_root() is a predicate so it should return
> bool.
>
> Signed-off-by: David Sterba <dsterba@suse.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>   fs/btrfs/relocation.c | 19 +++++++++----------
>   fs/btrfs/relocation.h |  2 +-
>   2 files changed, 10 insertions(+), 11 deletions(-)
>
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index 75463377f418..d1dcbb15baa7 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -325,31 +325,30 @@ static bool have_reloc_root(struct btrfs_root *root)
>   	return true;
>   }
>
> -int btrfs_should_ignore_reloc_root(struct btrfs_root *root)
> +bool btrfs_should_ignore_reloc_root(struct btrfs_root *root)
>   {
>   	struct btrfs_root *reloc_root;
>
>   	if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
> -		return 0;
> +		return false;
>
>   	/* This root has been merged with its reloc tree, we can ignore it */
>   	if (reloc_root_is_dead(root))
> -		return 1;
> +		return true;
>
>   	reloc_root = root->reloc_root;
>   	if (!reloc_root)
> -		return 0;
> +		return false;
>
>   	if (btrfs_header_generation(reloc_root->commit_root) ==
>   	    root->fs_info->running_transaction->transid)
> -		return 0;
> +		return false;
>   	/*
> -	 * if there is reloc tree and it was created in previous
> -	 * transaction backref lookup can find the reloc tree,
> -	 * so backref node for the fs tree root is useless for
> -	 * relocation.
> +	 * If there is reloc tree and it was created in previous transaction
> +	 * backref lookup can find the reloc tree, so backref node for the fs
> +	 * tree root is useless for relocation.
>   	 */
> -	return 1;
> +	return true;
>   }
>
>   /*
> diff --git a/fs/btrfs/relocation.h b/fs/btrfs/relocation.h
> index 77d69f6ae967..af749c780b4e 100644
> --- a/fs/btrfs/relocation.h
> +++ b/fs/btrfs/relocation.h
> @@ -18,7 +18,7 @@ int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
>   			      struct btrfs_pending_snapshot *pending);
>   int btrfs_should_cancel_balance(struct btrfs_fs_info *fs_info);
>   struct btrfs_root *find_reloc_root(struct btrfs_fs_info *fs_info, u64 bytenr);
> -int btrfs_should_ignore_reloc_root(struct btrfs_root *root);
> +bool btrfs_should_ignore_reloc_root(struct btrfs_root *root);
>   u64 btrfs_get_reloc_bg_bytenr(struct btrfs_fs_info *fs_info);
>
>   #endif

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree
  2023-09-22 11:07 ` [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree David Sterba
  2023-09-22 12:46   ` Johannes Thumshirn
@ 2023-09-22 22:35   ` Qu Wenruo
  2023-09-25 13:42     ` David Sterba
  2023-10-04 12:35   ` Filipe Manana
  2 siblings, 1 reply; 29+ messages in thread
From: Qu Wenruo @ 2023-09-22 22:35 UTC (permalink / raw)
  To: David Sterba, linux-btrfs



On 2023/9/22 20:37, David Sterba wrote:
> build_backref_tree() is called in a loop by relocate_tree_blocks()
> for each relocated block. The iterator is allocated and freed repeatedly
> while we could simply use an on-stack variable to avoid the allocation
> and remove one more failure case. The stack grows by 48 bytes.
>
> This was the only use of btrfs_backref_iter_alloc() so it's changed to
> be an initializer and btrfs_backref_iter_free() can be removed
> completely.
>
> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
>   fs/btrfs/backref.c    | 26 ++++++++++----------------
>   fs/btrfs/backref.h    | 11 ++---------
>   fs/btrfs/relocation.c | 12 ++++++------
>   3 files changed, 18 insertions(+), 31 deletions(-)
>
> diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
> index 0dc91bf654b5..691b20b47065 100644
> --- a/fs/btrfs/backref.c
> +++ b/fs/btrfs/backref.c
> @@ -2828,26 +2828,20 @@ void free_ipath(struct inode_fs_paths *ipath)
>   	kfree(ipath);
>   }
>
> -struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_info)
> +int btrfs_backref_iter_init(struct btrfs_fs_info *fs_info,
> +			    struct btrfs_backref_iter *iter)
>   {
> -	struct btrfs_backref_iter *ret;
> -
> -	ret = kzalloc(sizeof(*ret), GFP_NOFS);
> -	if (!ret)
> -		return NULL;
> -
> -	ret->path = btrfs_alloc_path();
> -	if (!ret->path) {
> -		kfree(ret);
> -		return NULL;
> -	}
> +	memset(iter, 0, sizeof(struct btrfs_backref_iter));
> +	iter->path = btrfs_alloc_path();
> +	if (!iter->path)
> +		return -ENOMEM;

We can do one step further, by integrating the btrfs_path into @iter,
other than re-allocating it again and again.

Thanks,
Qu
>
>   	/* Current backref iterator only supports iteration in commit root */
> -	ret->path->search_commit_root = 1;
> -	ret->path->skip_locking = 1;
> -	ret->fs_info = fs_info;
> +	iter->path->search_commit_root = 1;
> +	iter->path->skip_locking = 1;
> +	iter->fs_info = fs_info;
>
> -	return ret;
> +	return 0;
>   }
>
>   int btrfs_backref_iter_start(struct btrfs_backref_iter *iter, u64 bytenr)
> diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
> index 83a9a34e948e..24fabbd2a80a 100644
> --- a/fs/btrfs/backref.h
> +++ b/fs/btrfs/backref.h
> @@ -269,15 +269,8 @@ struct btrfs_backref_iter {
>   	u32 end_ptr;
>   };
>
> -struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_info);
> -
> -static inline void btrfs_backref_iter_free(struct btrfs_backref_iter *iter)
> -{
> -	if (!iter)
> -		return;
> -	btrfs_free_path(iter->path);
> -	kfree(iter);
> -}
> +int btrfs_backref_iter_init(struct btrfs_fs_info *fs_info,
> +			    struct btrfs_backref_iter *iter);
>
>   static inline struct extent_buffer *btrfs_backref_get_eb(
>   		struct btrfs_backref_iter *iter)
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index d1dcbb15baa7..6a31e73c3df7 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -464,7 +464,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
>   			struct reloc_control *rc, struct btrfs_key *node_key,
>   			int level, u64 bytenr)
>   {
> -	struct btrfs_backref_iter *iter;
> +	struct btrfs_backref_iter iter;
>   	struct btrfs_backref_cache *cache = &rc->backref_cache;
>   	/* For searching parent of TREE_BLOCK_REF */
>   	struct btrfs_path *path;
> @@ -474,9 +474,9 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
>   	int ret;
>   	int err = 0;
>
> -	iter = btrfs_backref_iter_alloc(rc->extent_root->fs_info);
> -	if (!iter)
> -		return ERR_PTR(-ENOMEM);
> +	ret = btrfs_backref_iter_init(rc->extent_root->fs_info, &iter);
> +	if (ret < 0)
> +		return ERR_PTR(ret);
>   	path = btrfs_alloc_path();
>   	if (!path) {
>   		err = -ENOMEM;
> @@ -494,7 +494,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
>
>   	/* Breadth-first search to build backref cache */
>   	do {
> -		ret = btrfs_backref_add_tree_node(cache, path, iter, node_key,
> +		ret = btrfs_backref_add_tree_node(cache, path, &iter, node_key,
>   						  cur);
>   		if (ret < 0) {
>   			err = ret;
> @@ -522,7 +522,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
>   	if (handle_useless_nodes(rc, node))
>   		node = NULL;
>   out:
> -	btrfs_backref_iter_free(iter);
> +	btrfs_backref_iter_release(&iter);
>   	btrfs_free_path(path);
>   	if (err) {
>   		btrfs_backref_error_cleanup(cache, node);

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree
  2023-09-22 22:35   ` Qu Wenruo
@ 2023-09-25 13:42     ` David Sterba
  0 siblings, 0 replies; 29+ messages in thread
From: David Sterba @ 2023-09-25 13:42 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: David Sterba, linux-btrfs

On Sat, Sep 23, 2023 at 08:05:25AM +0930, Qu Wenruo wrote:
> On 2023/9/22 20:37, David Sterba wrote:
> > build_backref_tree() is called in a loop by relocate_tree_blocks()
> > for each relocated block. The iterator is allocated and freed repeatedly
> > while we could simply use an on-stack variable to avoid the allocation
> > and remove one more failure case. The stack grows by 48 bytes.
> >
> > This was the only use of btrfs_backref_iter_alloc() so it's changed to
> > be an initializer and btrfs_backref_iter_free() can be removed
> > completely.
> >
> > Signed-off-by: David Sterba <dsterba@suse.com>
> > ---
> >   fs/btrfs/backref.c    | 26 ++++++++++----------------
> >   fs/btrfs/backref.h    | 11 ++---------
> >   fs/btrfs/relocation.c | 12 ++++++------
> >   3 files changed, 18 insertions(+), 31 deletions(-)
> >
> > diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
> > index 0dc91bf654b5..691b20b47065 100644
> > --- a/fs/btrfs/backref.c
> > +++ b/fs/btrfs/backref.c
> > @@ -2828,26 +2828,20 @@ void free_ipath(struct inode_fs_paths *ipath)
> >   	kfree(ipath);
> >   }
> >
> > -struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_info)
> > +int btrfs_backref_iter_init(struct btrfs_fs_info *fs_info,
> > +			    struct btrfs_backref_iter *iter)
> >   {
> > -	struct btrfs_backref_iter *ret;
> > -
> > -	ret = kzalloc(sizeof(*ret), GFP_NOFS);
> > -	if (!ret)
> > -		return NULL;
> > -
> > -	ret->path = btrfs_alloc_path();
> > -	if (!ret->path) {
> > -		kfree(ret);
> > -		return NULL;
> > -	}
> > +	memset(iter, 0, sizeof(struct btrfs_backref_iter));
> > +	iter->path = btrfs_alloc_path();
> > +	if (!iter->path)
> > +		return -ENOMEM;
> 
> We can do one step further, by integrating the btrfs_path into @iter,
> other than re-allocating it again and again.

Possible but needs to be evaluated separately, the size of path is 112
and this starts to become noticeable on the stack.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/8] btrfs: relocation: use enum for stages
  2023-09-22 22:29   ` Qu Wenruo
@ 2023-09-25 13:44     ` David Sterba
  0 siblings, 0 replies; 29+ messages in thread
From: David Sterba @ 2023-09-25 13:44 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: David Sterba, linux-btrfs

On Sat, Sep 23, 2023 at 07:59:54AM +0930, Qu Wenruo wrote:
> 
> 
> On 2023/9/22 20:37, David Sterba wrote:
> > Add an enum type for data relocation stages.
> >
> > Signed-off-by: David Sterba <dsterba@suse.com>
> > ---
> >   fs/btrfs/relocation.c | 16 +++++++++-------
> >   1 file changed, 9 insertions(+), 7 deletions(-)
> >
> > diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> > index 9ff3572a8451..3afe499f00b1 100644
> > --- a/fs/btrfs/relocation.c
> > +++ b/fs/btrfs/relocation.c
> > @@ -125,6 +125,12 @@ struct file_extent_cluster {
> >   	u64 owning_root;
> >   };
> >
> > +/* Stages of data relocation. */
> > +enum reloc_stage {
> > +	MOVE_DATA_EXTENTS,
> > +	UPDATE_DATA_PTRS
> > +};
> > +
> >   struct reloc_control {
> >   	/* block group to relocate */
> >   	struct btrfs_block_group *block_group;
> > @@ -156,16 +162,12 @@ struct reloc_control {
> >   	u64 search_start;
> >   	u64 extents_found;
> >
> > -	unsigned int stage:8;
> > +	enum reloc_stage stage;
> 
> Wouldn't this cause extra hole?

No, it's an int and after u64, the bitfields are in an int as well, so
both are aligned. The diff after the change:

@@ -7711,15 +7711,14 @@ struct reloc_control {
        u64                        reserved_bytes;       /*  1496     8 */
        u64                        search_start;         /*  1504     8 */
        u64                        extents_found;        /*  1512     8 */
-       unsigned int               stage:8;              /*  1520: 0  4 */
-       unsigned int               create_reloc_tree:1;  /*  1520: 8  4 */
-       unsigned int               merge_reloc_tree:1;   /*  1520: 9  4 */
-       unsigned int               found_file_extent:1;  /*  1520:10  4 */
+       enum reloc_stage           stage;                /*  1520     4 */
+       unsigned int               create_reloc_tree:1;  /*  1524: 0  4 */
+       unsigned int               merge_reloc_tree:1;   /*  1524: 1  4 */
+       unsigned int               found_file_extent:1;  /*  1524: 2  4 */
 
        /* size: 1528, cachelines: 24, members: 19 */
-       /* padding: 4 */
        /* paddings: 2, sum paddings: 8 */
-       /* bit_padding: 21 bits */
+       /* bit_padding: 29 bits */
        /* last cacheline: 56 bytes */
 };
---

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree
  2023-09-22 11:07 ` [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree David Sterba
  2023-09-22 12:46   ` Johannes Thumshirn
  2023-09-22 22:35   ` Qu Wenruo
@ 2023-10-04 12:35   ` Filipe Manana
  2023-10-04 12:46     ` David Sterba
  2 siblings, 1 reply; 29+ messages in thread
From: Filipe Manana @ 2023-10-04 12:35 UTC (permalink / raw)
  To: David Sterba; +Cc: linux-btrfs

On Fri, Sep 22, 2023 at 2:26 PM David Sterba <dsterba@suse.com> wrote:
>
> build_backref_tree() is called in a loop by relocate_tree_blocks()
> for each relocated block. The iterator is allocated and freed repeatedly
> while we could simply use an on-stack variable to avoid the allocation
> and remove one more failure case. The stack grows by 48 bytes.
>
> This was the only use of btrfs_backref_iter_alloc() so it's changed to
> be an initializer and btrfs_backref_iter_free() can be removed
> completely.
>
> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
>  fs/btrfs/backref.c    | 26 ++++++++++----------------
>  fs/btrfs/backref.h    | 11 ++---------
>  fs/btrfs/relocation.c | 12 ++++++------
>  3 files changed, 18 insertions(+), 31 deletions(-)
>
> diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
> index 0dc91bf654b5..691b20b47065 100644
> --- a/fs/btrfs/backref.c
> +++ b/fs/btrfs/backref.c
> @@ -2828,26 +2828,20 @@ void free_ipath(struct inode_fs_paths *ipath)
>         kfree(ipath);
>  }
>
> -struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_info)
> +int btrfs_backref_iter_init(struct btrfs_fs_info *fs_info,
> +                           struct btrfs_backref_iter *iter)
>  {
> -       struct btrfs_backref_iter *ret;
> -
> -       ret = kzalloc(sizeof(*ret), GFP_NOFS);
> -       if (!ret)
> -               return NULL;
> -
> -       ret->path = btrfs_alloc_path();
> -       if (!ret->path) {
> -               kfree(ret);
> -               return NULL;
> -       }
> +       memset(iter, 0, sizeof(struct btrfs_backref_iter));
> +       iter->path = btrfs_alloc_path();

So this is breaking misc-next, as paths are leaking here, easily
visible after "rmmod btrfs":

[ 2265.115295] =============================================================================
[ 2265.115938] BUG btrfs_path (Not tainted): Objects remaining in
btrfs_path on __kmem_cache_shutdown()
[ 2265.116615] -----------------------------------------------------------------------------

[ 2265.117614] Slab 0x00000000dbb6fd30 objects=36 used=3
fp=0x000000001768ab21
flags=0x17fffc000000800(slab|node=0|zone=2|lastcpupid=0x1ffff)
[ 2265.118423] CPU: 1 PID: 402761 Comm: rmmod Not tainted
6.6.0-rc3-btrfs-next-139+ #1
[ 2265.118440] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
[ 2265.118457] Call Trace:
[ 2265.118483]  <TASK>
[ 2265.118491]  dump_stack_lvl+0x44/0x60
[ 2265.118521]  slab_err+0xb6/0xf0
[ 2265.118547]  __kmem_cache_shutdown+0x15f/0x2f0
[ 2265.118565]  kmem_cache_destroy+0x4c/0x170
[ 2265.118588]  exit_btrfs_fs+0x24/0x40 [btrfs]
[ 2265.119121]  __x64_sys_delete_module+0x193/0x290
[ 2265.119137]  ? exit_to_user_mode_prepare+0x3d/0x170
[ 2265.119154]  do_syscall_64+0x38/0x90
[ 2265.119169]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
[ 2265.119185] RIP: 0033:0x7f55ec127997
[ 2265.119199] Code: 73 01 c3 48 8b 0d 81 94 0c 00 f7 d8 64 89 01 48
83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 b0 00 00
00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 51 94 0c 00 f7 d8 64 89
01 48
[ 2265.119210] RSP: 002b:00007ffe06412d98 EFLAGS: 00000206 ORIG_RAX:
00000000000000b0
[ 2265.119225] RAX: ffffffffffffffda RBX: 00005589627f26f0 RCX: 00007f55ec127997
[ 2265.119234] RDX: 0000000000000000 RSI: 0000000000000800 RDI: 00005589627f2758
[ 2265.119241] RBP: 0000000000000000 R08: 1999999999999999 R09: 0000000000000000
[ 2265.119249] R10: 00007f55ec19aac0 R11: 0000000000000206 R12: 00007ffe06412fe0
[ 2265.119257] R13: 00007ffe064133da R14: 00005589627f22a0 R15: 00007ffe06412fe8
[ 2265.119276]  </TASK>
[ 2265.119281] Disabling lock debugging due to kernel taint
[ 2265.119289] Object 0x0000000062d6ea78 @offset=784
[ 2265.120073] Object 0x0000000042bd66e6 @offset=1904
[ 2265.120712] Object 0x00000000603962f0 @offset=2240
[ 2265.121397] =============================================================================
[ 2265.122021] BUG btrfs_path (Tainted: G    B             ): Objects
remaining in btrfs_path on __kmem_cache_shutdown()
(...)

I get thousands and thousands of these messages after running fstests
and doing "rmmod btrfs".

The problem here is the code is reusing the iterator, and every time
allocating a new path without freeing the previous one.
It could simply avoid path allocation and reuse it.

Thanks.



> +       if (!iter->path)
> +               return -ENOMEM;
>
>         /* Current backref iterator only supports iteration in commit root */
> -       ret->path->search_commit_root = 1;
> -       ret->path->skip_locking = 1;
> -       ret->fs_info = fs_info;
> +       iter->path->search_commit_root = 1;
> +       iter->path->skip_locking = 1;
> +       iter->fs_info = fs_info;
>
> -       return ret;
> +       return 0;
>  }
>
>  int btrfs_backref_iter_start(struct btrfs_backref_iter *iter, u64 bytenr)
> diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
> index 83a9a34e948e..24fabbd2a80a 100644
> --- a/fs/btrfs/backref.h
> +++ b/fs/btrfs/backref.h
> @@ -269,15 +269,8 @@ struct btrfs_backref_iter {
>         u32 end_ptr;
>  };
>
> -struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_info);
> -
> -static inline void btrfs_backref_iter_free(struct btrfs_backref_iter *iter)
> -{
> -       if (!iter)
> -               return;
> -       btrfs_free_path(iter->path);
> -       kfree(iter);
> -}
> +int btrfs_backref_iter_init(struct btrfs_fs_info *fs_info,
> +                           struct btrfs_backref_iter *iter);
>
>  static inline struct extent_buffer *btrfs_backref_get_eb(
>                 struct btrfs_backref_iter *iter)
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index d1dcbb15baa7..6a31e73c3df7 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -464,7 +464,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
>                         struct reloc_control *rc, struct btrfs_key *node_key,
>                         int level, u64 bytenr)
>  {
> -       struct btrfs_backref_iter *iter;
> +       struct btrfs_backref_iter iter;
>         struct btrfs_backref_cache *cache = &rc->backref_cache;
>         /* For searching parent of TREE_BLOCK_REF */
>         struct btrfs_path *path;
> @@ -474,9 +474,9 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
>         int ret;
>         int err = 0;
>
> -       iter = btrfs_backref_iter_alloc(rc->extent_root->fs_info);
> -       if (!iter)
> -               return ERR_PTR(-ENOMEM);
> +       ret = btrfs_backref_iter_init(rc->extent_root->fs_info, &iter);
> +       if (ret < 0)
> +               return ERR_PTR(ret);
>         path = btrfs_alloc_path();
>         if (!path) {
>                 err = -ENOMEM;
> @@ -494,7 +494,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
>
>         /* Breadth-first search to build backref cache */
>         do {
> -               ret = btrfs_backref_add_tree_node(cache, path, iter, node_key,
> +               ret = btrfs_backref_add_tree_node(cache, path, &iter, node_key,
>                                                   cur);
>                 if (ret < 0) {
>                         err = ret;
> @@ -522,7 +522,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
>         if (handle_useless_nodes(rc, node))
>                 node = NULL;
>  out:
> -       btrfs_backref_iter_free(iter);
> +       btrfs_backref_iter_release(&iter);
>         btrfs_free_path(path);
>         if (err) {
>                 btrfs_backref_error_cleanup(cache, node);
> --
> 2.41.0
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree
  2023-10-04 12:35   ` Filipe Manana
@ 2023-10-04 12:46     ` David Sterba
  0 siblings, 0 replies; 29+ messages in thread
From: David Sterba @ 2023-10-04 12:46 UTC (permalink / raw)
  To: Filipe Manana; +Cc: David Sterba, linux-btrfs

On Wed, Oct 04, 2023 at 01:35:26PM +0100, Filipe Manana wrote:
> On Fri, Sep 22, 2023 at 2:26 PM David Sterba <dsterba@suse.com> wrote:
> >
> > build_backref_tree() is called in a loop by relocate_tree_blocks()
> > for each relocated block. The iterator is allocated and freed repeatedly
> > while we could simply use an on-stack variable to avoid the allocation
> > and remove one more failure case. The stack grows by 48 bytes.
> >
> > This was the only use of btrfs_backref_iter_alloc() so it's changed to
> > be an initializer and btrfs_backref_iter_free() can be removed
> > completely.
> >
> > Signed-off-by: David Sterba <dsterba@suse.com>
> > ---
> >  fs/btrfs/backref.c    | 26 ++++++++++----------------
> >  fs/btrfs/backref.h    | 11 ++---------
> >  fs/btrfs/relocation.c | 12 ++++++------
> >  3 files changed, 18 insertions(+), 31 deletions(-)
> >
> > diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
> > index 0dc91bf654b5..691b20b47065 100644
> > --- a/fs/btrfs/backref.c
> > +++ b/fs/btrfs/backref.c
> > @@ -2828,26 +2828,20 @@ void free_ipath(struct inode_fs_paths *ipath)
> >         kfree(ipath);
> >  }
> >
> > -struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_info)
> > +int btrfs_backref_iter_init(struct btrfs_fs_info *fs_info,
> > +                           struct btrfs_backref_iter *iter)
> >  {
> > -       struct btrfs_backref_iter *ret;
> > -
> > -       ret = kzalloc(sizeof(*ret), GFP_NOFS);
> > -       if (!ret)
> > -               return NULL;
> > -
> > -       ret->path = btrfs_alloc_path();
> > -       if (!ret->path) {
> > -               kfree(ret);
> > -               return NULL;
> > -       }
> > +       memset(iter, 0, sizeof(struct btrfs_backref_iter));
> > +       iter->path = btrfs_alloc_path();
> 
> So this is breaking misc-next, as paths are leaking here, easily
> visible after "rmmod btrfs":
> 
> [ 2265.115295] =============================================================================
> [ 2265.115938] BUG btrfs_path (Not tainted): Objects remaining in
> btrfs_path on __kmem_cache_shutdown()
> [ 2265.116615] -----------------------------------------------------------------------------
> 
> [ 2265.117614] Slab 0x00000000dbb6fd30 objects=36 used=3
> fp=0x000000001768ab21
> flags=0x17fffc000000800(slab|node=0|zone=2|lastcpupid=0x1ffff)
> [ 2265.118423] CPU: 1 PID: 402761 Comm: rmmod Not tainted
> 6.6.0-rc3-btrfs-next-139+ #1
> [ 2265.118440] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
> BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
> [ 2265.118457] Call Trace:
> [ 2265.118483]  <TASK>
> [ 2265.118491]  dump_stack_lvl+0x44/0x60
> [ 2265.118521]  slab_err+0xb6/0xf0
> [ 2265.118547]  __kmem_cache_shutdown+0x15f/0x2f0
> [ 2265.118565]  kmem_cache_destroy+0x4c/0x170
> [ 2265.118588]  exit_btrfs_fs+0x24/0x40 [btrfs]
> [ 2265.119121]  __x64_sys_delete_module+0x193/0x290
> [ 2265.119137]  ? exit_to_user_mode_prepare+0x3d/0x170
> [ 2265.119154]  do_syscall_64+0x38/0x90
> [ 2265.119169]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
> [ 2265.119185] RIP: 0033:0x7f55ec127997
> [ 2265.119199] Code: 73 01 c3 48 8b 0d 81 94 0c 00 f7 d8 64 89 01 48
> 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 b0 00 00
> 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 51 94 0c 00 f7 d8 64 89
> 01 48
> [ 2265.119210] RSP: 002b:00007ffe06412d98 EFLAGS: 00000206 ORIG_RAX:
> 00000000000000b0
> [ 2265.119225] RAX: ffffffffffffffda RBX: 00005589627f26f0 RCX: 00007f55ec127997
> [ 2265.119234] RDX: 0000000000000000 RSI: 0000000000000800 RDI: 00005589627f2758
> [ 2265.119241] RBP: 0000000000000000 R08: 1999999999999999 R09: 0000000000000000
> [ 2265.119249] R10: 00007f55ec19aac0 R11: 0000000000000206 R12: 00007ffe06412fe0
> [ 2265.119257] R13: 00007ffe064133da R14: 00005589627f22a0 R15: 00007ffe06412fe8
> [ 2265.119276]  </TASK>
> [ 2265.119281] Disabling lock debugging due to kernel taint
> [ 2265.119289] Object 0x0000000062d6ea78 @offset=784
> [ 2265.120073] Object 0x0000000042bd66e6 @offset=1904
> [ 2265.120712] Object 0x00000000603962f0 @offset=2240
> [ 2265.121397] =============================================================================
> [ 2265.122021] BUG btrfs_path (Tainted: G    B             ): Objects
> remaining in btrfs_path on __kmem_cache_shutdown()
> (...)
> 
> I get thousands and thousands of these messages after running fstests
> and doing "rmmod btrfs".

Thanks, for catching it, I don't seem to have the rmmod test in my
setups.

> The problem here is the code is reusing the iterator, and every time
> allocating a new path without freeing the previous one.
> It could simply avoid path allocation and reuse it.

I'll remove the patch for now and revisit using this suggestion, thanks.

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2023-10-04 12:53 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-22 11:07 [PATCH 0/8] Minor cleanups in relocation.c David Sterba
2023-09-22 11:07 ` [PATCH 1/8] btrfs: relocation: use more natural types for tree_block bitfields David Sterba
2023-09-22 12:28   ` Johannes Thumshirn
2023-09-22 22:28   ` Qu Wenruo
2023-09-22 11:07 ` [PATCH 2/8] btrfs: relocation: use enum for stages David Sterba
2023-09-22 12:29   ` Johannes Thumshirn
2023-09-22 22:29   ` Qu Wenruo
2023-09-25 13:44     ` David Sterba
2023-09-22 11:07 ` [PATCH 3/8] btrfs: relocation: switch bitfields to bool in reloc_control David Sterba
2023-09-22 12:30   ` Johannes Thumshirn
2023-09-22 22:30   ` Qu Wenruo
2023-09-22 11:07 ` [PATCH 4/8] btrfs: relocation: open code mapping_tree_init David Sterba
2023-09-22 12:31   ` Johannes Thumshirn
2023-09-22 22:31   ` Qu Wenruo
2023-09-22 11:07 ` [PATCH 5/8] btrfs: switch btrfs_backref_cache::is_reloc to bool David Sterba
2023-09-22 12:31   ` Johannes Thumshirn
2023-09-22 22:31   ` Qu Wenruo
2023-09-22 11:07 ` [PATCH 6/8] btrfs: relocation: return bool from btrfs_should_ignore_reloc_root David Sterba
2023-09-22 12:36   ` Johannes Thumshirn
2023-09-22 18:35     ` David Sterba
2023-09-22 22:32   ` Qu Wenruo
2023-09-22 11:07 ` [PATCH 7/8] btrfs: relocation: use on-stack iterator in build_backref_tree David Sterba
2023-09-22 12:46   ` Johannes Thumshirn
2023-09-22 22:35   ` Qu Wenruo
2023-09-25 13:42     ` David Sterba
2023-10-04 12:35   ` Filipe Manana
2023-10-04 12:46     ` David Sterba
2023-09-22 11:07 ` [PATCH 8/8] btrfs: relocation: constify parameters where possible David Sterba
2023-09-22 12:43   ` Johannes Thumshirn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).