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>
This commit is contained in:
committed by
Theodore Ts'o
parent
56d35a4cd1
commit
6c7a120ac6
@@ -4297,7 +4297,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
|
||||
inquota = ar->len;
|
||||
if (ar->len == 0) {
|
||||
*errp = -EDQUOT;
|
||||
goto out3;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4305,13 +4305,13 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
|
||||
if (!ac) {
|
||||
ar->len = 0;
|
||||
*errp = -ENOMEM;
|
||||
goto out1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*errp = ext4_mb_initialize_context(ac, ar);
|
||||
if (*errp) {
|
||||
ar->len = 0;
|
||||
goto out2;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ac->ac_op = EXT4_MB_HISTORY_PREALLOC;
|
||||
@@ -4320,7 +4320,9 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
|
||||
ext4_mb_normalize_request(ac, ar);
|
||||
repeat:
|
||||
/* allocate space in core */
|
||||
ext4_mb_regular_allocator(ac);
|
||||
*errp = ext4_mb_regular_allocator(ac);
|
||||
if (*errp)
|
||||
goto errout;
|
||||
|
||||
/* as we've just preallocated more space than
|
||||
* user requested orinally, we store allocated
|
||||
@@ -4342,12 +4344,10 @@ repeat:
|
||||
ac->ac_b_ex.fe_len = 0;
|
||||
ac->ac_status = AC_STATUS_CONTINUE;
|
||||
goto repeat;
|
||||
} else if (*errp) {
|
||||
} else if (*errp)
|
||||
errout:
|
||||
ext4_discard_allocated_blocks(ac);
|
||||
ac->ac_b_ex.fe_len = 0;
|
||||
ar->len = 0;
|
||||
ext4_mb_show_ac(ac);
|
||||
} else {
|
||||
else {
|
||||
block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex);
|
||||
ar->len = ac->ac_b_ex.fe_len;
|
||||
}
|
||||
@@ -4356,19 +4356,19 @@ repeat:
|
||||
if (freed)
|
||||
goto repeat;
|
||||
*errp = -ENOSPC;
|
||||
}
|
||||
|
||||
if (*errp) {
|
||||
ac->ac_b_ex.fe_len = 0;
|
||||
ar->len = 0;
|
||||
ext4_mb_show_ac(ac);
|
||||
}
|
||||
|
||||
ext4_mb_release_context(ac);
|
||||
|
||||
out2:
|
||||
out:
|
||||
if (ac)
|
||||
kmem_cache_free(ext4_ac_cachep, ac);
|
||||
out1:
|
||||
if (inquota && ar->len < inquota)
|
||||
dquot_free_block(ar->inode, inquota - ar->len);
|
||||
out3:
|
||||
if (!ar->len) {
|
||||
if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag)
|
||||
/* release all the reserved blocks if non delalloc */
|
||||
|
Reference in New Issue
Block a user