* [PATCH 0/3] btrfs: remove unused return_any parameter from btrfs_search_slot_for_read()
@ 2026-02-08 3:19 Sun YangKai
2026-02-08 3:19 ` [PATCH 1/3] btrfs: qgroup: drop pointless return_any fallback when reading qgroup config Sun YangKai
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Sun YangKai @ 2026-02-08 3:19 UTC (permalink / raw)
To: linux-btrfs; +Cc: Sun YangKai
The return_any parameter in btrfs_search_slot_for_read() was designed
to allow falling back to the opposite search direction when no item
is found in the requested direction. However, analysis shows that:
- The vast majority of callers pass return_any=0, meaning the fallback
logic is effectively dead code for the common case.
- The few callers that did pass return_any=1 were doing so unnecessarily
- get_last_extent() in send.c: There is always a previous item (at
minimum the inode_item) before an extent data item, making the fallback
impossible to trigger.
- btrfs_read_qgroup_config() in qgroup.c: When searching from the
zeroed key (0,0,0) with find_higher=1, there cannot possibly be a
lower key to fall back to, making return_any=1 logically nonsensical.
This series removes these unnecessary return_any=1 usages (patches 1-2),
then removes the now-unused parameter and associated dead code from
btrfs_search_slot_for_read() (patch 3).
The final result is a significantly simplified interface and implementation,
with no functional change for any existing code path.
Patch 1: Drop pointless return_any fallback in qgroup config reading
Patch 2: Drop unnecessary return_any search in send's get_last_extent()
Patch 3: Remove return_any parameter and simplify implementation
Sun YangKai (3):
btrfs: qgroup: drop pointless return_any fallback when reading qgroup
config
btrfs: send: drop unnecessary return_any search in get_last_extent()
btrfs: simplify btrfs_search_slot_for_read() by removing return_any
parameter
fs/btrfs/ctree.c | 48 +++++++-------------------------------
fs/btrfs/ctree.h | 3 +--
fs/btrfs/free-space-tree.c | 2 +-
fs/btrfs/qgroup.c | 10 ++++----
fs/btrfs/send.c | 22 ++++++++---------
5 files changed, 25 insertions(+), 60 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] btrfs: qgroup: drop pointless return_any fallback when reading qgroup config
2026-02-08 3:19 [PATCH 0/3] btrfs: remove unused return_any parameter from btrfs_search_slot_for_read() Sun YangKai
@ 2026-02-08 3:19 ` Sun YangKai
2026-02-08 3:38 ` [PATCH 2/3] btrfs: send: drop unnecessary return_any search in get_last_extent() Sun YangKai
2026-02-08 3:40 ` [PATCH 3/3] btrfs: simplify btrfs_search_slot_for_read() by removing return_any parameter Sun YangKai
2 siblings, 0 replies; 4+ messages in thread
From: Sun YangKai @ 2026-02-08 3:19 UTC (permalink / raw)
To: linux-btrfs; +Cc: Sun YangKai
btrfs_read_qgroup_config() initializes iteration over the quota root by
searching for the first item using a zeroed key (0, 0, 0).
The search is done with find_higher=1, meaning it looks for the first key
strictly greater than (0, 0, 0). However, the call also sets return_any=1,
which allows falling back to a lower key if no higher one is found.
Since (0, 0, 0) is the absolute minimum in the btrfs key space, there can
be no valid lower key. The return_any fallback is therefore impossible to
trigger and misleading in this context.
Set return_any to 0 to correctly express the intent: find the first item
greater than (0, 0, 0), or return not found if the quota root is empty.
Signed-off-by: Sun YangKai <sunk67188@gmail.com>
---
fs/btrfs/qgroup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 206587820fec..b8040740f7ca 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -415,7 +415,7 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
key.objectid = 0;
key.type = 0;
key.offset = 0;
- ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 1);
+ ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 0);
if (ret)
goto out;
--
2.52.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] btrfs: send: drop unnecessary return_any search in get_last_extent()
2026-02-08 3:19 [PATCH 0/3] btrfs: remove unused return_any parameter from btrfs_search_slot_for_read() Sun YangKai
2026-02-08 3:19 ` [PATCH 1/3] btrfs: qgroup: drop pointless return_any fallback when reading qgroup config Sun YangKai
@ 2026-02-08 3:38 ` Sun YangKai
2026-02-08 3:40 ` [PATCH 3/3] btrfs: simplify btrfs_search_slot_for_read() by removing return_any parameter Sun YangKai
2 siblings, 0 replies; 4+ messages in thread
From: Sun YangKai @ 2026-02-08 3:38 UTC (permalink / raw)
To: linux-btrfs; +Cc: Sun YangKai
There must always be a previous item before an extent data item, at
least the inode_item. Because of this, setting @return_any in
btrfs_search_slot_for_read() is unnecessary.
Signed-off-by: Sun YangKai <sunk67188@gmail.com>
---
fs/btrfs/send.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index d8127a7120c2..5b551f811bf6 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -6320,7 +6320,7 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset)
key.objectid = sctx->cur_ino;
key.type = BTRFS_EXTENT_DATA_KEY;
key.offset = offset;
- ret = btrfs_search_slot_for_read(root, &key, path, 0, 1);
+ ret = btrfs_search_slot_for_read(root, &key, path, 0, 0);
if (ret < 0)
return ret;
ret = 0;
--
2.52.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] btrfs: simplify btrfs_search_slot_for_read() by removing return_any parameter
2026-02-08 3:19 [PATCH 0/3] btrfs: remove unused return_any parameter from btrfs_search_slot_for_read() Sun YangKai
2026-02-08 3:19 ` [PATCH 1/3] btrfs: qgroup: drop pointless return_any fallback when reading qgroup config Sun YangKai
2026-02-08 3:38 ` [PATCH 2/3] btrfs: send: drop unnecessary return_any search in get_last_extent() Sun YangKai
@ 2026-02-08 3:40 ` Sun YangKai
2 siblings, 0 replies; 4+ messages in thread
From: Sun YangKai @ 2026-02-08 3:40 UTC (permalink / raw)
To: linux-btrfs; +Cc: Sun YangKai
The return_any parameter in btrfs_search_slot_for_read() was intended to
allow falling back to the opposite direction when no item is found in
the requested direction. However, all existing callers pass return_any=0,
meaning this fallback logic is never used.
Remove the unused return_any parameter and the associated fallback code
paths. This simplifies the function interface and implementation
significantly:
- Change find_higher from int to bool for type safety
- Remove the "again" loop and recursive search logic
- Add ASSERT(p->lowest_level == 0) to document the precondition
- Update all callers to use the new signature
The behavior remains unchanged for all existing callers since they all
used return_any=false.
Signed-off-by: Sun YangKai <sunk67188@gmail.com>
---
fs/btrfs/ctree.c | 48 +++++++-------------------------------
fs/btrfs/ctree.h | 3 +--
fs/btrfs/free-space-tree.c | 2 +-
fs/btrfs/qgroup.c | 10 ++++----
fs/btrfs/send.c | 12 +++++-----
5 files changed, 21 insertions(+), 54 deletions(-)
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index a48b4befbee7..0a0157db0b0c 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2450,22 +2450,15 @@ static int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
* instead the next or previous item should be returned.
* When find_higher is true, the next higher item is returned, the next lower
* otherwise.
- * When return_any and find_higher are both true, and no higher item is found,
- * return the next lower instead.
- * When return_any is true and find_higher is false, and no lower item is found,
- * return the next higher instead.
- * It returns 0 if any item is found, 1 if none is found (tree empty), and
- * < 0 on error
+ * It returns 0 if any item is found, 1 if none is found and < 0 on error
*/
int btrfs_search_slot_for_read(struct btrfs_root *root,
const struct btrfs_key *key,
- struct btrfs_path *p, int find_higher,
- int return_any)
+ struct btrfs_path *p, bool find_higher)
{
int ret;
- struct extent_buffer *leaf;
-again:
+ ASSERT(p->lowest_level == 0);
ret = btrfs_search_slot(NULL, root, key, p, 0, 0);
if (ret <= 0)
return ret;
@@ -2476,47 +2469,22 @@ int btrfs_search_slot_for_read(struct btrfs_root *root,
* to the first free slot in the previous leaf, i.e. at an invalid
* item.
*/
- leaf = p->nodes[0];
-
if (find_higher) {
- if (p->slots[0] >= btrfs_header_nritems(leaf)) {
- ret = btrfs_next_leaf(root, p);
- if (ret <= 0)
- return ret;
- if (!return_any)
- return 1;
- /*
- * no higher item found, return the next
- * lower instead
- */
- return_any = 0;
- find_higher = 0;
- btrfs_release_path(p);
- goto again;
- }
+ if (p->slots[0] >= btrfs_header_nritems(p->nodes[0]))
+ return btrfs_next_leaf(root, p);
} else {
if (p->slots[0] == 0) {
ret = btrfs_prev_leaf(root, p);
if (ret < 0)
return ret;
if (!ret) {
- leaf = p->nodes[0];
- if (p->slots[0] == btrfs_header_nritems(leaf))
+ if (p->slots[0] == btrfs_header_nritems(p->nodes[0]))
p->slots[0]--;
return 0;
}
- if (!return_any)
- return 1;
- /*
- * no lower item found, return the next
- * higher instead
- */
- return_any = 0;
- find_higher = 1;
- btrfs_release_path(p);
- goto again;
+ return 1;
} else {
- --p->slots[0];
+ p->slots[0]--;
}
}
return 0;
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 692370fc07b2..4b7b8ce7e211 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -595,8 +595,7 @@ int btrfs_search_old_slot(struct btrfs_root *root, const struct btrfs_key *key,
struct btrfs_path *p, u64 time_seq);
int btrfs_search_slot_for_read(struct btrfs_root *root,
const struct btrfs_key *key,
- struct btrfs_path *p, int find_higher,
- int return_any);
+ struct btrfs_path *p, bool find_higher);
void btrfs_release_path(struct btrfs_path *p);
struct btrfs_path *btrfs_alloc_path(void);
void btrfs_free_path(struct btrfs_path *p);
diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
index 1ad2ad384b9e..88c46950f5d2 100644
--- a/fs/btrfs/free-space-tree.c
+++ b/fs/btrfs/free-space-tree.c
@@ -1089,7 +1089,7 @@ static int populate_free_space_tree(struct btrfs_trans_handle *trans,
key.offset = 0;
extent_root = btrfs_extent_root(trans->fs_info, key.objectid);
- ret = btrfs_search_slot_for_read(extent_root, &key, path, 1, 0);
+ ret = btrfs_search_slot_for_read(extent_root, &key, path, true);
if (ret < 0)
goto out_locked;
/*
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index b8040740f7ca..0d84e456a41c 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -415,7 +415,7 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
key.objectid = 0;
key.type = 0;
key.offset = 0;
- ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 0);
+ ret = btrfs_search_slot_for_read(quota_root, &key, path, true);
if (ret)
goto out;
@@ -530,7 +530,7 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
key.objectid = 0;
key.type = BTRFS_QGROUP_RELATION_KEY;
key.offset = 0;
- ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 0);
+ ret = btrfs_search_slot_for_read(quota_root, &key, path, true);
if (ret)
goto out;
while (1) {
@@ -1088,7 +1088,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info,
key.offset = 0;
btrfs_release_path(path);
- ret = btrfs_search_slot_for_read(tree_root, &key, path, 1, 0);
+ ret = btrfs_search_slot_for_read(tree_root, &key, path, true);
if (ret > 0)
goto out_add_root;
if (unlikely(ret < 0)) {
@@ -1130,7 +1130,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info,
goto out_free_path;
}
ret = btrfs_search_slot_for_read(tree_root, &found_key,
- path, 1, 0);
+ path, true);
if (unlikely(ret < 0)) {
btrfs_abort_transaction(trans, ret);
goto out_free_path;
@@ -3690,7 +3690,7 @@ static int qgroup_rescan_leaf(struct btrfs_trans_handle *trans,
fs_info->qgroup_rescan_progress.objectid);
ret = btrfs_search_slot_for_read(extent_root,
&fs_info->qgroup_rescan_progress,
- path, 1, 0);
+ path, true);
btrfs_debug(fs_info,
"current progress key " BTRFS_KEY_FMT ", search_slot ret %d",
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 5b551f811bf6..59096abca5f0 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1234,7 +1234,7 @@ static int get_inode_path(struct btrfs_root *root,
key.type = BTRFS_INODE_REF_KEY;
key.offset = 0;
- ret = btrfs_search_slot_for_read(root, &key, p, 1, 0);
+ ret = btrfs_search_slot_for_read(root, &key, p, true);
if (ret < 0)
return ret;
if (ret)
@@ -1979,7 +1979,7 @@ static int get_first_ref(struct btrfs_root *root, u64 ino,
key.type = BTRFS_INODE_REF_KEY;
key.offset = 0;
- ret = btrfs_search_slot_for_read(root, &key, path, 1, 0);
+ ret = btrfs_search_slot_for_read(root, &key, path, true);
if (ret < 0)
return ret;
if (!ret)
@@ -2475,7 +2475,7 @@ static int send_subvol_begin(struct send_ctx *sctx)
key.offset = 0;
ret = btrfs_search_slot_for_read(send_root->fs_info->tree_root,
- &key, path, 1, 0);
+ &key, path, true);
if (ret < 0)
return ret;
if (ret)
@@ -6195,7 +6195,7 @@ static int is_extent_unchanged(struct send_ctx *sctx,
key.objectid = ekey->objectid;
key.type = BTRFS_EXTENT_DATA_KEY;
key.offset = ekey->offset;
- ret = btrfs_search_slot_for_read(sctx->parent_root, &key, path, 0, 0);
+ ret = btrfs_search_slot_for_read(sctx->parent_root, &key, path, false);
if (ret < 0)
return ret;
if (ret)
@@ -6320,7 +6320,7 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset)
key.objectid = sctx->cur_ino;
key.type = BTRFS_EXTENT_DATA_KEY;
key.offset = offset;
- ret = btrfs_search_slot_for_read(root, &key, path, 0, 0);
+ ret = btrfs_search_slot_for_read(root, &key, path, false);
if (ret < 0)
return ret;
ret = 0;
@@ -7292,7 +7292,7 @@ static int full_send_tree(struct send_ctx *sctx)
sctx->last_reloc_trans = fs_info->last_reloc_trans;
up_read(&fs_info->commit_root_sem);
- ret = btrfs_search_slot_for_read(send_root, &key, path, 1, 0);
+ ret = btrfs_search_slot_for_read(send_root, &key, path, true);
if (ret < 0)
return ret;
if (ret)
--
2.52.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-02-08 3:41 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-08 3:19 [PATCH 0/3] btrfs: remove unused return_any parameter from btrfs_search_slot_for_read() Sun YangKai
2026-02-08 3:19 ` [PATCH 1/3] btrfs: qgroup: drop pointless return_any fallback when reading qgroup config Sun YangKai
2026-02-08 3:38 ` [PATCH 2/3] btrfs: send: drop unnecessary return_any search in get_last_extent() Sun YangKai
2026-02-08 3:40 ` [PATCH 3/3] btrfs: simplify btrfs_search_slot_for_read() by removing return_any parameter Sun YangKai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox