Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c7a120a authored by Aditya Kali's avatar Aditya Kali Committed by Theodore Ts'o
Browse files

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: default avatarAditya Kali <adityakali@google.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 56d35a4c
Loading
Loading
Loading
Loading
+17 −17
Original line number Diff line number Diff line
@@ -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 */