]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ext4: factor out ext4_mb_scan_group()
authorBaokun Li <libaokun1@huawei.com>
Mon, 14 Jul 2025 13:03:24 +0000 (21:03 +0800)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 25 Jul 2025 13:14:17 +0000 (09:14 -0400)
Extract ext4_mb_scan_group() to make the code clearer and to
prepare for the later conversion of 'choose group' to 'scan groups'.
No functional changes.

Signed-off-by: Baokun Li <libaokun1@huawei.com>
Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
Link: https://patch.msgid.link/20250714130327.1830534-15-libaokun1@huawei.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/mballoc.c
fs/ext4/mballoc.h

index 52ec59f58c363a2a2b93e190a03bc64ff78a7a35..0c3cbc7e2e85472e2b1cf830d80394a7e9bd94ac 100644 (file)
@@ -2845,12 +2845,56 @@ void ext4_mb_prefetch_fini(struct super_block *sb, ext4_group_t group,
        }
 }
 
+static int ext4_mb_scan_group(struct ext4_allocation_context *ac,
+                             ext4_group_t group)
+{
+       int ret;
+       struct super_block *sb = ac->ac_sb;
+       enum criteria cr = ac->ac_criteria;
+
+       ext4_mb_might_prefetch(ac, group);
+
+       /* prevent unnecessary buddy loading. */
+       if (cr < CR_ANY_FREE && spin_is_locked(ext4_group_lock_ptr(sb, group)))
+               return 0;
+
+       /* This now checks without needing the buddy page */
+       ret = ext4_mb_good_group_nolock(ac, group, cr);
+       if (ret <= 0) {
+               if (!ac->ac_first_err)
+                       ac->ac_first_err = ret;
+               return 0;
+       }
+
+       ret = ext4_mb_load_buddy(sb, group, ac->ac_e4b);
+       if (ret)
+               return ret;
+
+       /* skip busy group */
+       if (cr >= CR_ANY_FREE)
+               ext4_lock_group(sb, group);
+       else if (!ext4_try_lock_group(sb, group))
+               goto out_unload;
+
+       /* We need to check again after locking the block group. */
+       if (unlikely(!ext4_mb_good_group(ac, group, cr)))
+               goto out_unlock;
+
+       __ext4_mb_scan_group(ac);
+
+out_unlock:
+       ext4_unlock_group(sb, group);
+out_unload:
+       ext4_mb_unload_buddy(ac->ac_e4b);
+       return ret;
+}
+
 static noinline_for_stack int
 ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
 {
        ext4_group_t ngroups, group, i;
        enum criteria new_cr, cr = CR_GOAL_LEN_FAST;
-       int err = 0, first_err = 0;
+       int err = 0;
        struct ext4_sb_info *sbi;
        struct super_block *sb;
        struct ext4_buddy e4b;
@@ -2912,6 +2956,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
 
        ac->ac_e4b = &e4b;
        ac->ac_prefetch_ios = 0;
+       ac->ac_first_err = 0;
 repeat:
        for (; cr < EXT4_MB_NUM_CRS && ac->ac_status == AC_STATUS_CONTINUE; cr++) {
                ac->ac_criteria = cr;
@@ -2926,7 +2971,6 @@ repeat:
 
                for (i = 0, new_cr = cr; i < ngroups; i++,
                     ext4_mb_choose_next_group(ac, &new_cr, &group, ngroups)) {
-                       int ret = 0;
 
                        cond_resched();
                        if (new_cr != cr) {
@@ -2934,49 +2978,10 @@ repeat:
                                goto repeat;
                        }
 
-                       ext4_mb_might_prefetch(ac, group);
-
-                       /* prevent unnecessary buddy loading. */
-                       if (cr < CR_ANY_FREE &&
-                           spin_is_locked(ext4_group_lock_ptr(sb, group)))
-                               continue;
-
-                       /* This now checks without needing the buddy page */
-                       ret = ext4_mb_good_group_nolock(ac, group, cr);
-                       if (ret <= 0) {
-                               if (!first_err)
-                                       first_err = ret;
-                               continue;
-                       }
-
-                       err = ext4_mb_load_buddy(sb, group, &e4b);
+                       err = ext4_mb_scan_group(ac, group);
                        if (err)
                                goto out;
 
-                       /* skip busy group */
-                       if (cr >= CR_ANY_FREE) {
-                               ext4_lock_group(sb, group);
-                       } else if (!ext4_try_lock_group(sb, group)) {
-                               ext4_mb_unload_buddy(&e4b);
-                               continue;
-                       }
-
-                       /*
-                        * We need to check again after locking the
-                        * block group
-                        */
-                       ret = ext4_mb_good_group(ac, group, cr);
-                       if (ret == 0) {
-                               ext4_unlock_group(sb, group);
-                               ext4_mb_unload_buddy(&e4b);
-                               continue;
-                       }
-
-                       __ext4_mb_scan_group(ac);
-
-                       ext4_unlock_group(sb, group);
-                       ext4_mb_unload_buddy(&e4b);
-
                        if (ac->ac_status != AC_STATUS_CONTINUE)
                                break;
                }
@@ -3025,8 +3030,8 @@ repeat:
                        atomic_inc(&sbi->s_bal_stream_goals);
        }
 out:
-       if (!err && ac->ac_status != AC_STATUS_FOUND && first_err)
-               err = first_err;
+       if (!err && ac->ac_status != AC_STATUS_FOUND && ac->ac_first_err)
+               err = ac->ac_first_err;
 
        mb_debug(sb, "Best len %d, origin len %d, ac_status %u, ac_flags 0x%x, cr %d ret %d\n",
                 ac->ac_b_ex.fe_len, ac->ac_o_ex.fe_len, ac->ac_status,
index 9f66b1d5db67a840d38db2dd3f8db821dc631bbc..83886fc9521b71e1f352d3785a867ecfa706f9c4 100644 (file)
@@ -196,6 +196,8 @@ struct ext4_allocation_context {
        unsigned int ac_prefetch_ios;
        unsigned int ac_prefetch_nr;
 
+       int ac_first_err;
+
        __u32 ac_flags;         /* allocation hints */
        __u32 ac_groups_linear_remaining;
        __u16 ac_groups_scanned;