From: Li Dongyang Date: Fri, 23 May 2025 10:05:47 +0000 (+1000) Subject: LU-14712 ldiskfs: keep EXT4_BG_TRIMMED flag in memory X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=ebb7c944a0115852fdcb0b32b078aed28292b054;p=fs%2Flustre-release.git LU-14712 ldiskfs: keep EXT4_BG_TRIMMED flag in memory 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 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/59312 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin --- diff --git a/ldiskfs/kernel_patches/patches/rhel7.9/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch b/ldiskfs/kernel_patches/patches/rhel7.9/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch index 227cf06..c481bdc 100644 --- a/ldiskfs/kernel_patches/patches/rhel7.9/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch +++ b/ldiskfs/kernel_patches/patches/rhel7.9/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch @@ -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); diff --git a/ldiskfs/kernel_patches/patches/rhel8.7/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch b/ldiskfs/kernel_patches/patches/rhel8.7/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch index 83fcfd6..2c12c78 100644 --- a/ldiskfs/kernel_patches/patches/rhel8.7/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch +++ b/ldiskfs/kernel_patches/patches/rhel8.7/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch @@ -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); diff --git a/ldiskfs/kernel_patches/patches/rhel9.4/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch b/ldiskfs/kernel_patches/patches/rhel9.4/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch index 54bbeef..290de2a 100644 --- a/ldiskfs/kernel_patches/patches/rhel9.4/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch +++ b/ldiskfs/kernel_patches/patches/rhel9.4/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch @@ -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); diff --git a/ldiskfs/kernel_patches/patches/rhel9/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch b/ldiskfs/kernel_patches/patches/rhel9/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch index d3a4a37..b73b970 100644 --- a/ldiskfs/kernel_patches/patches/rhel9/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch +++ b/ldiskfs/kernel_patches/patches/rhel9/ext4-introduce-EXT4_BG_TRIMMED-to-optimize-fstrim.patch @@ -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);