diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index d119c0388af1..2f82fabd7011 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -4028,6 +4028,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
4028 | int loop = 0; | 4028 | int loop = 0; |
4029 | bool found_uncached_bg = false; | 4029 | bool found_uncached_bg = false; |
4030 | bool failed_cluster_refill = false; | 4030 | bool failed_cluster_refill = false; |
4031 | bool failed_alloc = false; | ||
4031 | 4032 | ||
4032 | WARN_ON(num_bytes < root->sectorsize); | 4033 | WARN_ON(num_bytes < root->sectorsize); |
4033 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); | 4034 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); |
@@ -4232,14 +4233,23 @@ refill_cluster: | |||
4232 | 4233 | ||
4233 | offset = btrfs_find_space_for_alloc(block_group, search_start, | 4234 | offset = btrfs_find_space_for_alloc(block_group, search_start, |
4234 | num_bytes, empty_size); | 4235 | num_bytes, empty_size); |
4235 | if (!offset && (cached || (!cached && | 4236 | /* |
4236 | loop == LOOP_CACHING_NOWAIT))) { | 4237 | * If we didn't find a chunk, and we haven't failed on this |
4237 | goto loop; | 4238 | * block group before, and this block group is in the middle of |
4238 | } else if (!offset && (!cached && | 4239 | * caching and we are ok with waiting, then go ahead and wait |
4239 | loop > LOOP_CACHING_NOWAIT)) { | 4240 | * for progress to be made, and set failed_alloc to true. |
4241 | * | ||
4242 | * If failed_alloc is true then we've already waited on this | ||
4243 | * block group once and should move on to the next block group. | ||
4244 | */ | ||
4245 | if (!offset && !failed_alloc && !cached && | ||
4246 | loop > LOOP_CACHING_NOWAIT) { | ||
4240 | wait_block_group_cache_progress(block_group, | 4247 | wait_block_group_cache_progress(block_group, |
4241 | num_bytes + empty_size); | 4248 | num_bytes + empty_size); |
4249 | failed_alloc = true; | ||
4242 | goto have_block_group; | 4250 | goto have_block_group; |
4251 | } else if (!offset) { | ||
4252 | goto loop; | ||
4243 | } | 4253 | } |
4244 | checks: | 4254 | checks: |
4245 | search_start = stripe_align(root, offset); | 4255 | search_start = stripe_align(root, offset); |
@@ -4287,6 +4297,7 @@ checks: | |||
4287 | break; | 4297 | break; |
4288 | loop: | 4298 | loop: |
4289 | failed_cluster_refill = false; | 4299 | failed_cluster_refill = false; |
4300 | failed_alloc = false; | ||
4290 | btrfs_put_block_group(block_group); | 4301 | btrfs_put_block_group(block_group); |
4291 | } | 4302 | } |
4292 | up_read(&space_info->groups_sem); | 4303 | up_read(&space_info->groups_sem); |