Commit 0584f718 authored by Josef Bacik's avatar Josef Bacik Committed by Chris Mason

Btrfs: don't do extra bitmap search in one bit case

When we make ctl->unit allocations from a bitmap there is no point in searching
for the next 0 in the bitmap.  If we've found a bit we're done and can just exit
the loop.  Thanks,
Signed-off-by: default avatarJosef Bacik <jbacik@fb.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent cef40483
...@@ -1730,7 +1730,7 @@ static void bitmap_set_bits(struct btrfs_free_space_ctl *ctl, ...@@ -1730,7 +1730,7 @@ static void bitmap_set_bits(struct btrfs_free_space_ctl *ctl,
*/ */
static int search_bitmap(struct btrfs_free_space_ctl *ctl, static int search_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *bitmap_info, u64 *offset, struct btrfs_free_space *bitmap_info, u64 *offset,
u64 *bytes) u64 *bytes, bool for_alloc)
{ {
unsigned long found_bits = 0; unsigned long found_bits = 0;
unsigned long max_bits = 0; unsigned long max_bits = 0;
...@@ -1742,7 +1742,8 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl, ...@@ -1742,7 +1742,8 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,
* Skip searching the bitmap if we don't have a contiguous section that * Skip searching the bitmap if we don't have a contiguous section that
* is large enough for this allocation. * is large enough for this allocation.
*/ */
if (bitmap_info->max_extent_size && if (for_alloc &&
bitmap_info->max_extent_size &&
bitmap_info->max_extent_size < *bytes) { bitmap_info->max_extent_size < *bytes) {
*bytes = bitmap_info->max_extent_size; *bytes = bitmap_info->max_extent_size;
return -1; return -1;
...@@ -1753,6 +1754,10 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl, ...@@ -1753,6 +1754,10 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,
bits = bytes_to_bits(*bytes, ctl->unit); bits = bytes_to_bits(*bytes, ctl->unit);
for_each_set_bit_from(i, bitmap_info->bitmap, BITS_PER_BITMAP) { for_each_set_bit_from(i, bitmap_info->bitmap, BITS_PER_BITMAP) {
if (for_alloc && bits == 1) {
found_bits = 1;
break;
}
next_zero = find_next_zero_bit(bitmap_info->bitmap, next_zero = find_next_zero_bit(bitmap_info->bitmap,
BITS_PER_BITMAP, i); BITS_PER_BITMAP, i);
extent_bits = next_zero - i; extent_bits = next_zero - i;
...@@ -1824,7 +1829,7 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes, ...@@ -1824,7 +1829,7 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
if (entry->bitmap) { if (entry->bitmap) {
u64 size = *bytes; u64 size = *bytes;
ret = search_bitmap(ctl, entry, &tmp, &size); ret = search_bitmap(ctl, entry, &tmp, &size, true);
if (!ret) { if (!ret) {
*offset = tmp; *offset = tmp;
*bytes = size; *bytes = size;
...@@ -1885,7 +1890,8 @@ static noinline int remove_from_bitmap(struct btrfs_free_space_ctl *ctl, ...@@ -1885,7 +1890,8 @@ static noinline int remove_from_bitmap(struct btrfs_free_space_ctl *ctl,
search_start = *offset; search_start = *offset;
search_bytes = ctl->unit; search_bytes = ctl->unit;
search_bytes = min(search_bytes, end - search_start + 1); search_bytes = min(search_bytes, end - search_start + 1);
ret = search_bitmap(ctl, bitmap_info, &search_start, &search_bytes); ret = search_bitmap(ctl, bitmap_info, &search_start, &search_bytes,
false);
if (ret < 0 || search_start != *offset) if (ret < 0 || search_start != *offset)
return -EINVAL; return -EINVAL;
...@@ -1930,7 +1936,7 @@ static noinline int remove_from_bitmap(struct btrfs_free_space_ctl *ctl, ...@@ -1930,7 +1936,7 @@ static noinline int remove_from_bitmap(struct btrfs_free_space_ctl *ctl,
search_start = *offset; search_start = *offset;
search_bytes = ctl->unit; search_bytes = ctl->unit;
ret = search_bitmap(ctl, bitmap_info, &search_start, ret = search_bitmap(ctl, bitmap_info, &search_start,
&search_bytes); &search_bytes, false);
if (ret < 0 || search_start != *offset) if (ret < 0 || search_start != *offset)
return -EAGAIN; return -EAGAIN;
...@@ -2685,7 +2691,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, ...@@ -2685,7 +2691,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
search_start = min_start; search_start = min_start;
search_bytes = bytes; search_bytes = bytes;
err = search_bitmap(ctl, entry, &search_start, &search_bytes); err = search_bitmap(ctl, entry, &search_start, &search_bytes, true);
if (err) { if (err) {
if (search_bytes > *max_extent_size) if (search_bytes > *max_extent_size)
*max_extent_size = search_bytes; *max_extent_size = search_bytes;
...@@ -3262,7 +3268,7 @@ static int trim_bitmaps(struct btrfs_block_group_cache *block_group, ...@@ -3262,7 +3268,7 @@ static int trim_bitmaps(struct btrfs_block_group_cache *block_group,
} }
bytes = minlen; bytes = minlen;
ret2 = search_bitmap(ctl, entry, &start, &bytes); ret2 = search_bitmap(ctl, entry, &start, &bytes, false);
if (ret2 || start >= end) { if (ret2 || start >= end) {
spin_unlock(&ctl->tree_lock); spin_unlock(&ctl->tree_lock);
mutex_unlock(&ctl->cache_writeout_mutex); mutex_unlock(&ctl->cache_writeout_mutex);
...@@ -3415,7 +3421,7 @@ u64 btrfs_find_ino_for_alloc(struct btrfs_root *fs_root) ...@@ -3415,7 +3421,7 @@ u64 btrfs_find_ino_for_alloc(struct btrfs_root *fs_root)
u64 count = 1; u64 count = 1;
int ret; int ret;
ret = search_bitmap(ctl, entry, &offset, &count); ret = search_bitmap(ctl, entry, &offset, &count, true);
/* Logic error; Should be empty if it can't find anything */ /* Logic error; Should be empty if it can't find anything */
ASSERT(!ret); ASSERT(!ret);
...@@ -3600,10 +3606,6 @@ int test_add_free_space_entry(struct btrfs_block_group_cache *cache, ...@@ -3600,10 +3606,6 @@ int test_add_free_space_entry(struct btrfs_block_group_cache *cache,
bytes_added = add_bytes_to_bitmap(ctl, bitmap_info, offset, bytes); bytes_added = add_bytes_to_bitmap(ctl, bitmap_info, offset, bytes);
/* We used the newly allocated info, set the max_extent_size to bytes */
if (!info)
bitmap_info->max_extent_size = bytes_added;
bytes -= bytes_added; bytes -= bytes_added;
offset += bytes_added; offset += bytes_added;
spin_unlock(&ctl->tree_lock); spin_unlock(&ctl->tree_lock);
...@@ -3647,7 +3649,7 @@ int test_check_exists(struct btrfs_block_group_cache *cache, ...@@ -3647,7 +3649,7 @@ int test_check_exists(struct btrfs_block_group_cache *cache,
bit_off = offset; bit_off = offset;
bit_bytes = ctl->unit; bit_bytes = ctl->unit;
ret = search_bitmap(ctl, info, &bit_off, &bit_bytes); ret = search_bitmap(ctl, info, &bit_off, &bit_bytes, false);
if (!ret) { if (!ret) {
if (bit_off == offset) { if (bit_off == offset) {
ret = 1; ret = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment