btrfs: speed up and simplify generic_bin_search
The bin search jumps over the extent buffer item keys, comparing directly the bytes if the key is in one page, or storing it in a temporary buffer in case it spans two pages. The mapping start and length are obtained from map_private_extent_buffer, which is heavy weight compared to what we need. We know the key size and can find out the eb page in a simple way. For keys spanning two pages the fallback read_extent_buffer is used. The temporary variables are reduced and moved to the scope of use. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
ce7afe8782
commit
5cd17f343b
@ -1668,15 +1668,8 @@ static noinline int generic_bin_search(struct extent_buffer *eb,
|
||||
{
|
||||
int low = 0;
|
||||
int high = max;
|
||||
int mid;
|
||||
int ret;
|
||||
struct btrfs_disk_key *tmp = NULL;
|
||||
struct btrfs_disk_key unaligned;
|
||||
unsigned long offset;
|
||||
char *kaddr = NULL;
|
||||
unsigned long map_start = 0;
|
||||
unsigned long map_len = 0;
|
||||
int err;
|
||||
const int key_size = sizeof(struct btrfs_disk_key);
|
||||
|
||||
if (low > high) {
|
||||
btrfs_err(eb->fs_info,
|
||||
@ -1687,32 +1680,26 @@ static noinline int generic_bin_search(struct extent_buffer *eb,
|
||||
}
|
||||
|
||||
while (low < high) {
|
||||
unsigned long oip;
|
||||
unsigned long offset;
|
||||
struct btrfs_disk_key *tmp;
|
||||
struct btrfs_disk_key unaligned;
|
||||
int mid;
|
||||
|
||||
mid = (low + high) / 2;
|
||||
offset = p + mid * item_size;
|
||||
oip = offset_in_page(offset);
|
||||
|
||||
if (!kaddr || offset < map_start ||
|
||||
(offset + sizeof(struct btrfs_disk_key)) >
|
||||
map_start + map_len) {
|
||||
|
||||
err = map_private_extent_buffer(eb, offset,
|
||||
sizeof(struct btrfs_disk_key),
|
||||
&kaddr, &map_start, &map_len);
|
||||
|
||||
if (!err) {
|
||||
tmp = (struct btrfs_disk_key *)(kaddr + offset -
|
||||
map_start);
|
||||
} else if (err == 1) {
|
||||
read_extent_buffer(eb, &unaligned,
|
||||
offset, sizeof(unaligned));
|
||||
tmp = &unaligned;
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
if (oip + key_size <= PAGE_SIZE) {
|
||||
const unsigned long idx = offset >> PAGE_SHIFT;
|
||||
char *kaddr = page_address(eb->pages[idx]);
|
||||
|
||||
tmp = (struct btrfs_disk_key *)(kaddr + oip);
|
||||
} else {
|
||||
tmp = (struct btrfs_disk_key *)(kaddr + offset -
|
||||
map_start);
|
||||
read_extent_buffer(eb, &unaligned, offset, key_size);
|
||||
tmp = &unaligned;
|
||||
}
|
||||
|
||||
ret = comp_keys(tmp, key);
|
||||
|
||||
if (ret < 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user