* [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots
@ 2022-03-09 13:50 Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 01/14] btrfs: Introduce btrfs_for_each_slot iterator macro Gabriel Niebler
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler
There is a common pattern when searching for a key in btrfs:
* Call btrfs_search_slot to find the slot for the key
* Enter an endless loop:
* If the found slot is larger than the no. of items in the current leaf,
check the next leaf
* If it's still not found in the next leaf, terminate the loop
* Otherwise do something with the found key
* Increment the current slot and continue
To reduce code duplication, we can replace this code pattern with an iterator
macro, similar to the existing for_each_X macros found elsewhere in the kernel.
This also makes the code easier to understand for newcomers by putting a name
to the encapsulated functionality.
This patchset survived a complete fstest run.
Changes from v3:
* Surround arguments with (…) in iterator macro definition (David)
* Fix btrfs_unlink_all_paths after key/found_key confusion broke btrfs/168
(Josef)
* Various stylistic improvements (David)
Changes from v2:
* Rename btrfs_valid_slot to btrfs_get_next_valid_item (Nikolay)
* Fix comment formatting (David)
* Remove redundant parentheses and indentation in loop condition (David)
* Remove redundant iter_ret var and reuse ret instead (Nikolay)
* Make termination condition more consistent in btrfs_unlink_all_paths
(Nikolay)
* Improved patch organisation by splitting into one patch per function (David)
* Improve doc comment for btrfs_get_next_valid_item (Gabriel)
* Remove `out` label and assoc. gotos from id_create_dir (Gabriel)
* Initialise `ret` in process_all_refs and process_all_new_xattrs (Gabriel)
* Remove unneeded btrfs_item_key_to_cpu call from loop body in
btrfs_read_chunk_tree (Gabriel)
Changes from v1:
* Separate xattr changes from the macro introducing code (Johannes)
Changes from RFC:
* Add documentation to btrfs_for_each_slot macro and btrfs_valid_slot function
(David)
* Add documentation about the ret variable used as a macro argument (David)
* Match function argument from prototype and implementation (David)
* Changed ({ }) block to only () in btrfs_for_each_slot macro (David)
* Add more patches to show the code being reduced by using this approach
(Nikolay)
Marcos Paulo de Souza (14):
btrfs: Introduce btrfs_for_each_slot iterator macro
btrfs: Use btrfs_for_each_slot in find_first_block_group
btrfs: Use btrfs_for_each_slot in mark_block_group_to_copy
btrfs: Use btrfs_for_each_slot in btrfs_search_dir_index_item
btrfs: Use btrfs_for_each_slot in btrfs_real_readdir
btrfs: Use btrfs_for_each_slot in did_create_dir
btrfs: Use btrfs_for_each_slot in can_rmdir
btrfs: Use btrfs_for_each_slot in is_ancestor
btrfs: Use btrfs_for_each_slot in process_all_refs
btrfs: Use btrfs_for_each_slot in process_all_new_xattrs
btrfs: Use btrfs_for_each_slot in process_all_extents
btrfs: Use btrfs_for_each_slot in btrfs_unlink_all_paths
btrfs: Use btrfs_for_each_slot in btrfs_read_chunk_tree
btrfs: Use btrfs_for_each_slot in btrfs_listxattr
fs/btrfs/block-group.c | 26 +-----
fs/btrfs/ctree.c | 35 ++++++++
fs/btrfs/ctree.h | 25 ++++++
fs/btrfs/dev-replace.c | 40 ++-------
fs/btrfs/dir-item.c | 31 ++-----
fs/btrfs/inode.c | 35 +++-----
fs/btrfs/send.c | 229 +++++++++++++------------------------------------
fs/btrfs/volumes.c | 25 ++----
fs/btrfs/xattr.c | 40 +++------
9 files changed, 167 insertions(+), 319 deletions(-)
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 01/14] btrfs: Introduce btrfs_for_each_slot iterator macro
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH V4 02/14] btrfs: Use btrfs_for_each_slot in find_first_block_group Gabriel Niebler
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
There is a common pattern when searching for a key in btrfs:
* Call btrfs_search_slot to find the slot for the key
* Enter an endless loop:
* If the found slot is larger than the no. of items in the current leaf,
check the next leaf
* If it's still not found in the next leaf, terminate the loop
* Otherwise do something with the found key
* Increment the current slot and continue
To reduce code duplication, we can replace this code pattern with an iterator
macro, similar to the existing for_each_X macros found elsewhere in the kernel.
This also makes the code easier to understand for newcomers by putting a name
to the encapsulated functionality.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/ctree.c | 35 +++++++++++++++++++++++++++++++++++
fs/btrfs/ctree.h | 25 +++++++++++++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index a7db3f6f1b7b..13f1011bf2b4 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2277,6 +2277,41 @@ int btrfs_search_backwards(struct btrfs_root *root, struct btrfs_key *key,
return ret;
}
+/*
+ * Search for a valid slot for the given path.
+ *
+ * @root: The root node of the tree.
+ * @key: Will contain a valid item if found.
+ * @path: The starting point to validate the slot.
+ *
+ * Return 0 if the item is valid, 1 if not found and < 0 if error.
+ */
+int btrfs_get_next_valid_item(struct btrfs_root *root, struct btrfs_key *key,
+ struct btrfs_path *path)
+{
+ while (1) {
+ int ret;
+ const int slot = path->slots[0];
+ const struct extent_buffer *leaf = path->nodes[0];
+
+ /* This is where we start walking through the path. */
+ if (slot >= btrfs_header_nritems(leaf)) {
+ /*
+ * If we've reached the last slot in this leaf we need
+ * to go to the next leaf and reset the path.
+ */
+ ret = btrfs_next_leaf(root, path);
+ if (ret)
+ return ret;
+ continue;
+ }
+ /* Store the found, valid item in @key. */
+ btrfs_item_key_to_cpu(leaf, key, slot);
+ break;
+ }
+ return 0;
+}
+
/*
* adjust the pointers going up the tree, starting at level
* making sure the right key of each node is points to 'key'.
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index ebb2d109e8bb..5bacfa69457c 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2986,6 +2986,31 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
int btrfs_search_backwards(struct btrfs_root *root, struct btrfs_key *key,
struct btrfs_path *path);
+int btrfs_get_next_valid_item(struct btrfs_root *root, struct btrfs_key *key,
+ struct btrfs_path *path);
+
+/*
+ * Search in @root for a given @key, and store the slot found in @found_key.
+ *
+ * @root: The root node of the tree.
+ * @key: The key we are looking for.
+ * @found_key: Will hold the found item.
+ * @path: Holds the current slot/leaf.
+ * @iter_ret: Contains the value returned from btrfs_search_slot or
+ * btrfs_get_next_valid_item, whichever was executed last.
+ *
+ * The iter_ret is an output variable that will contain the return value of
+ * btrfs_search_slot, if it encountered an error, or the value returned from
+ * btrfs_get_next_valid_item, otherwise. That return value can be 0, if a valid
+ * slot was found, 1 if there were no more leaves, and <0 if there was an error.
+ */
+#define btrfs_for_each_slot(root, key, found_key, path, iter_ret) \
+ for (iter_ret = btrfs_search_slot(NULL, (root), (key), (path), 0, 0); \
+ (iter_ret) >= 0 && \
+ (iter_ret = btrfs_get_next_valid_item((root), (found_key), (path))) == 0; \
+ (path)->slots[0]++ \
+ )
+
static inline int btrfs_next_old_item(struct btrfs_root *root,
struct btrfs_path *p, u64 time_seq)
{
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V4 02/14] btrfs: Use btrfs_for_each_slot in find_first_block_group
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 01/14] btrfs: Introduce btrfs_for_each_slot iterator macro Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 03/14] btrfs: Use btrfs_for_each_slot in mark_block_group_to_copy Gabriel Niebler
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/block-group.c | 26 ++------------------------
1 file changed, 2 insertions(+), 24 deletions(-)
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 8202ad6aa131..aafd7909d0f8 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -1686,35 +1686,13 @@ static int find_first_block_group(struct btrfs_fs_info *fs_info,
struct btrfs_root *root = btrfs_block_group_root(fs_info);
int ret;
struct btrfs_key found_key;
- struct extent_buffer *leaf;
- int slot;
-
- ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
- if (ret < 0)
- return ret;
-
- while (1) {
- slot = path->slots[0];
- leaf = path->nodes[0];
- if (slot >= btrfs_header_nritems(leaf)) {
- ret = btrfs_next_leaf(root, path);
- if (ret == 0)
- continue;
- if (ret < 0)
- goto out;
- break;
- }
- btrfs_item_key_to_cpu(leaf, &found_key, slot);
+ btrfs_for_each_slot(root, key, &found_key, path, ret) {
if (found_key.objectid >= key->objectid &&
found_key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) {
- ret = read_bg_from_eb(fs_info, &found_key, path);
- break;
+ return read_bg_from_eb(fs_info, &found_key, path);
}
-
- path->slots[0]++;
}
-out:
return ret;
}
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 03/14] btrfs: Use btrfs_for_each_slot in mark_block_group_to_copy
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 01/14] btrfs: Introduce btrfs_for_each_slot iterator macro Gabriel Niebler
2022-03-09 13:50 ` [PATCH V4 02/14] btrfs: Use btrfs_for_each_slot in find_first_block_group Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 04/14] btrfs: Use btrfs_for_each_slot in btrfs_search_dir_index_item Gabriel Niebler
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/dev-replace.c | 40 +++++++---------------------------------
1 file changed, 7 insertions(+), 33 deletions(-)
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index 62b9651ea662..3fb807dc5243 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -470,6 +470,7 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info,
struct btrfs_dev_extent *dev_extent = NULL;
struct btrfs_block_group *cache;
struct btrfs_trans_handle *trans;
+ int iter_ret = 0;
int ret = 0;
u64 chunk_offset;
@@ -520,29 +521,8 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info,
key.type = BTRFS_DEV_EXTENT_KEY;
key.offset = 0;
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0)
- goto free_path;
- if (ret > 0) {
- if (path->slots[0] >=
- btrfs_header_nritems(path->nodes[0])) {
- ret = btrfs_next_leaf(root, path);
- if (ret < 0)
- goto free_path;
- if (ret > 0) {
- ret = 0;
- goto free_path;
- }
- } else {
- ret = 0;
- }
- }
-
- while (1) {
+ btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
struct extent_buffer *leaf = path->nodes[0];
- int slot = path->slots[0];
-
- btrfs_item_key_to_cpu(leaf, &found_key, slot);
if (found_key.objectid != src_dev->devid)
break;
@@ -553,30 +533,24 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info,
if (found_key.offset < key.offset)
break;
- dev_extent = btrfs_item_ptr(leaf, slot, struct btrfs_dev_extent);
+ dev_extent = btrfs_item_ptr(leaf, path->slots[0],
+ struct btrfs_dev_extent);
chunk_offset = btrfs_dev_extent_chunk_offset(leaf, dev_extent);
cache = btrfs_lookup_block_group(fs_info, chunk_offset);
if (!cache)
- goto skip;
+ continue;
spin_lock(&cache->lock);
cache->to_copy = 1;
spin_unlock(&cache->lock);
btrfs_put_block_group(cache);
-
-skip:
- ret = btrfs_next_item(root, path);
- if (ret != 0) {
- if (ret > 0)
- ret = 0;
- break;
- }
}
+ if (iter_ret < 0)
+ ret = iter_ret;
-free_path:
btrfs_free_path(path);
unlock:
mutex_unlock(&fs_info->chunk_mutex);
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 04/14] btrfs: Use btrfs_for_each_slot in btrfs_search_dir_index_item
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (2 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 03/14] btrfs: Use btrfs_for_each_slot in mark_block_group_to_copy Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 05/14] btrfs: Use btrfs_for_each_slot in btrfs_real_readdir Gabriel Niebler
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/dir-item.c | 31 ++++++-------------------------
1 file changed, 6 insertions(+), 25 deletions(-)
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index 3b532bab0755..7f1e6c48910f 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -325,36 +325,15 @@ btrfs_search_dir_index_item(struct btrfs_root *root,
struct btrfs_path *path, u64 dirid,
const char *name, int name_len)
{
- struct extent_buffer *leaf;
struct btrfs_dir_item *di;
struct btrfs_key key;
- u32 nritems;
int ret;
key.objectid = dirid;
key.type = BTRFS_DIR_INDEX_KEY;
key.offset = 0;
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0)
- return ERR_PTR(ret);
-
- leaf = path->nodes[0];
- nritems = btrfs_header_nritems(leaf);
-
- while (1) {
- if (path->slots[0] >= nritems) {
- ret = btrfs_next_leaf(root, path);
- if (ret < 0)
- return ERR_PTR(ret);
- if (ret > 0)
- break;
- leaf = path->nodes[0];
- nritems = btrfs_header_nritems(leaf);
- continue;
- }
-
- btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
+ btrfs_for_each_slot(root, &key, &key, path, ret) {
if (key.objectid != dirid || key.type != BTRFS_DIR_INDEX_KEY)
break;
@@ -362,10 +341,12 @@ btrfs_search_dir_index_item(struct btrfs_root *root,
name, name_len);
if (di)
return di;
-
- path->slots[0]++;
}
- return NULL;
+ /* Fix return code if key was not found in next leaf. */
+ if (ret > 0)
+ ret = 0;
+
+ return ERR_PTR(ret);
}
struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans,
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 05/14] btrfs: Use btrfs_for_each_slot in btrfs_real_readdir
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (3 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 04/14] btrfs: Use btrfs_for_each_slot in btrfs_search_dir_index_item Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 06/14] btrfs: Use btrfs_for_each_slot in did_create_dir Gabriel Niebler
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/inode.c | 35 ++++++++++-------------------------
1 file changed, 10 insertions(+), 25 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 5bbea5ec31fc..ca0de91eeece 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5755,8 +5755,6 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
struct list_head ins_list;
struct list_head del_list;
int ret;
- struct extent_buffer *leaf;
- int slot;
char *name_ptr;
int name_len;
int entries = 0;
@@ -5783,35 +5781,20 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
key.offset = ctx->pos;
key.objectid = btrfs_ino(BTRFS_I(inode));
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0)
- goto err;
-
- while (1) {
+ btrfs_for_each_slot(root, &key, &found_key, path, ret) {
struct dir_entry *entry;
-
- leaf = path->nodes[0];
- slot = path->slots[0];
- if (slot >= btrfs_header_nritems(leaf)) {
- ret = btrfs_next_leaf(root, path);
- if (ret < 0)
- goto err;
- else if (ret > 0)
- break;
- continue;
- }
-
- btrfs_item_key_to_cpu(leaf, &found_key, slot);
+ struct extent_buffer *leaf = path->nodes[0];
if (found_key.objectid != key.objectid)
break;
if (found_key.type != BTRFS_DIR_INDEX_KEY)
break;
if (found_key.offset < ctx->pos)
- goto next;
+ continue;
if (btrfs_should_delete_dir_index(&del_list, found_key.offset))
- goto next;
- di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
+ continue;
+ di = btrfs_item_ptr(leaf, path->slots[0],
+ struct btrfs_dir_item);
name_len = btrfs_dir_name_len(leaf, di);
if ((total_len + sizeof(struct dir_entry) + name_len) >=
PAGE_SIZE) {
@@ -5838,9 +5821,11 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
entries++;
addr += sizeof(struct dir_entry) + name_len;
total_len += sizeof(struct dir_entry) + name_len;
-next:
- path->slots[0]++;
}
+ /* Catch error encountered while searching */
+ if (ret < 0)
+ goto err;
+
btrfs_release_path(path);
ret = btrfs_filldir(private->filldir_buf, entries, ctx);
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 06/14] btrfs: Use btrfs_for_each_slot in did_create_dir
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (4 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 05/14] btrfs: Use btrfs_for_each_slot in btrfs_real_readdir Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 07/14] btrfs: Use btrfs_for_each_slot in can_rmdir Gabriel Niebler
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/send.c | 40 +++++++++++-----------------------------
1 file changed, 11 insertions(+), 29 deletions(-)
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 201eb2628aea..417aed3ab592 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -2680,61 +2680,43 @@ static int send_create_inode(struct send_ctx *sctx, u64 ino)
static int did_create_dir(struct send_ctx *sctx, u64 dir)
{
int ret = 0;
+ int iter_ret = 0;
struct btrfs_path *path = NULL;
struct btrfs_key key;
struct btrfs_key found_key;
struct btrfs_key di_key;
- struct extent_buffer *eb;
struct btrfs_dir_item *di;
- int slot;
path = alloc_path_for_send();
- if (!path) {
- ret = -ENOMEM;
- goto out;
- }
+ if (!path)
+ return -ENOMEM;
key.objectid = dir;
key.type = BTRFS_DIR_INDEX_KEY;
key.offset = 0;
- ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0);
- if (ret < 0)
- goto out;
- while (1) {
- eb = path->nodes[0];
- slot = path->slots[0];
- if (slot >= btrfs_header_nritems(eb)) {
- ret = btrfs_next_leaf(sctx->send_root, path);
- if (ret < 0) {
- goto out;
- } else if (ret > 0) {
- ret = 0;
- break;
- }
- continue;
- }
+ btrfs_for_each_slot(sctx->send_root, &key, &found_key, path, iter_ret) {
+ struct extent_buffer *eb = path->nodes[0];
- btrfs_item_key_to_cpu(eb, &found_key, slot);
if (found_key.objectid != key.objectid ||
found_key.type != key.type) {
ret = 0;
- goto out;
+ break;
}
- di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item);
+ di = btrfs_item_ptr(eb, path->slots[0], struct btrfs_dir_item);
btrfs_dir_item_key_to_cpu(eb, di, &di_key);
if (di_key.type != BTRFS_ROOT_ITEM_KEY &&
di_key.objectid < sctx->send_progress) {
ret = 1;
- goto out;
+ break;
}
-
- path->slots[0]++;
}
+ /* Catch error found on iteration */
+ if (iter_ret < 0)
+ ret = iter_ret;
-out:
btrfs_free_path(path);
return ret;
}
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 07/14] btrfs: Use btrfs_for_each_slot in can_rmdir
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (5 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 06/14] btrfs: Use btrfs_for_each_slot in did_create_dir Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 08/14] btrfs: Use btrfs_for_each_slot in is_ancestor Gabriel Niebler
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/send.c | 23 ++++++-----------------
1 file changed, 6 insertions(+), 17 deletions(-)
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 417aed3ab592..5ecb8e39f449 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -2920,6 +2920,7 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen,
u64 send_progress)
{
int ret = 0;
+ int iter_ret = 0;
struct btrfs_root *root = sctx->parent_root;
struct btrfs_path *path;
struct btrfs_key key;
@@ -2946,23 +2947,9 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen,
if (odi)
key.offset = odi->last_dir_index_offset;
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0)
- goto out;
-
- while (1) {
+ btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
struct waiting_dir_move *dm;
- if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
- ret = btrfs_next_leaf(root, path);
- if (ret < 0)
- goto out;
- else if (ret > 0)
- break;
- continue;
- }
- btrfs_item_key_to_cpu(path->nodes[0], &found_key,
- path->slots[0]);
if (found_key.objectid != key.objectid ||
found_key.type != key.type)
break;
@@ -2997,8 +2984,10 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen,
ret = 0;
goto out;
}
-
- path->slots[0]++;
+ }
+ if (iter_ret < 0) {
+ ret = iter_ret;
+ goto out;
}
free_orphan_dir_info(sctx, odi);
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 08/14] btrfs: Use btrfs_for_each_slot in is_ancestor
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (6 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 07/14] btrfs: Use btrfs_for_each_slot in can_rmdir Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 09/14] btrfs: Use btrfs_for_each_slot in process_all_refs Gabriel Niebler
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/send.c | 25 +++++++------------------
1 file changed, 7 insertions(+), 18 deletions(-)
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 5ecb8e39f449..cad9b36ebdf8 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -3555,7 +3555,7 @@ static int check_ino_in_path(struct btrfs_root *root,
}
/*
- * Check if ino ino1 is an ancestor of inode ino2 in the given root for any
+ * Check if inode ino1 is an ancestor of inode ino2 in the given root for any
* possible path (in case ino2 is not a directory and has multiple hard links).
* Return 1 if true, 0 if false and < 0 on error.
*/
@@ -3567,6 +3567,7 @@ static int is_ancestor(struct btrfs_root *root,
{
bool free_fs_path = false;
int ret = 0;
+ int iter_ret = 0;
struct btrfs_path *path = NULL;
struct btrfs_key key;
@@ -3587,26 +3588,12 @@ static int is_ancestor(struct btrfs_root *root,
key.type = BTRFS_INODE_REF_KEY;
key.offset = 0;
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0)
- goto out;
-
- while (true) {
+ btrfs_for_each_slot(root, &key, &key, path, iter_ret) {
struct extent_buffer *leaf = path->nodes[0];
int slot = path->slots[0];
u32 cur_offset = 0;
u32 item_size;
- if (slot >= btrfs_header_nritems(leaf)) {
- ret = btrfs_next_leaf(root, path);
- if (ret < 0)
- goto out;
- if (ret > 0)
- break;
- continue;
- }
-
- btrfs_item_key_to_cpu(leaf, &key, slot);
if (key.objectid != ino2)
break;
if (key.type != BTRFS_INODE_REF_KEY &&
@@ -3644,10 +3631,12 @@ static int is_ancestor(struct btrfs_root *root,
if (ret)
goto out;
}
- path->slots[0]++;
}
ret = 0;
- out:
+ if (iter_ret < 0)
+ ret = iter_ret;
+
+out:
btrfs_free_path(path);
if (free_fs_path)
fs_path_free(fs_path);
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 09/14] btrfs: Use btrfs_for_each_slot in process_all_refs
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (7 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 08/14] btrfs: Use btrfs_for_each_slot in is_ancestor Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 10/14] btrfs: Use btrfs_for_each_slot in process_all_new_xattrs Gabriel Niebler
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/send.c | 33 +++++++++------------------------
1 file changed, 9 insertions(+), 24 deletions(-)
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index cad9b36ebdf8..2e35edd8d08e 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4516,13 +4516,12 @@ static int record_changed_ref(struct send_ctx *sctx)
static int process_all_refs(struct send_ctx *sctx,
enum btrfs_compare_tree_result cmd)
{
- int ret;
+ int ret = 0;
+ int iter_ret = 0;
struct btrfs_root *root;
struct btrfs_path *path;
struct btrfs_key key;
struct btrfs_key found_key;
- struct extent_buffer *eb;
- int slot;
iterate_inode_ref_t cb;
int pending_move = 0;
@@ -4538,7 +4537,7 @@ static int process_all_refs(struct send_ctx *sctx,
cb = __record_deleted_ref;
} else {
btrfs_err(sctx->send_root->fs_info,
- "Wrong command %d in process_all_refs", cmd);
+ "Wrong command %d in process_all_refs", cmd);
ret = -EINVAL;
goto out;
}
@@ -4546,24 +4545,7 @@ static int process_all_refs(struct send_ctx *sctx,
key.objectid = sctx->cmp_key->objectid;
key.type = BTRFS_INODE_REF_KEY;
key.offset = 0;
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0)
- goto out;
-
- while (1) {
- eb = path->nodes[0];
- slot = path->slots[0];
- if (slot >= btrfs_header_nritems(eb)) {
- ret = btrfs_next_leaf(root, path);
- if (ret < 0)
- goto out;
- else if (ret > 0)
- break;
- continue;
- }
-
- btrfs_item_key_to_cpu(eb, &found_key, slot);
-
+ btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
if (found_key.objectid != key.objectid ||
(found_key.type != BTRFS_INODE_REF_KEY &&
found_key.type != BTRFS_INODE_EXTREF_KEY))
@@ -4572,8 +4554,11 @@ static int process_all_refs(struct send_ctx *sctx,
ret = iterate_inode_ref(root, path, &found_key, 0, cb, sctx);
if (ret < 0)
goto out;
-
- path->slots[0]++;
+ }
+ /* Catch error found on iteration */
+ if (iter_ret < 0) {
+ ret = iter_ret;
+ goto out;
}
btrfs_release_path(path);
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 10/14] btrfs: Use btrfs_for_each_slot in process_all_new_xattrs
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (8 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 09/14] btrfs: Use btrfs_for_each_slot in process_all_refs Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 11/14] btrfs: Use btrfs_for_each_slot in process_all_extents Gabriel Niebler
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/send.c | 35 ++++++++---------------------------
1 file changed, 8 insertions(+), 27 deletions(-)
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 2e35edd8d08e..14c343cdf76c 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4820,13 +4820,12 @@ static int process_changed_xattr(struct send_ctx *sctx)
static int process_all_new_xattrs(struct send_ctx *sctx)
{
- int ret;
+ int ret = 0;
+ int iter_ret = 0;
struct btrfs_root *root;
struct btrfs_path *path;
struct btrfs_key key;
struct btrfs_key found_key;
- struct extent_buffer *eb;
- int slot;
path = alloc_path_for_send();
if (!path)
@@ -4837,39 +4836,21 @@ static int process_all_new_xattrs(struct send_ctx *sctx)
key.objectid = sctx->cmp_key->objectid;
key.type = BTRFS_XATTR_ITEM_KEY;
key.offset = 0;
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0)
- goto out;
-
- while (1) {
- eb = path->nodes[0];
- slot = path->slots[0];
- if (slot >= btrfs_header_nritems(eb)) {
- ret = btrfs_next_leaf(root, path);
- if (ret < 0) {
- goto out;
- } else if (ret > 0) {
- ret = 0;
- break;
- }
- continue;
- }
-
- btrfs_item_key_to_cpu(eb, &found_key, slot);
+ btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
if (found_key.objectid != key.objectid ||
found_key.type != key.type) {
ret = 0;
- goto out;
+ break;
}
ret = iterate_dir_item(root, path, __process_new_xattr, sctx);
if (ret < 0)
- goto out;
-
- path->slots[0]++;
+ break;
}
+ /* Catch error found on iteration */
+ if (iter_ret < 0)
+ ret = iter_ret;
-out:
btrfs_free_path(path);
return ret;
}
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 11/14] btrfs: Use btrfs_for_each_slot in process_all_extents
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (9 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 10/14] btrfs: Use btrfs_for_each_slot in process_all_new_xattrs Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 12/14] btrfs: Use btrfs_for_each_slot in btrfs_unlink_all_paths Gabriel Niebler
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/send.c | 37 ++++++++-----------------------------
1 file changed, 8 insertions(+), 29 deletions(-)
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 14c343cdf76c..573ea102f8ab 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -5896,13 +5896,12 @@ static int process_extent(struct send_ctx *sctx,
static int process_all_extents(struct send_ctx *sctx)
{
- int ret;
+ int ret = 0;
+ int iter_ret = 0;
struct btrfs_root *root;
struct btrfs_path *path;
struct btrfs_key key;
struct btrfs_key found_key;
- struct extent_buffer *eb;
- int slot;
root = sctx->send_root;
path = alloc_path_for_send();
@@ -5912,41 +5911,21 @@ static int process_all_extents(struct send_ctx *sctx)
key.objectid = sctx->cmp_key->objectid;
key.type = BTRFS_EXTENT_DATA_KEY;
key.offset = 0;
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0)
- goto out;
-
- while (1) {
- eb = path->nodes[0];
- slot = path->slots[0];
-
- if (slot >= btrfs_header_nritems(eb)) {
- ret = btrfs_next_leaf(root, path);
- if (ret < 0) {
- goto out;
- } else if (ret > 0) {
- ret = 0;
- break;
- }
- continue;
- }
-
- btrfs_item_key_to_cpu(eb, &found_key, slot);
-
+ btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
if (found_key.objectid != key.objectid ||
found_key.type != key.type) {
ret = 0;
- goto out;
+ break;
}
ret = process_extent(sctx, path, &found_key);
if (ret < 0)
- goto out;
-
- path->slots[0]++;
+ break;
}
+ /* Catch error found on iteration */
+ if (iter_ret < 0)
+ ret = iter_ret;
-out:
btrfs_free_path(path);
return ret;
}
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 12/14] btrfs: Use btrfs_for_each_slot in btrfs_unlink_all_paths
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (10 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 11/14] btrfs: Use btrfs_for_each_slot in process_all_extents Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 13/14] btrfs: Use btrfs_for_each_slot in btrfs_read_chunk_tree Gabriel Niebler
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/send.c | 36 +++++++++++++-----------------------
1 file changed, 13 insertions(+), 23 deletions(-)
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 573ea102f8ab..b339f919bb75 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -6115,8 +6115,11 @@ static int btrfs_unlink_all_paths(struct send_ctx *sctx)
{
LIST_HEAD(deleted_refs);
struct btrfs_path *path;
+ struct btrfs_root *root = sctx->parent_root;
struct btrfs_key key;
+ struct btrfs_key found_key;
struct parent_paths_ctx ctx;
+ int iter_ret = 0;
int ret;
path = alloc_path_for_send();
@@ -6126,39 +6129,26 @@ static int btrfs_unlink_all_paths(struct send_ctx *sctx)
key.objectid = sctx->cur_ino;
key.type = BTRFS_INODE_REF_KEY;
key.offset = 0;
- ret = btrfs_search_slot(NULL, sctx->parent_root, &key, path, 0, 0);
- if (ret < 0)
- goto out;
ctx.refs = &deleted_refs;
ctx.sctx = sctx;
- while (true) {
- struct extent_buffer *eb = path->nodes[0];
- int slot = path->slots[0];
-
- if (slot >= btrfs_header_nritems(eb)) {
- ret = btrfs_next_leaf(sctx->parent_root, path);
- if (ret < 0)
- goto out;
- else if (ret > 0)
- break;
- continue;
- }
-
- btrfs_item_key_to_cpu(eb, &key, slot);
- if (key.objectid != sctx->cur_ino)
+ btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
+ if (found_key.objectid != key.objectid)
break;
- if (key.type != BTRFS_INODE_REF_KEY &&
- key.type != BTRFS_INODE_EXTREF_KEY)
+ if (found_key.type != key.type &&
+ found_key.type != BTRFS_INODE_EXTREF_KEY)
break;
- ret = iterate_inode_ref(sctx->parent_root, path, &key, 1,
+ ret = iterate_inode_ref(root, path, &found_key, 1,
record_parent_ref, &ctx);
if (ret < 0)
goto out;
-
- path->slots[0]++;
+ }
+ /* Catch error found on iteration */
+ if (iter_ret < 0) {
+ ret = iter_ret;
+ goto out;
}
while (!list_empty(&deleted_refs)) {
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 13/14] btrfs: Use btrfs_for_each_slot in btrfs_read_chunk_tree
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (11 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 12/14] btrfs: Use btrfs_for_each_slot in btrfs_unlink_all_paths Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 14/14] btrfs: Use btrfs_for_each_slot in btrfs_listxattr Gabriel Niebler
2022-03-14 19:35 ` [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots David Sterba
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/volumes.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index b07d382d53a8..3185ececc672 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -7575,6 +7575,7 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
struct btrfs_key found_key;
int ret;
int slot;
+ int iter_ret = 0;
u64 total_dev = 0;
u64 last_ra_node = 0;
@@ -7618,30 +7619,18 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
key.offset = 0;
key.type = 0;
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0)
- goto error;
- while (1) {
- struct extent_buffer *node;
+ btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
+ struct extent_buffer *node = path->nodes[1];
leaf = path->nodes[0];
slot = path->slots[0];
- if (slot >= btrfs_header_nritems(leaf)) {
- ret = btrfs_next_leaf(root, path);
- if (ret == 0)
- continue;
- if (ret < 0)
- goto error;
- break;
- }
- node = path->nodes[1];
+
if (node) {
if (last_ra_node != node->start) {
readahead_tree_node_children(node);
last_ra_node = node->start;
}
}
- btrfs_item_key_to_cpu(leaf, &found_key, slot);
if (found_key.type == BTRFS_DEV_ITEM_KEY) {
struct btrfs_dev_item *dev_item;
dev_item = btrfs_item_ptr(leaf, slot,
@@ -7666,7 +7655,11 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
if (ret)
goto error;
}
- path->slots[0]++;
+ }
+ /* Catch error found on iteration */
+ if (iter_ret < 0) {
+ ret = iter_ret;
+ goto error;
}
/*
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 14/14] btrfs: Use btrfs_for_each_slot in btrfs_listxattr
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (12 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 13/14] btrfs: Use btrfs_for_each_slot in btrfs_read_chunk_tree Gabriel Niebler
@ 2022-03-09 13:50 ` Gabriel Niebler
2022-03-14 19:35 ` [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots David Sterba
14 siblings, 0 replies; 16+ messages in thread
From: Gabriel Niebler @ 2022-03-09 13:50 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, Gabriel Niebler, Marcos Paulo de Souza
This function can be simplified by refactoring to use the new iterator macro.
No functional changes.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Signed-off-by: Gabriel Niebler <gniebler@suse.com>
---
fs/btrfs/xattr.c | 40 +++++++++++-----------------------------
1 file changed, 11 insertions(+), 29 deletions(-)
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 99abf41b89b9..b96ffd775b41 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -271,10 +271,12 @@ int btrfs_setxattr_trans(struct inode *inode, const char *name,
ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
+ struct btrfs_key found_key;
struct btrfs_key key;
struct inode *inode = d_inode(dentry);
struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_path *path;
+ int iter_ret = 0;
int ret = 0;
size_t total_size = 0, size_left = size;
@@ -293,44 +295,23 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
path->reada = READA_FORWARD;
/* search for our xattrs */
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0)
- goto err;
-
- while (1) {
+ btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
struct extent_buffer *leaf;
int slot;
struct btrfs_dir_item *di;
- struct btrfs_key found_key;
u32 item_size;
u32 cur;
leaf = path->nodes[0];
slot = path->slots[0];
- /* this is where we start walking through the path */
- if (slot >= btrfs_header_nritems(leaf)) {
- /*
- * if we've reached the last slot in this leaf we need
- * to go to the next leaf and reset everything
- */
- ret = btrfs_next_leaf(root, path);
- if (ret < 0)
- goto err;
- else if (ret > 0)
- break;
- continue;
- }
-
- btrfs_item_key_to_cpu(leaf, &found_key, slot);
-
/* check to make sure this item is what we want */
if (found_key.objectid != key.objectid)
break;
if (found_key.type > BTRFS_XATTR_ITEM_KEY)
break;
if (found_key.type < BTRFS_XATTR_ITEM_KEY)
- goto next_item;
+ continue;
di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
item_size = btrfs_item_size(leaf, slot);
@@ -350,8 +331,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
goto next;
if (!buffer || (name_len + 1) > size_left) {
- ret = -ERANGE;
- goto err;
+ iter_ret = -ERANGE;
+ break;
}
read_extent_buffer(leaf, buffer, name_ptr, name_len);
@@ -363,12 +344,13 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
cur += this_len;
di = (struct btrfs_dir_item *)((char *)di + this_len);
}
-next_item:
- path->slots[0]++;
}
- ret = total_size;
-err:
+ if (iter_ret < 0)
+ ret = iter_ret;
+ else
+ ret = total_size;
+
btrfs_free_path(path);
return ret;
--
2.35.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
` (13 preceding siblings ...)
2022-03-09 13:50 ` [PATCH v4 14/14] btrfs: Use btrfs_for_each_slot in btrfs_listxattr Gabriel Niebler
@ 2022-03-14 19:35 ` David Sterba
14 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2022-03-14 19:35 UTC (permalink / raw)
To: Gabriel Niebler; +Cc: linux-btrfs, dsterba
On Wed, Mar 09, 2022 at 02:50:37PM +0100, Gabriel Niebler wrote:
> There is a common pattern when searching for a key in btrfs:
>
> * Call btrfs_search_slot to find the slot for the key
> * Enter an endless loop:
> * If the found slot is larger than the no. of items in the current leaf,
> check the next leaf
> * If it's still not found in the next leaf, terminate the loop
> * Otherwise do something with the found key
> * Increment the current slot and continue
>
> To reduce code duplication, we can replace this code pattern with an iterator
> macro, similar to the existing for_each_X macros found elsewhere in the kernel.
> This also makes the code easier to understand for newcomers by putting a name
> to the encapsulated functionality.
>
> This patchset survived a complete fstest run.
>
> Changes from v3:
> * Surround arguments with (…) in iterator macro definition (David)
> * Fix btrfs_unlink_all_paths after key/found_key confusion broke btrfs/168
> (Josef)
> * Various stylistic improvements (David)
Added to misc-next with some fixups, thanks.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2022-03-14 19:39 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-09 13:50 [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 01/14] btrfs: Introduce btrfs_for_each_slot iterator macro Gabriel Niebler
2022-03-09 13:50 ` [PATCH V4 02/14] btrfs: Use btrfs_for_each_slot in find_first_block_group Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 03/14] btrfs: Use btrfs_for_each_slot in mark_block_group_to_copy Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 04/14] btrfs: Use btrfs_for_each_slot in btrfs_search_dir_index_item Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 05/14] btrfs: Use btrfs_for_each_slot in btrfs_real_readdir Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 06/14] btrfs: Use btrfs_for_each_slot in did_create_dir Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 07/14] btrfs: Use btrfs_for_each_slot in can_rmdir Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 08/14] btrfs: Use btrfs_for_each_slot in is_ancestor Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 09/14] btrfs: Use btrfs_for_each_slot in process_all_refs Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 10/14] btrfs: Use btrfs_for_each_slot in process_all_new_xattrs Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 11/14] btrfs: Use btrfs_for_each_slot in process_all_extents Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 12/14] btrfs: Use btrfs_for_each_slot in btrfs_unlink_all_paths Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 13/14] btrfs: Use btrfs_for_each_slot in btrfs_read_chunk_tree Gabriel Niebler
2022-03-09 13:50 ` [PATCH v4 14/14] btrfs: Use btrfs_for_each_slot in btrfs_listxattr Gabriel Niebler
2022-03-14 19:35 ` [PATCH v4 0/14] btrfs: Introduce macro to iterate over slots David Sterba
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox