|
|
@@ -3217,8 +3217,27 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac)
|
|
|
static void ext4_discard_allocated_blocks(struct ext4_allocation_context *ac)
|
|
|
{
|
|
|
struct ext4_prealloc_space *pa = ac->ac_pa;
|
|
|
+ struct ext4_buddy e4b;
|
|
|
+ int err;
|
|
|
|
|
|
- if (pa && pa->pa_type == MB_INODE_PA)
|
|
|
+ if (pa == NULL) {
|
|
|
+ err = ext4_mb_load_buddy(ac->ac_sb, ac->ac_f_ex.fe_group, &e4b);
|
|
|
+ if (err) {
|
|
|
+ /*
|
|
|
+ * This should never happen since we pin the
|
|
|
+ * pages in the ext4_allocation_context so
|
|
|
+ * ext4_mb_load_buddy() should never fail.
|
|
|
+ */
|
|
|
+ WARN(1, "mb_load_buddy failed (%d)", err);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ ext4_lock_group(ac->ac_sb, ac->ac_f_ex.fe_group);
|
|
|
+ mb_free_blocks(ac->ac_inode, &e4b, ac->ac_f_ex.fe_start,
|
|
|
+ ac->ac_f_ex.fe_len);
|
|
|
+ ext4_unlock_group(ac->ac_sb, ac->ac_f_ex.fe_group);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (pa->pa_type == MB_INODE_PA)
|
|
|
pa->pa_free += ac->ac_b_ex.fe_len;
|
|
|
}
|
|
|
|