diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 5b9b6b6df242..71cd456fdb60 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3089,6 +3089,13 @@ alloc: | |||
3089 | } | 3089 | } |
3090 | goto again; | 3090 | goto again; |
3091 | } | 3091 | } |
3092 | |||
3093 | /* | ||
3094 | * If we have less pinned bytes than we want to allocate then | ||
3095 | * don't bother committing the transaction, it won't help us. | ||
3096 | */ | ||
3097 | if (data_sinfo->bytes_pinned < bytes) | ||
3098 | committed = 1; | ||
3092 | spin_unlock(&data_sinfo->lock); | 3099 | spin_unlock(&data_sinfo->lock); |
3093 | 3100 | ||
3094 | /* commit the current transaction and try again */ | 3101 | /* commit the current transaction and try again */ |
@@ -3307,10 +3314,6 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3307 | if (reserved == 0) | 3314 | if (reserved == 0) |
3308 | return 0; | 3315 | return 0; |
3309 | 3316 | ||
3310 | /* nothing to shrink - nothing to reclaim */ | ||
3311 | if (root->fs_info->delalloc_bytes == 0) | ||
3312 | return 0; | ||
3313 | |||
3314 | max_reclaim = min(reserved, to_reclaim); | 3317 | max_reclaim = min(reserved, to_reclaim); |
3315 | 3318 | ||
3316 | while (loops < 1024) { | 3319 | while (loops < 1024) { |
@@ -4839,7 +4842,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
4839 | u64 num_bytes, u64 empty_size, | 4842 | u64 num_bytes, u64 empty_size, |
4840 | u64 search_start, u64 search_end, | 4843 | u64 search_start, u64 search_end, |
4841 | u64 hint_byte, struct btrfs_key *ins, | 4844 | u64 hint_byte, struct btrfs_key *ins, |
4842 | int data) | 4845 | u64 data) |
4843 | { | 4846 | { |
4844 | int ret = 0; | 4847 | int ret = 0; |
4845 | struct btrfs_root *root = orig_root->fs_info->extent_root; | 4848 | struct btrfs_root *root = orig_root->fs_info->extent_root; |
@@ -4866,7 +4869,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
4866 | 4869 | ||
4867 | space_info = __find_space_info(root->fs_info, data); | 4870 | space_info = __find_space_info(root->fs_info, data); |
4868 | if (!space_info) { | 4871 | if (!space_info) { |
4869 | printk(KERN_ERR "No space info for %d\n", data); | 4872 | printk(KERN_ERR "No space info for %llu\n", data); |
4870 | return -ENOSPC; | 4873 | return -ENOSPC; |
4871 | } | 4874 | } |
4872 | 4875 | ||
@@ -5211,9 +5214,7 @@ loop: | |||
5211 | * LOOP_NO_EMPTY_SIZE, set empty_size and empty_cluster to 0 and try | 5214 | * LOOP_NO_EMPTY_SIZE, set empty_size and empty_cluster to 0 and try |
5212 | * again | 5215 | * again |
5213 | */ | 5216 | */ |
5214 | if (!ins->objectid && loop < LOOP_NO_EMPTY_SIZE && | 5217 | if (!ins->objectid && loop < LOOP_NO_EMPTY_SIZE) { |
5215 | (found_uncached_bg || empty_size || empty_cluster || | ||
5216 | allowed_chunk_alloc)) { | ||
5217 | index = 0; | 5218 | index = 0; |
5218 | if (loop == LOOP_FIND_IDEAL && found_uncached_bg) { | 5219 | if (loop == LOOP_FIND_IDEAL && found_uncached_bg) { |
5219 | found_uncached_bg = false; | 5220 | found_uncached_bg = false; |
@@ -5253,32 +5254,36 @@ loop: | |||
5253 | goto search; | 5254 | goto search; |
5254 | } | 5255 | } |
5255 | 5256 | ||
5256 | if (loop < LOOP_CACHING_WAIT) { | 5257 | loop++; |
5257 | loop++; | ||
5258 | goto search; | ||
5259 | } | ||
5260 | 5258 | ||
5261 | if (loop == LOOP_ALLOC_CHUNK) { | 5259 | if (loop == LOOP_ALLOC_CHUNK) { |
5262 | empty_size = 0; | 5260 | if (allowed_chunk_alloc) { |
5263 | empty_cluster = 0; | 5261 | ret = do_chunk_alloc(trans, root, num_bytes + |
5264 | } | 5262 | 2 * 1024 * 1024, data, |
5263 | CHUNK_ALLOC_LIMITED); | ||
5264 | allowed_chunk_alloc = 0; | ||
5265 | if (ret == 1) | ||
5266 | done_chunk_alloc = 1; | ||
5267 | } else if (!done_chunk_alloc && | ||
5268 | space_info->force_alloc == | ||
5269 | CHUNK_ALLOC_NO_FORCE) { | ||
5270 | space_info->force_alloc = CHUNK_ALLOC_LIMITED; | ||
5271 | } | ||
5265 | 5272 | ||
5266 | if (allowed_chunk_alloc) { | 5273 | /* |
5267 | ret = do_chunk_alloc(trans, root, num_bytes + | 5274 | * We didn't allocate a chunk, go ahead and drop the |
5268 | 2 * 1024 * 1024, data, | 5275 | * empty size and loop again. |
5269 | CHUNK_ALLOC_LIMITED); | 5276 | */ |
5270 | allowed_chunk_alloc = 0; | 5277 | if (!done_chunk_alloc) |
5271 | done_chunk_alloc = 1; | 5278 | loop = LOOP_NO_EMPTY_SIZE; |
5272 | } else if (!done_chunk_alloc && | ||
5273 | space_info->force_alloc == CHUNK_ALLOC_NO_FORCE) { | ||
5274 | space_info->force_alloc = CHUNK_ALLOC_LIMITED; | ||
5275 | } | 5279 | } |
5276 | 5280 | ||
5277 | if (loop < LOOP_NO_EMPTY_SIZE) { | 5281 | if (loop == LOOP_NO_EMPTY_SIZE) { |
5278 | loop++; | 5282 | empty_size = 0; |
5279 | goto search; | 5283 | empty_cluster = 0; |
5280 | } | 5284 | } |
5281 | ret = -ENOSPC; | 5285 | |
5286 | goto search; | ||
5282 | } else if (!ins->objectid) { | 5287 | } else if (!ins->objectid) { |
5283 | ret = -ENOSPC; | 5288 | ret = -ENOSPC; |
5284 | } else if (ins->objectid) { | 5289 | } else if (ins->objectid) { |