In comes cases the empty cluster was added twice to the total number of
bytes the allocator was trying to find.
With empty clustering on, the hint byte was sometimes outside of the
block group. Add an extra goto to find the correct block group.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
}
search_start = max(search_start, first_logical_byte(root, 0));
search_start = max(search_start, hint_byte);
}
search_start = max(search_start, first_logical_byte(root, 0));
search_start = max(search_start, hint_byte);
- total_needed += empty_size;
- if (search_start != last_wanted)
+ if (last_wanted && search_start != last_wanted) {
+ empty_size += empty_cluster;
+ }
+ total_needed += empty_size;
block_group = btrfs_lookup_block_group(root->fs_info, search_start);
if (!block_group)
block_group = btrfs_lookup_first_block_group(root->fs_info,
block_group = btrfs_lookup_block_group(root->fs_info, search_start);
if (!block_group)
block_group = btrfs_lookup_first_block_group(root->fs_info,
* group thats not of the proper type, while looping this
* should never happen
*/
* group thats not of the proper type, while looping this
* should never happen
*/
+ if (!block_group)
+ goto new_group_no_lock;
+
mutex_lock(&block_group->alloc_mutex);
if (unlikely(!block_group_bits(block_group, data)))
goto new_group;
mutex_lock(&block_group->alloc_mutex);
if (unlikely(!block_group_bits(block_group, data)))
goto new_group;
+ mutex_unlock(&block_group->alloc_mutex);
+new_group_no_lock:
+ if (!allowed_chunk_alloc && loop > 0) {
total_needed -= empty_cluster;
empty_cluster = 0;
}
total_needed -= empty_cluster;
empty_cluster = 0;
}
- mutex_unlock(&block_group->alloc_mutex);
/*
* Here's how this works.
* loop == 0: we were searching a block group via a hint
/*
* Here's how this works.
* loop == 0: we were searching a block group via a hint
cur = head->next;
loop++;
} else if (loop == 1 && cur == head) {
cur = head->next;
loop++;
} else if (loop == 1 && cur == head) {
+
+ total_needed -= empty_cluster;
+ empty_cluster = 0;
+
if (allowed_chunk_alloc && !chunk_alloc_done) {
up_read(&space_info->groups_sem);
ret = do_chunk_alloc(trans, root, num_bytes +
if (allowed_chunk_alloc && !chunk_alloc_done) {
up_read(&space_info->groups_sem);
ret = do_chunk_alloc(trans, root, num_bytes +