btrfs: open code key_search
This function wraps the optimisation implemented by d7396f0735
("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 <johannes.thumshirn@wdc.com>
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Родитель
d8f3e73587
Коммит
995e9a166b
|
@ -2488,19 +2488,6 @@ done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int key_search(struct extent_buffer *b, const struct btrfs_key *key,
|
|
||||||
int *prev_cmp, int *slot)
|
|
||||||
{
|
|
||||||
if (*prev_cmp != 0) {
|
|
||||||
*prev_cmp = btrfs_bin_search(b, key, slot);
|
|
||||||
return *prev_cmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
*slot = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path,
|
int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path,
|
||||||
u64 iobjectid, u64 ioff, u8 key_type,
|
u64 iobjectid, u64 ioff, u8 key_type,
|
||||||
struct btrfs_key *found_key)
|
struct btrfs_key *found_key)
|
||||||
|
@ -2770,9 +2757,23 @@ cow_done:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = key_search(b, key, &prev_cmp, &slot);
|
/*
|
||||||
if (ret < 0)
|
* If btrfs_bin_search returns an exact match (prev_cmp == 0)
|
||||||
goto done;
|
* we can safely assume the target key will always be in slot 0
|
||||||
|
* on lower levels due to the invariants BTRFS' btree provides,
|
||||||
|
* namely that a btrfs_key_ptr entry always points to the
|
||||||
|
* lowest key in the child node, thus we can skip searching
|
||||||
|
* lower levels
|
||||||
|
*/
|
||||||
|
if (prev_cmp == 0) {
|
||||||
|
slot = 0;
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
ret = btrfs_bin_search(b, key, &slot);
|
||||||
|
prev_cmp = ret;
|
||||||
|
if (ret < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (level == 0) {
|
if (level == 0) {
|
||||||
p->slots[level] = slot;
|
p->slots[level] = slot;
|
||||||
|
@ -2896,7 +2897,6 @@ int btrfs_search_old_slot(struct btrfs_root *root, const struct btrfs_key *key,
|
||||||
int level;
|
int level;
|
||||||
int lowest_unlock = 1;
|
int lowest_unlock = 1;
|
||||||
u8 lowest_level = 0;
|
u8 lowest_level = 0;
|
||||||
int prev_cmp = -1;
|
|
||||||
|
|
||||||
lowest_level = p->lowest_level;
|
lowest_level = p->lowest_level;
|
||||||
WARN_ON(p->nodes[0] != NULL);
|
WARN_ON(p->nodes[0] != NULL);
|
||||||
|
@ -2929,12 +2929,7 @@ again:
|
||||||
*/
|
*/
|
||||||
btrfs_unlock_up_safe(p, level + 1);
|
btrfs_unlock_up_safe(p, level + 1);
|
||||||
|
|
||||||
/*
|
ret = btrfs_bin_search(b, key, &slot);
|
||||||
* Since we can unwind ebs we want to do a real search every
|
|
||||||
* time.
|
|
||||||
*/
|
|
||||||
prev_cmp = -1;
|
|
||||||
ret = key_search(b, key, &prev_cmp, &slot);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче