aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 0d73a53c6763..b92e92c29e3b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2152,11 +2152,13 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
2152 } 2152 }
2153 search_start = max(search_start, first_logical_byte(root, 0)); 2153 search_start = max(search_start, first_logical_byte(root, 0));
2154 search_start = max(search_start, hint_byte); 2154 search_start = max(search_start, hint_byte);
2155 total_needed += empty_size;
2156 2155
2157 if (search_start != last_wanted) 2156 if (last_wanted && search_start != last_wanted) {
2158 last_wanted = 0; 2157 last_wanted = 0;
2158 empty_size += empty_cluster;
2159 }
2159 2160
2161 total_needed += empty_size;
2160 block_group = btrfs_lookup_block_group(root->fs_info, search_start); 2162 block_group = btrfs_lookup_block_group(root->fs_info, search_start);
2161 if (!block_group) 2163 if (!block_group)
2162 block_group = btrfs_lookup_first_block_group(root->fs_info, 2164 block_group = btrfs_lookup_first_block_group(root->fs_info,
@@ -2171,7 +2173,9 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
2171 * group thats not of the proper type, while looping this 2173 * group thats not of the proper type, while looping this
2172 * should never happen 2174 * should never happen
2173 */ 2175 */
2174 WARN_ON(!block_group); 2176 if (!block_group)
2177 goto new_group_no_lock;
2178
2175 mutex_lock(&block_group->alloc_mutex); 2179 mutex_lock(&block_group->alloc_mutex);
2176 if (unlikely(!block_group_bits(block_group, data))) 2180 if (unlikely(!block_group_bits(block_group, data)))
2177 goto new_group; 2181 goto new_group;
@@ -2248,12 +2252,13 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
2248 break; 2252 break;
2249 } 2253 }
2250new_group: 2254new_group:
2255 mutex_unlock(&block_group->alloc_mutex);
2256new_group_no_lock:
2251 last_wanted = 0; 2257 last_wanted = 0;
2252 if (loop > 0) { 2258 if (!allowed_chunk_alloc && loop > 0) {
2253 total_needed -= empty_cluster; 2259 total_needed -= empty_cluster;
2254 empty_cluster = 0; 2260 empty_cluster = 0;
2255 } 2261 }
2256 mutex_unlock(&block_group->alloc_mutex);
2257 /* 2262 /*
2258 * Here's how this works. 2263 * Here's how this works.
2259 * loop == 0: we were searching a block group via a hint 2264 * loop == 0: we were searching a block group via a hint
@@ -2271,6 +2276,10 @@ new_group:
2271 cur = head->next; 2276 cur = head->next;
2272 loop++; 2277 loop++;
2273 } else if (loop == 1 && cur == head) { 2278 } else if (loop == 1 && cur == head) {
2279
2280 total_needed -= empty_cluster;
2281 empty_cluster = 0;
2282
2274 if (allowed_chunk_alloc && !chunk_alloc_done) { 2283 if (allowed_chunk_alloc && !chunk_alloc_done) {
2275 up_read(&space_info->groups_sem); 2284 up_read(&space_info->groups_sem);
2276 ret = do_chunk_alloc(trans, root, num_bytes + 2285 ret = do_chunk_alloc(trans, root, num_bytes +