aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAditya Kali <adityakali@google.com>2010-08-05 16:22:24 -0400
committerTheodore Ts'o <tytso@mit.edu>2010-08-05 16:22:24 -0400
commit6c7a120ac6c62316ab1fc78dfc0a7b13f3bfcbff (patch)
tree371f7d7050c42fbc8fb03a66233081a594df40b8 /fs
parent56d35a4cd13e7bc5eca5b2dba5a41794afb17e11 (diff)
ext4: Adding error check after calling ext4_mb_regular_allocator()
If the bitmap block on disk is bad, ext4_mb_load_buddy() returns an error. This error is returned to the caller, ext4_mb_regular_allocator() and then to ext4_mb_new_blocks(). But ext4_mb_new_blocks() did not check for the return value of ext4_mb_regular_allocator() and would repeatedly try to load the bitmap block. The fix simply catches the return value and exits out of the 'repeat' loop after cleanup. We also take the opportunity to clean up the error handling in ext4_mb_new_blocks(). Google-Bug-Id: 2853530 Signed-off-by: Aditya Kali <adityakali@google.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/mballoc.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 3da28281bc54..1f360f07cb40 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -4253,7 +4253,7 @@ static int ext4_mb_discard_preallocations(struct super_block *sb, int needed)
4253 * to usual allocation 4253 * to usual allocation
4254 */ 4254 */
4255ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, 4255ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
4256 struct ext4_allocation_request *ar, int *errp) 4256 struct ext4_allocation_request *ar, int *errp)
4257{ 4257{
4258 int freed; 4258 int freed;
4259 struct ext4_allocation_context *ac = NULL; 4259 struct ext4_allocation_context *ac = NULL;
@@ -4297,7 +4297,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
4297 inquota = ar->len; 4297 inquota = ar->len;
4298 if (ar->len == 0) { 4298 if (ar->len == 0) {
4299 *errp = -EDQUOT; 4299 *errp = -EDQUOT;
4300 goto out3; 4300 goto out;
4301 } 4301 }
4302 } 4302 }
4303 4303
@@ -4305,13 +4305,13 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
4305 if (!ac) { 4305 if (!ac) {
4306 ar->len = 0; 4306 ar->len = 0;
4307 *errp = -ENOMEM; 4307 *errp = -ENOMEM;
4308 goto out1; 4308 goto out;
4309 } 4309 }
4310 4310
4311 *errp = ext4_mb_initialize_context(ac, ar); 4311 *errp = ext4_mb_initialize_context(ac, ar);
4312 if (*errp) { 4312 if (*errp) {
4313 ar->len = 0; 4313 ar->len = 0;
4314 goto out2; 4314 goto out;
4315 } 4315 }
4316 4316
4317 ac->ac_op = EXT4_MB_HISTORY_PREALLOC; 4317 ac->ac_op = EXT4_MB_HISTORY_PREALLOC;
@@ -4320,7 +4320,9 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
4320 ext4_mb_normalize_request(ac, ar); 4320 ext4_mb_normalize_request(ac, ar);
4321repeat: 4321repeat:
4322 /* allocate space in core */ 4322 /* allocate space in core */
4323 ext4_mb_regular_allocator(ac); 4323 *errp = ext4_mb_regular_allocator(ac);
4324 if (*errp)
4325 goto errout;
4324 4326
4325 /* as we've just preallocated more space than 4327 /* as we've just preallocated more space than
4326 * user requested orinally, we store allocated 4328 * user requested orinally, we store allocated
@@ -4331,7 +4333,7 @@ repeat:
4331 } 4333 }
4332 if (likely(ac->ac_status == AC_STATUS_FOUND)) { 4334 if (likely(ac->ac_status == AC_STATUS_FOUND)) {
4333 *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_blks); 4335 *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_blks);
4334 if (*errp == -EAGAIN) { 4336 if (*errp == -EAGAIN) {
4335 /* 4337 /*
4336 * drop the reference that we took 4338 * drop the reference that we took
4337 * in ext4_mb_use_best_found 4339 * in ext4_mb_use_best_found
@@ -4342,12 +4344,10 @@ repeat:
4342 ac->ac_b_ex.fe_len = 0; 4344 ac->ac_b_ex.fe_len = 0;
4343 ac->ac_status = AC_STATUS_CONTINUE; 4345 ac->ac_status = AC_STATUS_CONTINUE;
4344 goto repeat; 4346 goto repeat;
4345 } else if (*errp) { 4347 } else if (*errp)
4348 errout:
4346 ext4_discard_allocated_blocks(ac); 4349 ext4_discard_allocated_blocks(ac);
4347 ac->ac_b_ex.fe_len = 0; 4350 else {
4348 ar->len = 0;
4349 ext4_mb_show_ac(ac);
4350 } else {
4351 block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); 4351 block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex);
4352 ar->len = ac->ac_b_ex.fe_len; 4352 ar->len = ac->ac_b_ex.fe_len;
4353 } 4353 }
@@ -4356,19 +4356,19 @@ repeat:
4356 if (freed) 4356 if (freed)
4357 goto repeat; 4357 goto repeat;
4358 *errp = -ENOSPC; 4358 *errp = -ENOSPC;
4359 }
4360
4361 if (*errp) {
4359 ac->ac_b_ex.fe_len = 0; 4362 ac->ac_b_ex.fe_len = 0;
4360 ar->len = 0; 4363 ar->len = 0;
4361 ext4_mb_show_ac(ac); 4364 ext4_mb_show_ac(ac);
4362 } 4365 }
4363
4364 ext4_mb_release_context(ac); 4366 ext4_mb_release_context(ac);
4365 4367out:
4366out2: 4368 if (ac)
4367 kmem_cache_free(ext4_ac_cachep, ac); 4369 kmem_cache_free(ext4_ac_cachep, ac);
4368out1:
4369 if (inquota && ar->len < inquota) 4370 if (inquota && ar->len < inquota)
4370 dquot_free_block(ar->inode, inquota - ar->len); 4371 dquot_free_block(ar->inode, inquota - ar->len);
4371out3:
4372 if (!ar->len) { 4372 if (!ar->len) {
4373 if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) 4373 if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag)
4374 /* release all the reserved blocks if non delalloc */ 4374 /* release all the reserved blocks if non delalloc */