ext4: add EXT4_MB_HINT_GOAL_ONLY test in ext4_mb_use_preallocated
authorKemeng Shi <shikemeng@huaweicloud.com>
Sat, 3 Jun 2023 15:03:13 +0000 (23:03 +0800)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 15 Jun 2023 04:02:10 +0000 (00:02 -0400)
ext4_mb_use_preallocated will ignore the demand to alloc goal blocks,
although the EXT4_MB_HINT_GOAL_ONLY is requested.
For group pa, ext4_mb_group_or_file will not set EXT4_MB_HINT_GROUP_ALLOC
if EXT4_MB_HINT_GOAL_ONLY is set. So we will not alloc goal blocks from
group pa if EXT4_MB_HINT_GOAL_ONLY is set.
For inode pa, ext4_mb_pa_goal_check is added to check if free extent in
found inode pa meets goal blocks when EXT4_MB_HINT_GOAL_ONLY is set.

Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
Suggested-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Link: https://lore.kernel.org/r/20230603150327.3596033-6-shikemeng@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/mballoc.c

index 7ef95bdde91de01410bcde55dedae75c0aaad671..839db9c46aeae9f2fbef0452393a540f390273ff 100644 (file)
@@ -4531,6 +4531,37 @@ ext4_mb_check_group_pa(ext4_fsblk_t goal_block,
        return pa;
 }
 
+/*
+ * check if found pa meets EXT4_MB_HINT_GOAL_ONLY
+ */
+static bool
+ext4_mb_pa_goal_check(struct ext4_allocation_context *ac,
+                     struct ext4_prealloc_space *pa)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
+       ext4_fsblk_t start;
+
+       if (likely(!(ac->ac_flags & EXT4_MB_HINT_GOAL_ONLY)))
+               return true;
+
+       /*
+        * If EXT4_MB_HINT_GOAL_ONLY is set, ac_g_ex will not be adjusted
+        * in ext4_mb_normalize_request and will keep same with ac_o_ex
+        * from ext4_mb_initialize_context. Choose ac_g_ex here to keep
+        * consistent with ext4_mb_find_by_goal.
+        */
+       start = pa->pa_pstart +
+               (ac->ac_g_ex.fe_logical - pa->pa_lstart);
+       if (ext4_grp_offs_to_block(ac->ac_sb, &ac->ac_g_ex) != start)
+               return false;
+
+       if (ac->ac_g_ex.fe_len > pa->pa_len -
+           EXT4_B2C(sbi, ac->ac_g_ex.fe_logical - pa->pa_lstart))
+               return false;
+
+       return true;
+}
+
 /*
  * search goal blocks in preallocated space
  */
@@ -4581,7 +4612,8 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
 
                /* found preallocated blocks, use them */
                spin_lock(&tmp_pa->pa_lock);
-               if (tmp_pa->pa_deleted == 0 && tmp_pa->pa_free) {
+               if (tmp_pa->pa_deleted == 0 && tmp_pa->pa_free &&
+                   likely(ext4_mb_pa_goal_check(ac, tmp_pa))) {
                        atomic_inc(&tmp_pa->pa_count);
                        ext4_mb_use_inode_pa(ac, tmp_pa);
                        spin_unlock(&tmp_pa->pa_lock);