Whamcloud - gitweb
LU-14712 ldiskfs: keep EXT4_BG_TRIMMED flag in memory 12/59312/7
authorLi Dongyang <dongyangli@ddn.com>
Fri, 23 May 2025 10:05:47 +0000 (20:05 +1000)
committerOleg Drokin <green@whamcloud.com>
Thu, 12 Jun 2025 06:36:12 +0000 (06:36 +0000)
Keep the EXT4_BG_TRIMMED flag in memory for the trimmed block groups
so that the filesystem without track_trim superblock bit(e.g. existing
filesystem created with earlier version of e2fsprogs) can still
skip trimmed block groups during fstrim as long as it's mounted.

For persistent trimmed block group tracking we should turn on track_trim
with tune2fs.

Change-Id: I19df047c717d3b20310fcba7fa682b6dfab9d5e4
Signed-off-by: Li Dongyang <dongyangli@ddn.com>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/59312
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
ldiskfs/kernel_patches/patches/rhel7.9/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch
ldiskfs/kernel_patches/patches/rhel8.7/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch
ldiskfs/kernel_patches/patches/rhel9.4/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch
ldiskfs/kernel_patches/patches/rhel9/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch

index 227cf06..c481bdc 100644 (file)
@@ -177,14 +177,17 @@ Index: linux-3.10.0-1160.88.1.el7/fs/ext4/mballoc.c
        ext4_group_desc_csum_set(sb, block_group, gdp);
        ext4_unlock_group(sb, block_group);
  
