Skip to content

Commit 995e9a1

Browse files
lorddoskiaskdave
authored andcommitted
btrfs: open code key_search
This function wraps the optimisation implemented by d7396f0 ("Btrfs: optimize key searches in btrfs_search_slot") however this optimisation is really used in only one place - btrfs_search_slot. Just open code the optimisation and also add a comment explaining how it works since it's not clear just by looking at the code - the key point here is it depends on an internal invariant that BTRFS' btree provides, namely intermediate pointers always contain the key at slot0 at the child node. So in the case of exact match we can safely assume that the given key will always be in slot 0 on lower levels. Furthermore this results in a reduction of btrfs_search_slot's size: ./scripts/bloat-o-meter ctree.orig fs/btrfs/ctree.o add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-75 (-75) Function old new delta btrfs_search_slot 2783 2708 -75 Total: Before=50423, After=50348, chg -0.15% Reviewed-by: Johannes Thumshirn <[email protected]> Signed-off-by: Nikolay Borisov <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent d8f3e73 commit 995e9a1

File tree

1 file changed

+18
-23
lines changed

1 file changed

+18
-23
lines changed

fs/btrfs/ctree.c

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,19 +2488,6 @@ setup_nodes_for_search(struct btrfs_trans_handle *trans,
24882488
return ret;
24892489
}
24902490

2491-
static int key_search(struct extent_buffer *b, const struct btrfs_key *key,
2492-
int *prev_cmp, int *slot)
2493-
{
2494-
if (*prev_cmp != 0) {
2495-
*prev_cmp = btrfs_bin_search(b, key, slot);
2496-
return *prev_cmp;
2497-
}
2498-
2499-
*slot = 0;
2500-
2501-
return 0;
2502-
}
2503-
25042491
int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path,
25052492
u64 iobjectid, u64 ioff, u8 key_type,
25062493
struct btrfs_key *found_key)
@@ -2770,9 +2757,23 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
27702757
}
27712758
}
27722759

2773-
ret = key_search(b, key, &prev_cmp, &slot);
2774-
if (ret < 0)
2775-
goto done;
2760+
/*
2761+
* If btrfs_bin_search returns an exact match (prev_cmp == 0)
2762+
* we can safely assume the target key will always be in slot 0
2763+
* on lower levels due to the invariants BTRFS' btree provides,
2764+
* namely that a btrfs_key_ptr entry always points to the
2765+
* lowest key in the child node, thus we can skip searching
2766+
* lower levels
2767+
*/
2768+
if (prev_cmp == 0) {
2769+
slot = 0;
2770+
ret = 0;
2771+
} else {
2772+
ret = btrfs_bin_search(b, key, &slot);
2773+
prev_cmp = ret;
2774+
if (ret < 0)
2775+
goto done;
2776+
}
27762777

27772778
if (level == 0) {
27782779
p->slots[level] = slot;
@@ -2896,7 +2897,6 @@ int btrfs_search_old_slot(struct btrfs_root *root, const struct btrfs_key *key,
28962897
int level;
28972898
int lowest_unlock = 1;
28982899
u8 lowest_level = 0;
2899-
int prev_cmp = -1;
29002900

29012901
lowest_level = p->lowest_level;
29022902
WARN_ON(p->nodes[0] != NULL);
@@ -2929,12 +2929,7 @@ int btrfs_search_old_slot(struct btrfs_root *root, const struct btrfs_key *key,
29292929
*/
29302930
btrfs_unlock_up_safe(p, level + 1);
29312931

2932-
/*
2933-
* Since we can unwind ebs we want to do a real search every
2934-
* time.
2935-
*/
2936-
prev_cmp = -1;
2937-
ret = key_search(b, key, &prev_cmp, &slot);
2932+
ret = btrfs_bin_search(b, key, &slot);
29382933
if (ret < 0)
29392934
goto done;
29402935

0 commit comments

Comments
 (0)