Skip to contentSkip to conversation

btrfs: relocation: Cleanup while() loop using rbtree_postorder_for_each_entry_safe()

PATCH In review Qu Wenruo 4 participants 6 messages Sep 21, 2018 – Oct 12, 2018 Btrfs file system

lore
Share & tools
lore

Qu Wenruo

author
#0 lore raw

PATCH v2 1/2 btrfs: relocation: Cleanup while() loop using rbtree_postorder_for_each_entry_safe()

And add one line comment explaining what we're doing for each loop.

---
changelog:
v2:
Use rbtree_postorder_for_each_entry_safe() to replace for() loop.

---
 fs/btrfs/relocation.c | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)
fs/btrfs/relocation.c +9 -15
index 8783a1776540..94aa148ccde6 100644
@@ -2987,7 +2987,7 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
 	struct backref_node *node;
 	struct btrfs_path *path;
 	struct tree_block *block;
-	struct rb_node *rb_node;
+	struct tree_block *next;
 	int ret;
 	int err = 0;
 
@@ -2997,29 +2997,23 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
 		goto out_free_blocks;
 	}
 
-	rb_node = rb_first(blocks);
-	while (rb_node) {
-		block = rb_entry(rb_node, struct tree_block, rb_node);
+	/* Kick in readahead for tree blocks with missing keys */
+	rbtree_postorder_for_each_entry_safe(block, next, blocks, rb_node) {
 		if (!block->key_ready)
 			readahead_tree_block(fs_info, block->bytenr);
-		rb_node = rb_next(rb_node);
 	}
 
-	rb_node = rb_first(blocks);
-	while (rb_node) {
-		block = rb_entry(rb_node, struct tree_block, rb_node);
+	/* Get first keys */
+	rbtree_postorder_for_each_entry_safe(block, next, blocks, rb_node) {
 		if (!block->key_ready) {
 			err = get_tree_block_key(fs_info, block);
 			if (err)
 				goto out_free_path;
 		}
-		rb_node = rb_next(rb_node);
 	}
 
-	rb_node = rb_first(blocks);
-	while (rb_node) {
-		block = rb_entry(rb_node, struct tree_block, rb_node);
-
+	/* Do tree relocation */
+	rbtree_postorder_for_each_entry_safe(block, next, blocks, rb_node) {
 		node = build_backref_tree(rc, &block->key,
 					  block->level, block->bytenr);
 		if (IS_ERR(node)) {
@@ -3030,11 +3024,11 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
 		ret = relocate_tree_block(trans, rc, node, &block->key,
 					  path);
 		if (ret < 0) {
-			if (ret != -EAGAIN || rb_node == rb_first(blocks))
+			if (ret != -EAGAIN || &block->rb_node ==
+					      rb_first(blocks))
 				err = ret;
 			goto out;
 		}
-		rb_node = rb_next(rb_node);
 	}
 out:
 	err = finish_pending_nodes(trans, rc, path, err);
Signature · 1 line
2.19.0
author
#1 lore raw

PATCH v2 2/2 btrfs: relocation: Remove redundant tree level check

Commit 581c1760415c ("btrfs: Validate child tree block's level and first key") has made tree block level check mandatory.

So if tree block level doesn't match, we won't get a valid extent buffer.
The extra WARN_ON() check can be removed completely.

---
Changelog:
v2:
Added tags.

---
 fs/btrfs/relocation.c | 1 -
 1 file changed, 1 deletion(-)
fs/btrfs/relocation.c +0 -1
index 94aa148ccde6..a554e7861b6e 100644
@@ -2911,7 +2911,6 @@ static int get_tree_block_key(struct btrfs_fs_info *fs_info,
 		free_extent_buffer(eb);
 		return -EIO;
 	}
-	WARN_ON(btrfs_header_level(eb) != block->level);
 	if (block->level == 0)
 		btrfs_item_key_to_cpu(eb, &block->key, 0);
 	else
Signature · 1 line
2.19.0
#2 lore raw

Re: [PATCH v2 2/2] btrfs: relocation: Remove redundant tree level check

Quoted 7 lines · Qu Wenruo

Commit 581c1760415c ("btrfs: Validate child tree block's level and first key") has made tree block level check mandatory.

So if tree block level doesn't match, we won't get a valid extent buffer.
The extra WARN_ON() check can be removed completely.

Quoted 5 lines

---
Changelog:
v2:
Added tags.

Nope you didn't :)

Quoted 17 lines
---
 fs/btrfs/relocation.c | 1 -
 1 file changed, 1 deletion(-)
fs/btrfs/relocation.c +0 -1
index 94aa148ccde6..a554e7861b6e 100644
@@ -2911,7 +2911,6 @@ static int get_tree_block_key(struct btrfs_fs_info *fs_info,
 		free_extent_buffer(eb);
 		return -EIO;
 	}
-	WARN_ON(btrfs_header_level(eb) != block->level);
 	if (block->level == 0)
 		btrfs_item_key_to_cpu(eb, &block->key, 0);
 	else
#3 lore raw

Re: [PATCH v2 2/2] btrfs: relocation: Remove redundant tree level check

Quoted 10 lines · Nikolay Borisov
Quoted 7 lines · Qu Wenruo

Commit 581c1760415c ("btrfs: Validate child tree block's level and first key") has made tree block level check mandatory.

So if tree block level doesn't match, we won't get a valid extent buffer.
The extra WARN_ON() check can be removed completely.

Quoted 7 lines
Quoted 5 lines

---
Changelog:
v2:
Added tags.

Nope you didn't :)

Face palm, only added in formatted patch, and just re-formatted patch again.

Anyway, David could handle it.

Thanks,
Qu

Quoted 18 lines
Quoted 18 lines
---
 fs/btrfs/relocation.c | 1 -
 1 file changed, 1 deletion(-)
fs/btrfs/relocation.c +0 -1
index 94aa148ccde6..a554e7861b6e 100644
@@ -2911,7 +2911,6 @@ static int get_tree_block_key(struct btrfs_fs_info *fs_info,
 		free_extent_buffer(eb);
 		return -EIO;
 	}
-	WARN_ON(btrfs_header_level(eb) != block->level);
 	if (block->level == 0)
 		btrfs_item_key_to_cpu(eb, &block->key, 0);
 	else
Reviewed-by on v2 1/2
#4 lore raw
In reply to Qu Wenruo
Quoted 4 lines · Qu Wenruo

And add one line comment explaining what we're doing for each loop.

---

Quoted 71 lines

changelog:
v2:
Use rbtree_postorder_for_each_entry_safe() to replace for() loop.

---
 fs/btrfs/relocation.c | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)
fs/btrfs/relocation.c +9 -15
index 8783a1776540..94aa148ccde6 100644
@@ -2987,7 +2987,7 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
 	struct backref_node *node;
 	struct btrfs_path *path;
 	struct tree_block *block;
-	struct rb_node *rb_node;
+	struct tree_block *next;
 	int ret;
 	int err = 0;
 
@@ -2997,29 +2997,23 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
 		goto out_free_blocks;
 	}
 
-	rb_node = rb_first(blocks);
-	while (rb_node) {
-		block = rb_entry(rb_node, struct tree_block, rb_node);
+	/* Kick in readahead for tree blocks with missing keys */
+	rbtree_postorder_for_each_entry_safe(block, next, blocks, rb_node) {
 		if (!block->key_ready)
 			readahead_tree_block(fs_info, block->bytenr);
-		rb_node = rb_next(rb_node);
 	}
 
-	rb_node = rb_first(blocks);
-	while (rb_node) {
-		block = rb_entry(rb_node, struct tree_block, rb_node);
+	/* Get first keys */
+	rbtree_postorder_for_each_entry_safe(block, next, blocks, rb_node) {
 		if (!block->key_ready) {
 			err = get_tree_block_key(fs_info, block);
 			if (err)
 				goto out_free_path;
 		}
-		rb_node = rb_next(rb_node);
 	}
 
-	rb_node = rb_first(blocks);
-	while (rb_node) {
-		block = rb_entry(rb_node, struct tree_block, rb_node);
-
+	/* Do tree relocation */
+	rbtree_postorder_for_each_entry_safe(block, next, blocks, rb_node) {
 		node = build_backref_tree(rc, &block->key,
 					  block->level, block->bytenr);
 		if (IS_ERR(node)) {
@@ -3030,11 +3024,11 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
 		ret = relocate_tree_block(trans, rc, node, &block->key,
 					  path);
 		if (ret < 0) {
-			if (ret != -EAGAIN || rb_node == rb_first(blocks))
+			if (ret != -EAGAIN || &block->rb_node ==
+					      rb_first(blocks))
 				err = ret;
 			goto out;
 		}
-		rb_node = rb_next(rb_node);
 	}
 out:
 	err = finish_pending_nodes(trans, rc, path, err);