-@@ -5676,9 +5685,16 @@ ext4_trim_all_free(struct super_block *s
+@@ -5676,9 +5685,19 @@ ext4_trim_all_free(struct super_block *s
        void *bitmap;
        ext4_grpblk_t next, count = 0, free_count = 0;
        struct ext4_buddy e4b;
 +      struct ext4_super_block *es = EXT4_SB(sb)->s_es;
 +      struct ext4_group_desc *gdp;
++      struct ext4_group_info *grp = ext4_get_group_info(sb, group);
 +      struct buffer_head *gd_bh;
 +      ext4_grpblk_t freed_last_trimmed_orig;
++      bool track_trim = (es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM)) &&
++                        !(sb->s_flags & MS_RDONLY);
        int ret = 0;
  
        trace_ext4_trim_all_free(sb, group, start, max);
@@ -194,21 +197,20 @@ Index: linux-3.10.0-1160.88.1.el7/fs/ext4/mballoc.c
  
        ret = ext4_mb_load_buddy(sb, group, &e4b);
        if (ret)
-@@ -5682,10 +5700,12 @@ ext4_trim_all_free(struct super_block *s
+@@ -5687,10 +5705,11 @@ ext4_trim_all_free(struct super_block *s
        bitmap = e4b.bd_bitmap;
  
        ext4_lock_group(sb, group);
 -      if (EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) &&
-+      if (es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM) &&
-+          gdp->bg_flags & cpu_to_le16(EXT4_BG_TRIMMED) &&
++      if (gdp->bg_flags & cpu_to_le16(EXT4_BG_TRIMMED) &&
            minblocks >= atomic_read(&EXT4_SB(sb)->s_last_trim_minblks))
                goto out;
  
-+      freed_last_trimmed_orig = e4b.bd_info->bb_freed_since_trim;
++      freed_last_trimmed_orig = grp->bb_freed_since_trim;
        start = (e4b.bd_info->bb_first_free > start) ?
                e4b.bd_info->bb_first_free : start;
  
-@@ -5721,14 +5741,46 @@ ext4_trim_all_free(struct super_block *s
+@@ -5726,14 +5745,54 @@ ext4_trim_all_free(struct super_block *s
                        break;
        }
  
@@ -220,40 +222,48 @@ Index: linux-3.10.0-1160.88.1.el7/fs/ext4/mballoc.c
  out:
        ext4_unlock_group(sb, group);
        ext4_mb_unload_buddy(&e4b);
-+      if (ret > 0 && es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM)) {
++      if (ret > 0) {
++              handle_t *handle = NULL;
 +              int err;
-+              handle_t *handle;
 +
-+              handle = ext4_journal_start_sb(sb, EXT4_HT_FS_TRIM, 1);
-+              if (IS_ERR(handle)) {
-+                      ret = PTR_ERR(handle);
-+                      goto out_return;
-+              }
-+              err = ext4_journal_get_write_access(handle, gd_bh);
-+              if (err) {
-+                      ret = err;
-+                      goto out_journal;
++              if (track_trim) {
++                      handle = ext4_journal_start_sb(sb, EXT4_HT_FS_TRIM, 1);
++                      if (IS_ERR(handle)) {
++                              ret = PTR_ERR(handle);
++                              goto out_return;
++                      }
++                      err = ext4_journal_get_write_access(handle, gd_bh);
++                      if (err) {
++                              ret = err;
++                              goto out_journal;
++                      }
 +              }
++
 +              ext4_lock_group(sb, group);
 +              /* someone freed blocks while we were working on the group */
-+              if (freed_last_trimmed_orig !=
-+                      e4b.bd_info->bb_freed_since_trim) {
++              if (freed_last_trimmed_orig != grp->bb_freed_since_trim) {
 +                      ext4_unlock_group(sb, group);
 +                      goto out_journal;
 +              }
 +              gdp->bg_flags |= cpu_to_le16(EXT4_BG_TRIMMED);
-+              e4b.bd_info->bb_freed_since_trim = 0;
++              grp->bb_freed_since_trim = 0;
 +              ext4_group_desc_csum_set(sb, group, gdp);
 +              ext4_unlock_group(sb, group);
-+              err = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
-+              if (err)
-+                      ret = err;
++
++              if (track_trim) {
++                      err = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
++                      if (err)
++                              ret = err;
++              }
 +out_journal:
-+              err = ext4_journal_stop(handle);
-+              if (err)
-+                      ret = err;
++              if (track_trim) {
++                      err = ext4_journal_stop(handle);
++                      if (err)
++                              ret = err;
++              }
 +      }
++
 +out_return:
        ext4_debug("trimmed %d blocks in the group %d\n",
                count, group);
@@ -262,7 +272,18 @@ Index: linux-3.10.0-1160.88.1.el7/fs/ext4/super.c
 ===================================================================
 --- linux-3.10.0-1160.88.1.el7.orig/fs/ext4/super.c
 +++ linux-3.10.0-1160.88.1.el7/fs/ext4/super.c
-@@ -2936,6 +2936,7 @@ EXT4_RW_ATTR_SBI_UI(mb_prefetch, s_mb_pr
+@@ -2295,6 +2295,10 @@ static int ext4_check_descriptors(struct
+                               return 0;
+                       }
+               }
++              if (!(sbi->s_es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM))) {
++                      gdp->bg_flags &= cpu_to_le16(~EXT4_BG_TRIMMED);
++                      ext4_group_desc_csum_set(sb, i, gdp);
++              }
+               ext4_unlock_group(sb, i);
+               if (!flexbg_flag)
+                       first_block += EXT4_BLOCKS_PER_GROUP(sb);
+@@ -2936,6 +2940,7 @@ EXT4_RW_ATTR_SBI_UI(mb_prefetch, s_mb_pr
  EXT4_RW_ATTR_SBI_UI(mb_prefetch_limit, s_mb_prefetch_limit);
  EXT4_DEPRECATED_ATTR(max_writeback_mb_bump, 128);
  EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb);
index 83fcfd6..2c12c78 100644 (file)
@@ -177,14 +177,17 @@ Index: linux-4.18.0-425.10.1.el8_7/fs/ext4/mballoc.c
        ext4_group_desc_csum_set(sb, block_group, gdp);
        ext4_unlock_group(sb, block_group);
  
-@@ -5889,9 +5898,16 @@ ext4_trim_all_free(struct super_block *s
+@@ -5889,9 +5898,19 @@ ext4_trim_all_free(struct super_block *s
        void *bitmap;
        ext4_grpblk_t next, count = 0, free_count = 0;
        struct ext4_buddy e4b;
 +      struct ext4_super_block *es = EXT4_SB(sb)->s_es;
 +      struct ext4_group_desc *gdp;
++      struct ext4_group_info *grp = ext4_get_group_info(sb, group);
 +      struct buffer_head *gd_bh;
 +      ext4_grpblk_t freed_last_trimmed_orig;
++      bool track_trim = (es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM)) &&
++                        !sb_rdonly(sb);
        int ret = 0;
  
        trace_ext4_trim_all_free(sb, group, start, max);
@@ -194,21 +197,20 @@ Index: linux-4.18.0-425.10.1.el8_7/fs/ext4/mballoc.c
  
        ret = ext4_mb_load_buddy(sb, group, &e4b);
        if (ret)
-@@ -5899,10 +5915,12 @@ ext4_trim_all_free(struct super_block *s
+@@ -5899,10 +5917,11 @@ ext4_trim_all_free(struct super_block *s
        bitmap = e4b.bd_bitmap;
  
        ext4_lock_group(sb, group);
 -      if (EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) &&
-+      if (es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM) &&
-+          gdp->bg_flags & cpu_to_le16(EXT4_BG_TRIMMED) &&
++      if (gdp->bg_flags & cpu_to_le16(EXT4_BG_TRIMMED) &&
            minblocks >= atomic_read(&EXT4_SB(sb)->s_last_trim_minblks))
                goto out;
  
-+      freed_last_trimmed_orig = e4b.bd_info->bb_freed_since_trim;
++      freed_last_trimmed_orig = grp->bb_freed_since_trim;
        start = (e4b.bd_info->bb_first_free > start) ?
                e4b.bd_info->bb_first_free : start;
  
-@@ -5938,14 +5956,46 @@ ext4_trim_all_free(struct super_block *s
+@@ -5938,14 +5957,54 @@ ext4_trim_all_free(struct super_block *s
                        break;
        }
  
@@ -220,40 +222,48 @@ Index: linux-4.18.0-425.10.1.el8_7/fs/ext4/mballoc.c
  out:
        ext4_unlock_group(sb, group);
        ext4_mb_unload_buddy(&e4b);
-+      if (ret > 0 && es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM)) {
++      if (ret > 0) {
++              handle_t *handle = NULL;
 +              int err;
-+              handle_t *handle;
 +
-+              handle = ext4_journal_start_sb(sb, EXT4_HT_FS_TRIM, 1);
-+              if (IS_ERR(handle)) {
-+                      ret = PTR_ERR(handle);
-+                      goto out_return;
-+              }
-+              err = ext4_journal_get_write_access(handle, gd_bh);
-+              if (err) {
-+                      ret = err;
-+                      goto out_journal;
++              if (track_trim) {
++                      handle = ext4_journal_start_sb(sb, EXT4_HT_FS_TRIM, 1);
++                      if (IS_ERR(handle)) {
++                              ret = PTR_ERR(handle);
++                              goto out_return;
++                      }
++                      err = ext4_journal_get_write_access(handle, gd_bh);
++                      if (err) {
++                              ret = err;
++                              goto out_journal;
++                      }
 +              }
++
 +              ext4_lock_group(sb, group);
 +              /* someone freed blocks while we were working on the group */
-+              if (freed_last_trimmed_orig !=
-+                      e4b.bd_info->bb_freed_since_trim) {
++              if (freed_last_trimmed_orig != grp->bb_freed_since_trim) {
 +                      ext4_unlock_group(sb, group);
 +                      goto out_journal;
 +              }
 +              gdp->bg_flags |= cpu_to_le16(EXT4_BG_TRIMMED);
-+              e4b.bd_info->bb_freed_since_trim = 0;
++              grp->bb_freed_since_trim = 0;
 +              ext4_group_desc_csum_set(sb, group, gdp);
 +              ext4_unlock_group(sb, group);
-+              err = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
-+              if (err)
-+                      ret = err;
++
++              if (track_trim) {
++                      err = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
++                      if (err)
++                              ret = err;
++              }
 +out_journal:
-+              err = ext4_journal_stop(handle);
-+              if (err)
-+                      ret = err;
++              if (track_trim) {
++                      err = ext4_journal_stop(handle);
++                      if (err)
++                              ret = err;
++              }
 +      }
++
 +out_return:
        ext4_debug("trimmed %d blocks in the group %d\n",
                count, group);
@@ -278,3 +288,18 @@ Index: linux-4.18.0-425.10.1.el8_7/fs/ext4/sysfs.c
        ATTR_LIST(trigger_fs_error),
        ATTR_LIST(err_ratelimit_interval_ms),
        ATTR_LIST(err_ratelimit_burst),
+Index: linux-4.18.0-425.10.1.el8_7/fs/ext4/super.c
+===================================================================
+--- linux-4.18.0-425.10.1.el8_7.orig/fs/ext4/super.c
++++ linux-4.18.0-425.10.1.el8_7/fs/ext4/super.c
+@@ -2703,6 +2703,10 @@ static int ext4_check_descriptors(struct
+                               return 0;
+                       }
+               }
++              if (!(sbi->s_es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM))) {
++                      gdp->bg_flags &= cpu_to_le16(~EXT4_BG_TRIMMED);
++                      ext4_group_desc_csum_set(sb, i, gdp);
++              }
+               ext4_unlock_group(sb, i);
+               if (!flexbg_flag)
+                       first_block += EXT4_BLOCKS_PER_GROUP(sb);
index 54bbeef..290de2a 100644 (file)
@@ -177,19 +177,22 @@ Index: linux-5.14.0-427.20.1.el9.x86_64/fs/ext4/mballoc.c
 +      }
        ext4_group_desc_csum_set(sb, block_group, gdp);
        ext4_unlock_group(sb, block_group);
-
-@@ -7024,10 +7033,18 @@ ext4_trim_all_free(struct super_block *s
+@@ -7024,10 +7033,21 @@ ext4_trim_all_free(struct super_block *s
                   ext4_grpblk_t minblocks, bool set_trimmed)
  {
        struct ext4_buddy e4b;
 +      struct ext4_super_block *es = EXT4_SB(sb)->s_es;
 +      struct ext4_group_desc *gdp;
++      struct ext4_group_info *grp = ext4_get_group_info(sb, group);
 +      struct buffer_head *gd_bh;
 +      ext4_grpblk_t freed_last_trimmed_orig;
++      bool track_trim = (es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM)) &&
++                        !sb_rdonly(sb);
        int ret;
-
        trace_ext4_trim_all_free(sb, group, start, max);
-
 +      gdp = ext4_get_group_desc(sb, group, &gd_bh);
 +      if (!gdp)
 +              return -EIO;
@@ -197,15 +200,14 @@ Index: linux-5.14.0-427.20.1.el9.x86_64/fs/ext4/mballoc.c
        ret = ext4_mb_load_buddy(sb, group, &e4b);
        if (ret) {
                return ret;
-@@ -7035,11 +7052,12 @@ ext4_trim_all_free(struct super_block *s
-
+@@ -7035,11 +7054,11 @@ ext4_trim_all_free(struct super_block *s
        ext4_lock_group(sb, group);
-
 -      if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) ||
-+      freed_last_trimmed_orig = e4b.bd_info->bb_freed_since_trim;
++      freed_last_trimmed_orig = grp->bb_freed_since_trim;
 +
-+      if (!(es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM) &&
-+            gdp->bg_flags & cpu_to_le16(EXT4_BG_TRIMMED)) ||
++      if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_TRIMMED)) ||
            minblocks < EXT4_SB(sb)->s_last_trim_minblks) {
                ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks);
 -              if (ret >= 0 && set_trimmed)
@@ -213,45 +215,52 @@ Index: linux-5.14.0-427.20.1.el9.x86_64/fs/ext4/mballoc.c
        } else {
                ret = 0;
        }
-@@ -7047,6 +7065,42 @@ ext4_trim_all_free(struct super_block *s
+@@ -7047,6 +7066,49 @@ ext4_trim_all_free(struct super_block *s
        ext4_unlock_group(sb, group);
        ext4_mb_unload_buddy(&e4b);
-
-+      if (ret > 0 && set_trimmed &&
-+          es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM)) {
++      if (ret > 0 && set_trimmed) {
++              handle_t *handle = NULL;
 +              int err;
-+              handle_t *handle;
 +
-+              handle = ext4_journal_start_sb(sb, EXT4_HT_FS_TRIM, 1);
-+              if (IS_ERR(handle)) {
-+                      ret = PTR_ERR(handle);
-+                      goto out_return;
-+              }
-+              err = ext4_journal_get_write_access(handle, sb, gd_bh,
-+                                                  EXT4_JTR_NONE);
-+              if (err) {
-+                      ret = err;
-+                      goto out_journal;
++              if (track_trim) {
++                      handle = ext4_journal_start_sb(sb, EXT4_HT_FS_TRIM, 1);
++                      if (IS_ERR(handle)) {
++                              ret = PTR_ERR(handle);
++                              goto out_return;
++                      }
++                      err = ext4_journal_get_write_access(handle, sb, gd_bh,
++                                                          EXT4_JTR_NONE);
++                      if (err) {
++                              ret = err;
++                              goto out_journal;
++                      }
 +              }
++
 +              ext4_lock_group(sb, group);
 +              /* someone freed blocks while we were working on the group */
-+              if (freed_last_trimmed_orig !=
-+                  e4b.bd_info->bb_freed_since_trim) {
++              if (freed_last_trimmed_orig != grp->bb_freed_since_trim) {
 +                      ext4_unlock_group(sb, group);
 +                      goto out_journal;
 +              }
 +              gdp->bg_flags |= cpu_to_le16(EXT4_BG_TRIMMED);
-+              e4b.bd_info->bb_freed_since_trim = 0;
++              grp->bb_freed_since_trim = 0;
 +              ext4_group_desc_csum_set(sb, group, gdp);
 +              ext4_unlock_group(sb, group);
-+              err = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
-+              if (err)
-+                      ret = err;
++
++              if (track_trim) {
++                      err = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
++                      if (err)
++                              ret = err;
++              }
 +out_journal:
-+              err = ext4_journal_stop(handle);
-+              if (err)
-+                      ret = err;
++              if (track_trim) {
++                      err = ext4_journal_stop(handle);
++                      if (err)
++                              ret = err;
++              }
 +      }
++
 +out_return:
        ext4_debug("trimmed %d blocks in the group %d\n",
                ret, group);
@@ -276,3 +285,18 @@ Index: linux-5.14.0-162.23.1.el9_1/fs/ext4/sysfs.c
        ATTR_LIST(trigger_fs_error),
        ATTR_LIST(err_ratelimit_interval_ms),
        ATTR_LIST(err_ratelimit_burst),
+Index: linux-5.14.0-427.20.1.el9_4/fs/ext4/super.c
+===================================================================
+--- linux-5.14.0-427.20.1.el9_4.orig/fs/ext4/super.c
++++ linux-5.14.0-427.20.1.el9_4/fs/ext4/super.c
+@@ -3354,6 +3354,10 @@ static int ext4_check_descriptors(struct
+                               return 0;
+                       }
+               }
++              if (!(sbi->s_es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM))) {
++                      gdp->bg_flags &= cpu_to_le16(~EXT4_BG_TRIMMED);
++                      ext4_group_desc_csum_set(sb, i, gdp);
++              }
+               ext4_unlock_group(sb, i);
+               if (!flexbg_flag)
+                       first_block += EXT4_BLOCKS_PER_GROUP(sb);
index d3a4a37..b73b970 100644 (file)
@@ -178,14 +178,17 @@ Index: linux-5.14.0-162.23.1.el9_1/fs/ext4/mballoc.c
        ext4_group_desc_csum_set(sb, block_group, gdp);
        ext4_unlock_group(sb, block_group);
  
-@@ -6692,10 +6701,18 @@ ext4_trim_all_free(struct super_block *s
+@@ -6692,10 +6701,21 @@ ext4_trim_all_free(struct super_block *s
                   ext4_grpblk_t minblocks, bool set_trimmed)
  {
        struct ext4_buddy e4b;
 +      struct ext4_super_block *es = EXT4_SB(sb)->s_es;
 +      struct ext4_group_desc *gdp;
++      struct ext4_group_info *grp = ext4_get_group_info(sb, group);
 +      struct buffer_head *gd_bh;
 +      ext4_grpblk_t freed_last_trimmed_orig;
++      bool track_trim = (es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM)) &&
++                        !sb_rdonly(sb);
        int ret;
  
        trace_ext4_trim_all_free(sb, group, start, max);
@@ -197,15 +200,14 @@ Index: linux-5.14.0-162.23.1.el9_1/fs/ext4/mballoc.c
        ret = ext4_mb_load_buddy(sb, group, &e4b);
        if (ret) {
                return ret;
-@@ -6703,11 +6720,12 @@ ext4_trim_all_free(struct super_block *s
+@@ -6703,11 +6722,11 @@ ext4_trim_all_free(struct super_block *s
  
        ext4_lock_group(sb, group);
  
 -      if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) ||
-+      freed_last_trimmed_orig = e4b.bd_info->bb_freed_since_trim;
++      freed_last_trimmed_orig = grp->bb_freed_since_trim;
 +
-+      if (!(es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM) &&
-+            gdp->bg_flags & cpu_to_le16(EXT4_BG_TRIMMED)) ||
++      if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_TRIMMED)) ||
            minblocks < EXT4_SB(sb)->s_last_trim_minblks) {
                ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks);
 -              if (ret >= 0 && set_trimmed)
@@ -213,45 +215,52 @@ Index: linux-5.14.0-162.23.1.el9_1/fs/ext4/mballoc.c
        } else {
                ret = 0;
        }
-@@ -6715,6 +6733,42 @@ ext4_trim_all_free(struct super_block *s
+@@ -6715,6 +6734,49 @@ ext4_trim_all_free(struct super_block *s
        ext4_unlock_group(sb, group);
        ext4_mb_unload_buddy(&e4b);
  
-+      if (ret > 0 && set_trimmed &&
-+          es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM)) {
++      if (ret > 0 && set_trimmed) {
++              handle_t *handle = NULL;
 +              int err;
-+              handle_t *handle;
 +
-+              handle = ext4_journal_start_sb(sb, EXT4_HT_FS_TRIM, 1);
-+              if (IS_ERR(handle)) {
-+                      ret = PTR_ERR(handle);
-+                      goto out_return;
-+              }
-+              err = ext4_journal_get_write_access(handle, sb, gd_bh,
-+                                                  EXT4_JTR_NONE);
-+              if (err) {
-+                      ret = err;
-+                      goto out_journal;
++              if (track_trim) {
++                      handle = ext4_journal_start_sb(sb, EXT4_HT_FS_TRIM, 1);
++                      if (IS_ERR(handle)) {
++                              ret = PTR_ERR(handle);
++                              goto out_return;
++                      }
++                      err = ext4_journal_get_write_access(handle, sb, gd_bh,
++                                                          EXT4_JTR_NONE);
++                      if (err) {
++                              ret = err;
++                              goto out_journal;
++                      }
 +              }
++
 +              ext4_lock_group(sb, group);
 +              /* someone freed blocks while we were working on the group */
-+              if (freed_last_trimmed_orig !=
-+                  e4b.bd_info->bb_freed_since_trim) {
++              if (freed_last_trimmed_orig != grp->bb_freed_since_trim) {
 +                      ext4_unlock_group(sb, group);
 +                      goto out_journal;
 +              }
 +              gdp->bg_flags |= cpu_to_le16(EXT4_BG_TRIMMED);
-+              e4b.bd_info->bb_freed_since_trim = 0;
++              grp->bb_freed_since_trim = 0;
 +              ext4_group_desc_csum_set(sb, group, gdp);
 +              ext4_unlock_group(sb, group);
-+              err = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
-+              if (err)
-+                      ret = err;
++
++              if (track_trim) {
++                      err = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
++                      if (err)
++                              ret = err;
++              }
 +out_journal:
-+              err = ext4_journal_stop(handle);
-+              if (err)
-+                      ret = err;
++              if (track_trim) {
++                      err = ext4_journal_stop(handle);
++                      if (err)
++                              ret = err;
++              }
 +      }
++
 +out_return:
        ext4_debug("trimmed %d blocks in the group %d\n",
                ret, group);
@@ -276,3 +285,18 @@ Index: linux-5.14.0-162.23.1.el9_1/fs/ext4/sysfs.c
        ATTR_LIST(trigger_fs_error),
        ATTR_LIST(err_ratelimit_interval_ms),
        ATTR_LIST(err_ratelimit_burst),
+Index: linux-5.14.0-162.23.1.el9_1/fs/ext4/super.c
+===================================================================
+--- linux-5.14.0-162.23.1.el9_1.orig/fs/ext4/super.c
++++ linux-5.14.0-162.23.1.el9_1/fs/ext4/super.c
+@@ -3467,6 +3467,10 @@ static int ext4_check_descriptors(struct
+                               return 0;
+                       }
+               }
++              if (!(sbi->s_es->s_flags & cpu_to_le32(EXT2_FLAGS_TRACK_TRIM))) {
++                      gdp->bg_flags &= cpu_to_le16(~EXT4_BG_TRIMMED);
++                      ext4_group_desc_csum_set(sb, i, gdp);
++              }
+               ext4_unlock_group(sb, i);
+               if (!flexbg_flag)
+                       first_block += EXT4_BLOCKS_PER_GROUP(sb);