aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-05-27 16:11:38 -0400
committerJosef Bacik <josef@redhat.com>2011-06-08 16:37:29 -0400
commit723bda2083d44edbd6be0f0b09f902120dc07442 (patch)
tree55ee1276c7e5e1dc95a6204cc138d69983bb0ffb /fs
parent2cdc342c204dba69ca3b2ec43d8e6ff41ed920b8 (diff)
Btrfs: fix the allocator loop logic
I was testing with empty_cluster = 0 to try and reproduce a problem and kept hitting early enospc panics. This was because our loop logic was a little confused. So this is what I did 1) Make the loop variable the ultimate decider on wether we should loop again isntead of checking to see if we had an uncached bg, empty size or empty cluster. 2) Increment loop before checking to see what we are on to make the loop definitions make more sense. 3) If we are on the chunk alloc loop don't set empty_size/empty_cluster to 0 unless we didn't actually allocate a chunk. If we did allocate a chunk we should be able to easily setup a new cluster so clearing empty_size/empty_cluster makes us less efficient. This kept me from hitting panics while trying to reproduce the other problem. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/extent-tree.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 0d0a3fe77bb7..b42efc2ded51 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5218,9 +5218,7 @@ loop:
5218 * LOOP_NO_EMPTY_SIZE, set empty_size and empty_cluster to 0 and try 5218 * LOOP_NO_EMPTY_SIZE, set empty_size and empty_cluster to 0 and try
5219 * again 5219 * again
5220 */ 5220 */
5221 if (!ins->objectid && loop < LOOP_NO_EMPTY_SIZE && 5221 if (!ins->objectid && loop < LOOP_NO_EMPTY_SIZE) {
5222 (found_uncached_bg || empty_size || empty_cluster ||
5223 allowed_chunk_alloc)) {
5224 index = 0; 5222 index = 0;
5225 if (loop == LOOP_FIND_IDEAL && found_uncached_bg) { 5223 if (loop == LOOP_FIND_IDEAL && found_uncached_bg) {
5226 found_uncached_bg = false; 5224 found_uncached_bg = false;
@@ -5260,32 +5258,36 @@ loop:
5260 goto search; 5258 goto search;
5261 } 5259 }
5262 5260
5263 if (loop < LOOP_CACHING_WAIT) { 5261 loop++;
5264 loop++;
5265 goto search;
5266 }
5267 5262
5268 if (loop == LOOP_ALLOC_CHUNK) { 5263 if (loop == LOOP_ALLOC_CHUNK) {
5269 empty_size = 0; 5264 if (allowed_chunk_alloc) {
5270 empty_cluster = 0; 5265 ret = do_chunk_alloc(trans, root, num_bytes +
5271 } 5266 2 * 1024 * 1024, data,
5267 CHUNK_ALLOC_LIMITED);
5268 allowed_chunk_alloc = 0;
5269 if (ret == 1)
5270 done_chunk_alloc = 1;
5271 } else if (!done_chunk_alloc &&
5272 space_info->force_alloc ==
5273 CHUNK_ALLOC_NO_FORCE) {
5274 space_info->force_alloc = CHUNK_ALLOC_LIMITED;
5275 }
5272 5276
5273 if (allowed_chunk_alloc) { 5277 /*
5274 ret = do_chunk_alloc(trans, root, num_bytes + 5278 * We didn't allocate a chunk, go ahead and drop the
5275 2 * 1024 * 1024, data, 5279 * empty size and loop again.
5276 CHUNK_ALLOC_LIMITED); 5280 */
5277 allowed_chunk_alloc = 0; 5281 if (!done_chunk_alloc)
5278 done_chunk_alloc = 1; 5282 loop = LOOP_NO_EMPTY_SIZE;
5279 } else if (!done_chunk_alloc &&
5280 space_info->force_alloc == CHUNK_ALLOC_NO_FORCE) {
5281 space_info->force_alloc = CHUNK_ALLOC_LIMITED;
5282 } 5283 }
5283 5284
5284 if (loop < LOOP_NO_EMPTY_SIZE) { 5285 if (loop == LOOP_NO_EMPTY_SIZE) {
5285 loop++; 5286 empty_size = 0;
5286 goto search; 5287 empty_cluster = 0;
5287 } 5288 }
5288 ret = -ENOSPC; 5289
5290 goto search;
5289 } else if (!ins->objectid) { 5291 } else if (!ins->objectid) {
5290 ret = -ENOSPC; 5292 ret = -ENOSPC;
5291 } else if (ins->objectid) { 5293 } else if (ins->objectid) {