[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20230829054309.684530-1-dongyangli@ddn.com>
Date: Tue, 29 Aug 2023 15:43:09 +1000
From: Li Dongyang <dongyangli@....com>
To: linux-ext4@...r.kernel.org
Cc: adilger@...ger.ca, sihara@....com, wangshilong1991@...il.com
Subject: [PATCH V2] e2fsprogs: support EXT2_FLAG_BG_TRIMMED and EXT2_FLAGS_TRACK_TRIM
This adds EXT2_FLAG_BG_TRIMMED, which is set on block group
descriptors during mke2fs after discard is done for that group.
The EXT2_FLAG_BG_TRIMMED flag is cleared on the block group when
we free blocks.
Introduce EXT2_FLAGS_TRACK_TRIM, which is a new super block flag,
to indicate whether we should honour the EXT2_FLAG_BG_TRIMMED
set on each block group.
EXT2_FLAGS_TRACK_TRIM itself can be turned on/off via tune2fs.
Make dumpe2fs aware of the new flags.
Cc: Shuichi Ihara <sihara@....com>
Cc: Andreas Dilger <adilger@...ger.ca>
Cc: Wang Shilong <wangshilong1991@...il.com>
Signed-off-by: Wang Shilong <wshilong@....com>
Signed-off-by: Li Dongyang <dongyangli@....com>
---
v1->v2:
set BG_TRIMMED flag on gd progressively as we discard the groups.
---
lib/e2p/ls.c | 4 ++++
lib/ext2fs/alloc_stats.c | 8 ++++++--
lib/ext2fs/ext2_fs.h | 2 ++
misc/dumpe2fs.c | 2 ++
misc/mke2fs.c | 34 +++++++++++++++++-----------------
misc/tune2fs.8.in | 8 ++++++++
misc/tune2fs.c | 10 ++++++++++
7 files changed, 49 insertions(+), 19 deletions(-)
diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c
index 0b74aea2b..4b356eca6 100644
--- a/lib/e2p/ls.c
+++ b/lib/e2p/ls.c
@@ -162,6 +162,10 @@ static void print_super_flags(struct ext2_super_block * s, FILE *f)
fputs("test_filesystem ", f);
flags_found++;
}
+ if (s->s_flags & EXT2_FLAGS_TRACK_TRIM) {
+ fputs("track_trim ", f);
+ flags_found++;
+ }
if (flags_found)
fputs("\n", f);
else
diff --git a/lib/ext2fs/alloc_stats.c b/lib/ext2fs/alloc_stats.c
index 6f98bcc7c..4e03f92a4 100644
--- a/lib/ext2fs/alloc_stats.c
+++ b/lib/ext2fs/alloc_stats.c
@@ -70,10 +70,12 @@ void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse)
#endif
return;
}
- if (inuse > 0)
+ if (inuse > 0) {
ext2fs_mark_block_bitmap2(fs->block_map, blk);
- else
+ } else {
ext2fs_unmark_block_bitmap2(fs->block_map, blk);
+ ext2fs_bg_flags_clear(fs, group, EXT2_BG_TRIMMED);
+ }
ext2fs_bg_free_blocks_count_set(fs, group, ext2fs_bg_free_blocks_count(fs, group) - inuse);
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
ext2fs_group_desc_csum_set(fs, group);
@@ -139,6 +141,8 @@ void ext2fs_block_alloc_stats_range(ext2_filsys fs, blk64_t blk,
ext2fs_bg_free_blocks_count(fs, group) -
inuse*n/EXT2FS_CLUSTER_RATIO(fs));
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
+ if (inuse < 0)
+ ext2fs_bg_flags_clear(fs, group, EXT2_BG_TRIMMED);
ext2fs_group_desc_csum_set(fs, group);
ext2fs_free_blocks_count_add(fs->super, -inuse * (blk64_t) n);
blk += n;
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 0fc9c09a5..88e1114c9 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -223,6 +223,7 @@ struct ext4_group_desc
#define EXT2_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not initialized */
#define EXT2_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not initialized */
#define EXT2_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */
+#define EXT2_BG_TRIMMED 0x0008 /* Block group was trimmed */
/*
* Data structures used by the directory indexing feature
@@ -563,6 +564,7 @@ struct ext2_inode *EXT2_INODE(struct ext2_inode_large *large_inode)
#define EXT2_FLAGS_SIGNED_HASH 0x0001 /* Signed dirhash in use */
#define EXT2_FLAGS_UNSIGNED_HASH 0x0002 /* Unsigned dirhash in use */
#define EXT2_FLAGS_TEST_FILESYS 0x0004 /* OK for use on development code */
+#define EXT2_FLAGS_TRACK_TRIM 0x0008 /* Track trim status in each bg */
#define EXT2_FLAGS_IS_SNAPSHOT 0x0010 /* This is a snapshot image */
#define EXT2_FLAGS_FIX_SNAPSHOT 0x0020 /* Snapshot inodes corrupted */
#define EXT2_FLAGS_FIX_EXCLUDE 0x0040 /* Exclude bitmaps corrupted */
diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c
index 7c080ed9f..afe569dff 100644
--- a/misc/dumpe2fs.c
+++ b/misc/dumpe2fs.c
@@ -131,6 +131,8 @@ static void print_bg_opts(ext2_filsys fs, dgrp_t i)
&first);
print_bg_opt(bg_flags, EXT2_BG_INODE_ZEROED, "ITABLE_ZEROED",
&first);
+ print_bg_opt(bg_flags, EXT2_BG_TRIMMED, "TRIMMED",
+ &first);
if (!first)
fputc(']', stdout);
fputc('\n', stdout);
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 4a9c1b092..0eff41aad 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -71,8 +71,6 @@ extern int optind;
#define ZAP_BOOTBLOCK
#endif
-#define DISCARD_STEP_MB (2048)
-
extern int isatty(int);
extern FILE *fpopen(const char *cmd, const char *mode);
@@ -2872,9 +2870,7 @@ err:
static int mke2fs_discard_device(ext2_filsys fs)
{
struct ext2fs_numeric_progress_struct progress;
- blk64_t blocks = ext2fs_blocks_count(fs->super);
- blk64_t count = DISCARD_STEP_MB;
- blk64_t cur = 0;
+ dgrp_t group;
int retval = 0;
/*
@@ -2886,22 +2882,26 @@ static int mke2fs_discard_device(ext2_filsys fs)
if (retval)
return retval;
- count *= (1024 * 1024);
- count /= fs->blocksize;
-
ext2fs_numeric_progress_init(fs, &progress,
_("Discarding device blocks: "),
- blocks);
- while (cur < blocks) {
- ext2fs_numeric_progress_update(fs, &progress, cur);
+ ext2fs_blocks_count(fs->super));
- if (cur + count > blocks)
- count = blocks - cur;
+ for (group = 0; group < fs->group_desc_count; group++) {
+ blk64_t start = ext2fs_group_first_block2(fs, group);
+ blk64_t count = ext2fs_group_blocks_count(fs, group);
+ int retval_discard;
- retval = io_channel_discard(fs->io, cur, count);
- if (retval)
- break;
- cur += count;
+ retval_discard = io_channel_discard(fs->io, start, count);
+ if (!retval_discard) {
+ ext2fs_bg_flags_set(fs, group, EXT2_BG_TRIMMED);
+ ext2fs_group_desc_csum_set(fs, group);
+ fs->super->s_flags |= EXT2_FLAGS_TRACK_TRIM;
+ } else if (!retval) {
+ retval = retval_discard;
+ }
+
+ ext2fs_numeric_progress_update(fs, &progress,
+ ext2fs_group_last_block2(fs, group));
}
if (retval) {
diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in
index dcf108c1f..2eb7e88ed 100644
--- a/misc/tune2fs.8.in
+++ b/misc/tune2fs.8.in
@@ -273,6 +273,14 @@ mounted using experimental kernel code, such as the ext4dev file system.
.B ^test_fs
Clear the test_fs flag, indicating the file system should only be mounted
using production-level file system code.
+.TP
+.B track_trim
+Set a flag in the file system superblock to make fstrim save the trim status
+in each block group and skip the block groups already been trimmed.
+.TP
+.B ^track_trim
+Clear the track_trim flag to make fstrim ignore the trim status saved in
+each block group, and trim every block group.
.RE
.TP
.B \-f
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index 458f7cf6a..dd9e8eab0 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -2312,6 +2312,14 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts)
sb->s_flags &= ~EXT2_FLAGS_TEST_FILESYS;
printf("Clearing test filesystem flag\n");
ext2fs_mark_super_dirty(fs);
+ } else if (!strcmp(token, "track_trim")) {
+ sb->s_flags |= EXT2_FLAGS_TRACK_TRIM;
+ printf("Setting track_trim flag\n");
+ ext2fs_mark_super_dirty(fs);
+ } else if (!strcmp(token, "^track_trim")) {
+ sb->s_flags &= ~EXT2_FLAGS_TRACK_TRIM;
+ printf("Clearing track_trim flag\n");
+ ext2fs_mark_super_dirty(fs);
} else if (strcmp(token, "stride") == 0) {
if (!arg) {
r_usage++;
@@ -2458,6 +2466,8 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts)
"\tforce_fsck\n"
"\ttest_fs\n"
"\t^test_fs\n"
+ "\ttrack_trim\n"
+ "\t^track_trim\n"
"\tencoding=<encoding>\n"
"\tencoding_flags=<flags>\n"));
free(buf);
--
2.41.0
Powered by blists - more mailing lists