public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
* [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