|
@@ -2011,7 +2011,12 @@ void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* This is now called BEFORE we load the buddy bitmap. */
|
|
|
+/*
|
|
|
+ * This is now called BEFORE we load the buddy bitmap.
|
|
|
+ * Returns either 1 or 0 indicating that the group is either suitable
|
|
|
+ * for the allocation or not. In addition it can also return negative
|
|
|
+ * error code when something goes wrong.
|
|
|
+ */
|
|
|
static int ext4_mb_good_group(struct ext4_allocation_context *ac,
|
|
|
ext4_group_t group, int cr)
|
|
|
{
|
|
@@ -2034,7 +2039,7 @@ static int ext4_mb_good_group(struct ext4_allocation_context *ac,
|
|
|
if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
|
|
|
int ret = ext4_mb_init_group(ac->ac_sb, group);
|
|
|
if (ret)
|
|
|
- return 0;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
fragments = grp->bb_fragments;
|
|
@@ -2081,7 +2086,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
|
|
|
{
|
|
|
ext4_group_t ngroups, group, i;
|
|
|
int cr;
|
|
|
- int err = 0;
|
|
|
+ int err = 0, first_err = 0;
|
|
|
struct ext4_sb_info *sbi;
|
|
|
struct super_block *sb;
|
|
|
struct ext4_buddy e4b;
|
|
@@ -2148,6 +2153,7 @@ repeat:
|
|
|
group = ac->ac_g_ex.fe_group;
|
|
|
|
|
|
for (i = 0; i < ngroups; group++, i++) {
|
|
|
+ int ret = 0;
|
|
|
cond_resched();
|
|
|
/*
|
|
|
* Artificially restricted ngroups for non-extent
|
|
@@ -2157,8 +2163,12 @@ repeat:
|
|
|
group = 0;
|
|
|
|
|
|
/* This now checks without needing the buddy page */
|
|
|
- if (!ext4_mb_good_group(ac, group, cr))
|
|
|
+ ret = ext4_mb_good_group(ac, group, cr);
|
|
|
+ if (ret <= 0) {
|
|
|
+ if (!first_err)
|
|
|
+ first_err = ret;
|
|
|
continue;
|
|
|
+ }
|
|
|
|
|
|
err = ext4_mb_load_buddy(sb, group, &e4b);
|
|
|
if (err)
|
|
@@ -2170,9 +2180,12 @@ repeat:
|
|
|
* We need to check again after locking the
|
|
|
* block group
|
|
|
*/
|
|
|
- if (!ext4_mb_good_group(ac, group, cr)) {
|
|
|
+ ret = ext4_mb_good_group(ac, group, cr);
|
|
|
+ if (ret <= 0) {
|
|
|
ext4_unlock_group(sb, group);
|
|
|
ext4_mb_unload_buddy(&e4b);
|
|
|
+ if (!first_err)
|
|
|
+ first_err = ret;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
@@ -2219,6 +2232,8 @@ repeat:
|
|
|
}
|
|
|
}
|
|
|
out:
|
|
|
+ if (!err && ac->ac_status != AC_STATUS_FOUND && first_err)
|
|
|
+ err = first_err;
|
|
|
return err;
|
|
|
}
|
|
|
|