fs/ext4/mballoc.c | 2 +- fs/ext4/mballoc.h | 3 +++ fs/ext4/sysfs.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-)
This is used for userspace to decide whether
system should perform trimming at a proper time.
Signed-off-by: shisiyuan <shisiyuan@lixiang.com>
---
fs/ext4/mballoc.c | 2 +-
fs/ext4/mballoc.h | 3 +++
fs/ext4/sysfs.c | 29 +++++++++++++++++++++++++++++
3 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 9fc4b6177129..0b8c49b7535e 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -1727,7 +1727,7 @@ ext4_mb_load_buddy_gfp(struct super_block *sb, ext4_group_t group,
return ret;
}
-static int ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
+int ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
struct ext4_buddy *e4b)
{
return ext4_mb_load_buddy_gfp(sb, group, e4b, GFP_NOFS);
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
index f8280de3e882..9544abdcf7e4 100644
--- a/fs/ext4/mballoc.h
+++ b/fs/ext4/mballoc.h
@@ -246,6 +246,9 @@ static inline loff_t pa_logical_end(struct ext4_sb_info *sbi,
return (loff_t)pa->pa_lstart + EXT4_C2B(sbi, pa->pa_len);
}
+int ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
+ struct ext4_buddy *e4b);
+
typedef int (*ext4_mballoc_query_range_fn)(
struct super_block *sb,
ext4_group_t agno,
diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
index ddb54608ca2e..ecfd79505a79 100644
--- a/fs/ext4/sysfs.c
+++ b/fs/ext4/sysfs.c
@@ -17,6 +17,7 @@
#include "ext4.h"
#include "ext4_jbd2.h"
+#include "mballoc.h"
typedef enum {
attr_noop,
@@ -40,6 +41,7 @@ typedef enum {
attr_pointer_string,
attr_pointer_atomic,
attr_journal_task,
+ attr_untrimmed_groups,
} attr_id_t;
typedef enum {
@@ -138,6 +140,29 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf)
task_pid_vnr(sbi->s_journal->j_task));
}
+static ssize_t untrimmed_groups_show(struct ext4_sb_info *sbi, char *buf)
+{
+ struct super_block *sb = sbi->s_sb;
+ ext4_group_t ngroups, i;
+ struct ext4_buddy e4b;
+ int ret = 0, untrimmed = 0;
+
+ ngroups = ext4_get_groups_count(sb);
+ for (i = 0; i < ngroups; i++) {
+ ret = ext4_mb_load_buddy(sb, i, &e4b);
+ if (ret) {
+ ext4_warning(sb, "Error %d loading buddy information for %u",
+ ret, i);
+ return snprintf(buf, PAGE_SIZE, "load error\n");
+ }
+ if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info))
+ untrimmed++;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%d/%d\n",
+ untrimmed, ngroups);
+}
+
#define EXT4_ATTR(_name,_mode,_id) \
static struct ext4_attr ext4_attr_##_name = { \
.attr = {.name = __stringify(_name), .mode = _mode }, \
@@ -251,6 +276,7 @@ EXT4_RO_ATTR_ES_STRING(last_error_func, s_last_error_func, 32);
EXT4_ATTR(first_error_time, 0444, first_error_time);
EXT4_ATTR(last_error_time, 0444, last_error_time);
EXT4_ATTR(journal_task, 0444, journal_task);
+EXT4_ATTR(untrimmed_groups, 0444, untrimmed_groups);
EXT4_RW_ATTR_SBI_UI(mb_prefetch, s_mb_prefetch);
EXT4_RW_ATTR_SBI_UI(mb_prefetch_limit, s_mb_prefetch_limit);
EXT4_RW_ATTR_SBI_UL(last_trim_minblks, s_last_trim_minblks);
@@ -299,6 +325,7 @@ static struct attribute *ext4_attrs[] = {
ATTR_LIST(first_error_time),
ATTR_LIST(last_error_time),
ATTR_LIST(journal_task),
+ ATTR_LIST(untrimmed_groups),
#ifdef CONFIG_EXT4_DEBUG
ATTR_LIST(simulate_fail),
#endif
@@ -439,6 +466,8 @@ static ssize_t ext4_attr_show(struct kobject *kobj,
return print_tstamp(buf, sbi->s_es, s_last_error_time);
case attr_journal_task:
return journal_task_show(sbi, buf);
+ case attr_untrimmed_groups:
+ return untrimmed_groups_show(sbi, buf);
default:
return ext4_generic_attr_show(a, sbi, buf);
}
--
2.34.1
© 2016 - 2024 Red Hat, Inc.