Skip to content

Commit 5cd17f3

Browse files
committed
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 <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent ce7afe8 commit 5cd17f3

File tree

1 file changed

+15
-28
lines changed

1 file changed

+15
-28
lines changed

fs/btrfs/ctree.c

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,15 +1668,8 @@ static noinline int generic_bin_search(struct extent_buffer *eb,
16681668
{
16691669
int low = 0;
16701670
int high = max;
1671-
int mid;
16721671
int ret;
1673-
struct btrfs_disk_key *tmp = NULL;
1674-
struct btrfs_disk_key unaligned;
1675-
unsigned long offset;
1676-
char *kaddr = NULL;
1677-
unsigned long map_start = 0;
1678-
unsigned long map_len = 0;
1679-
int err;
1672+
const int key_size = sizeof(struct btrfs_disk_key);
16801673

16811674
if (low > high) {
16821675
btrfs_err(eb->fs_info,
@@ -1687,32 +1680,26 @@ static noinline int generic_bin_search(struct extent_buffer *eb,
16871680
}
16881681

16891682
while (low < high) {
1683+
unsigned long oip;
1684+
unsigned long offset;
1685+
struct btrfs_disk_key *tmp;
1686+
struct btrfs_disk_key unaligned;
1687+
int mid;
1688+
16901689
mid = (low + high) / 2;
16911690
offset = p + mid * item_size;
1691+
oip = offset_in_page(offset);
16921692

1693-
if (!kaddr || offset < map_start ||
1694-
(offset + sizeof(struct btrfs_disk_key)) >
1695-
map_start + map_len) {
1696-
1697-
err = map_private_extent_buffer(eb, offset,
1698-
sizeof(struct btrfs_disk_key),
1699-
&kaddr, &map_start, &map_len);
1700-
1701-
if (!err) {
1702-
tmp = (struct btrfs_disk_key *)(kaddr + offset -
1703-
map_start);
1704-
} else if (err == 1) {
1705-
read_extent_buffer(eb, &unaligned,
1706-
offset, sizeof(unaligned));
1707-
tmp = &unaligned;
1708-
} else {
1709-
return err;
1710-
}
1693+
if (oip + key_size <= PAGE_SIZE) {
1694+
const unsigned long idx = offset >> PAGE_SHIFT;
1695+
char *kaddr = page_address(eb->pages[idx]);
17111696

1697+
tmp = (struct btrfs_disk_key *)(kaddr + oip);
17121698
} else {
1713-
tmp = (struct btrfs_disk_key *)(kaddr + offset -
1714-
map_start);
1699+
read_extent_buffer(eb, &unaligned, offset, key_size);
1700+
tmp = &unaligned;
17151701
}
1702+
17161703
ret = comp_keys(tmp, key);
17171704

17181705
if (ret < 0)

0 commit comments

Comments
 (0)