* [f2fs-dev] [PATCH v2] f2fs: Add undiscard_blks_range and pending_discard_range sysfs node
@ 2026-03-05 13:40 liujinbao1
2026-03-09 6:29 ` Chao Yu via Linux-f2fs-devel
0 siblings, 1 reply; 2+ messages in thread
From: liujinbao1 @ 2026-03-05 13:40 UTC (permalink / raw)
To: jaegeuk; +Cc: jinbaoliu365, liujinbao1, linux-f2fs-devel
From: liujinbao1 <liujinbao1@xiaomi.com>
Add the undiscard_blks_range and pending_discard_range sysfs nodes to
expose the size distribution of undiscard blocks and pending discard
commands. These nodes categorize blocks into three ranges:
small: 1-15 blocks,middle: 16-511 blocks,large: 512 and above blocks
This classification helps better understand the fragmentation pattern
of discard operations. For example, when total undiscard blocks are 794,
the undiscard_blks_range node shows: "small: 424, mid: 370, large: 0",
indicating that most undiscard regions are small or medium sized.
Signed-off-by: liujinbao1 <liujinbao1@xiaomi.com>
---
v2:
- Add pending_discard_range sysfs node.
---
v1:
- Add undiscard_blks_range sysfs node.
---
Documentation/ABI/testing/sysfs-fs-f2fs | 14 +++++++++
fs/f2fs/f2fs.h | 9 ++++++
fs/f2fs/segment.c | 38 +++++++++++++++++++++++--
fs/f2fs/sysfs.c | 27 ++++++++++++++++++
4 files changed, 86 insertions(+), 2 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index c1d2b3fd9c65..6ea6e3693814 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -516,6 +516,20 @@ Date: December 2023
Contact: "Zhiguo Niu" <zhiguo.niu@unisoc.com>
Description: Shows the total number of undiscard blocks.
+What: /sys/fs/f2fs/<disk>/stat/undiscard_blks_range
+Date: March 2026
+Contact: "Jinbao Liu" <liujinbao1@xiaomi.com>
+Description: Show the total number of undiscard blocks by range.
+ Ranges: small[1-15], middle[16-511], large[512+]
+ Format: "small: %u, mid: %u, large: %u\n"
+
+What: /sys/fs/f2fs/<disk>/stat/pending_discard_range
+Date: March 2026
+Contact: "Jinbao Liu" <liujinbao1@xiaomi.com>
+Description: Show the number of pending discard commands by range.
+ Ranges: small[1-15], middle[16-511], large[512+]
+ Format: "small: %u, mid: %u, large: %u\n"
+
What: /sys/fs/f2fs/<disk>/ckpt_thread_ioprio
Date: January 2021
Contact: "Daeho Jeong" <daehojeong@google.com>
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index bb34e864d0ef..9d6b660c4a5f 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -494,6 +494,13 @@ enum {
DPOLICY_IO_AWARE_MAX,
};
+enum discard_range {
+ DISCARD_RANGE_SMALL, /* cached cmd of range in [1, 15] */
+ DISCARD_RANGE_MID, /* cached cmd of range in [16, 511] */
+ DISCARD_RANGE_LARGE, /* cached cmd of range in [512+]*/
+ DISCARD_RANGE_NR
+};
+
struct discard_policy {
int type; /* type of discard */
unsigned int min_interval; /* used for candidates exist */
@@ -528,10 +535,12 @@ struct discard_cmd_control {
unsigned int max_ordered_discard; /* maximum discard granularity issued by lba order */
unsigned int discard_io_aware; /* io_aware policy */
unsigned int undiscard_blks; /* # of undiscard blocks */
+ unsigned int undiscard_blks_range[DISCARD_RANGE_NR]; /* of undiscard blocks by range */
unsigned int next_pos; /* next discard position */
atomic_t issued_discard; /* # of issued discard */
atomic_t queued_discard; /* # of queued discard */
atomic_t discard_cmd_cnt; /* # of cached cmd count */
+ atomic_t discard_cmd_range[DISCARD_RANGE_NR]; /* of cached cmd by range */
struct rb_root_cached root; /* root of discard rb-tree */
bool rbtree_check; /* config for consistence check */
bool discard_wake; /* to wake up discard thread */
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 6a97fe76712b..46bcb27281ed 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -963,6 +963,27 @@ static unsigned int get_free_segment(struct f2fs_sb_info *sbi)
return NULL_SEGNO;
}
+static void __stat_discard_range(struct discard_cmd_control *dcc,
+ block_t len, bool inc)
+{
+ enum discard_range range;
+
+ if (len < DEFAULT_DISCARD_GRANULARITY)
+ range = DISCARD_RANGE_SMALL;
+ else if (len < MAX_PLIST_NUM)
+ range = DISCARD_RANGE_MID;
+ else
+ range = DISCARD_RANGE_LARGE;
+
+ if (inc) {
+ dcc->undiscard_blks_range[range] += len;
+ atomic_inc(&dcc->discard_cmd_range[range]);
+ } else {
+ dcc->undiscard_blks_range[range] -= len;
+ atomic_dec(&dcc->discard_cmd_range[range]);
+ }
+}
+
static struct discard_cmd *__create_discard_cmd(struct f2fs_sb_info *sbi,
struct block_device *bdev, block_t lstart,
block_t start, block_t len)
@@ -991,7 +1012,7 @@ static struct discard_cmd *__create_discard_cmd(struct f2fs_sb_info *sbi,
dc->bio_ref = 0;
atomic_inc(&dcc->discard_cmd_cnt);
dcc->undiscard_blks += len;
-
+ __stat_discard_range(dcc, len, true);
return dc;
}
@@ -1109,7 +1130,7 @@ static void __detach_discard_cmd(struct discard_cmd_control *dcc,
list_del(&dc->list);
rb_erase_cached(&dc->rb_node, &dcc->root);
dcc->undiscard_blks -= dc->di.len;
-
+ __stat_discard_range(dcc, dc->di.len, false);
kmem_cache_free(discard_cmd_slab, dc);
atomic_dec(&dcc->discard_cmd_cnt);
@@ -1382,6 +1403,8 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi,
}
if (len) {
+ __stat_discard_range(dcc, (dc->di.len + len), false);
+ __stat_discard_range(dcc, dc->di.len, true);
dcc->undiscard_blks -= len;
__update_discard_tree_range(sbi, bdev, lstart, start, len);
}
@@ -1439,10 +1462,12 @@ static void __punch_discard_cmd(struct f2fs_sb_info *sbi,
}
dcc->undiscard_blks -= di.len;
+ __stat_discard_range(dcc, di.len, false);
if (blkaddr > di.lstart) {
dc->di.len = blkaddr - dc->di.lstart;
dcc->undiscard_blks += dc->di.len;
+ __stat_discard_range(dcc, dc->di.len, true);
__relocate_discard_cmd(dcc, dc);
modified = true;
}
@@ -1457,6 +1482,7 @@ static void __punch_discard_cmd(struct f2fs_sb_info *sbi,
dc->di.len--;
dc->di.start++;
dcc->undiscard_blks += dc->di.len;
+ __stat_discard_range(dcc, dc->di.len, true);
__relocate_discard_cmd(dcc, dc);
}
}
@@ -1513,8 +1539,10 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
prev_dc->bdev == bdev &&
__is_discard_back_mergeable(&di, &prev_dc->di,
max_discard_blocks)) {
+ __stat_discard_range(dcc, prev_dc->di.len, false);
prev_dc->di.len += di.len;
dcc->undiscard_blks += di.len;
+ __stat_discard_range(dcc, prev_dc->di.len, true);
__relocate_discard_cmd(dcc, prev_dc);
di = prev_dc->di;
tdc = prev_dc;
@@ -1525,10 +1553,12 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
next_dc->bdev == bdev &&
__is_discard_front_mergeable(&di, &next_dc->di,
max_discard_blocks)) {
+ __stat_discard_range(dcc, next_dc->di.len, false);
next_dc->di.lstart = di.lstart;
next_dc->di.len += di.len;
next_dc->di.start = di.start;
dcc->undiscard_blks += di.len;
+ __stat_discard_range(dcc, next_dc->di.len, true);
__relocate_discard_cmd(dcc, next_dc);
if (tdc)
__remove_discard_cmd(sbi, tdc);
@@ -2330,6 +2360,8 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
atomic_set(&dcc->issued_discard, 0);
atomic_set(&dcc->queued_discard, 0);
atomic_set(&dcc->discard_cmd_cnt, 0);
+ for (i = 0; i < DISCARD_RANGE_NR; i++)
+ atomic_set(&dcc->discard_cmd_range[i], 0);
dcc->nr_discards = 0;
dcc->max_discards = SEGS_TO_BLKS(sbi, MAIN_SEGS(sbi));
dcc->max_discard_request = DEF_MAX_DISCARD_REQUEST;
@@ -2338,6 +2370,8 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
dcc->max_discard_issue_time = DEF_MAX_DISCARD_ISSUE_TIME;
dcc->discard_urgent_util = DEF_DISCARD_URGENT_UTIL;
dcc->undiscard_blks = 0;
+ for (i = 0; i < DISCARD_RANGE_NR; i++)
+ dcc->undiscard_blks_range[i] = 0;
dcc->next_pos = 0;
dcc->root = RB_ROOT_CACHED;
dcc->rbtree_check = false;
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 5fbfdc96e502..40b36d59802c 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -152,6 +152,18 @@ static ssize_t pending_discard_show(struct f2fs_attr *a,
&SM_I(sbi)->dcc_info->discard_cmd_cnt));
}
+static ssize_t pending_discard_range_show(struct f2fs_attr *a,
+ struct f2fs_sb_info *sbi, char *buf)
+{
+ struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
+ if (!dcc)
+ return -EINVAL;
+ return sysfs_emit(buf, "small:%llu, mid:%llu, large:%llu\n",
+ (unsigned long long)atomic_read(&dcc->discard_cmd_range[DISCARD_RANGE_SMALL]),
+ (unsigned long long)atomic_read(&dcc->discard_cmd_range[DISCARD_RANGE_MID]),
+ (unsigned long long)atomic_read(&dcc->discard_cmd_range[DISCARD_RANGE_LARGE]));
+}
+
static ssize_t issued_discard_show(struct f2fs_attr *a,
struct f2fs_sb_info *sbi, char *buf)
{
@@ -179,6 +191,17 @@ static ssize_t undiscard_blks_show(struct f2fs_attr *a,
SM_I(sbi)->dcc_info->undiscard_blks);
}
+static ssize_t undiscard_blks_range_show(struct f2fs_attr *a,
+ struct f2fs_sb_info *sbi, char *buf)
+{
+ if (!SM_I(sbi)->dcc_info)
+ return -EINVAL;
+ return sysfs_emit(buf, "small: %u, mid: %u, large: %u\n",
+ SM_I(sbi)->dcc_info->undiscard_blks_range[DISCARD_RANGE_SMALL],
+ SM_I(sbi)->dcc_info->undiscard_blks_range[DISCARD_RANGE_MID],
+ SM_I(sbi)->dcc_info->undiscard_blks_range[DISCARD_RANGE_LARGE]);
+}
+
static ssize_t atgc_enabled_show(struct f2fs_attr *a,
struct f2fs_sb_info *sbi, char *buf)
{
@@ -1562,6 +1585,8 @@ F2FS_GENERAL_RO_ATTR(cp_status);
F2FS_GENERAL_RO_ATTR(issued_discard);
F2FS_GENERAL_RO_ATTR(queued_discard);
F2FS_GENERAL_RO_ATTR(undiscard_blks);
+F2FS_GENERAL_RO_ATTR(undiscard_blks_range);
+F2FS_GENERAL_RO_ATTR(pending_discard_range);
static struct attribute *f2fs_stat_attrs[] = {
ATTR_LIST(sb_status),
@@ -1569,6 +1594,8 @@ static struct attribute *f2fs_stat_attrs[] = {
ATTR_LIST(issued_discard),
ATTR_LIST(queued_discard),
ATTR_LIST(undiscard_blks),
+ ATTR_LIST(undiscard_blks_range),
+ ATTR_LIST(pending_discard_range),
NULL,
};
ATTRIBUTE_GROUPS(f2fs_stat);
--
2.25.1
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [f2fs-dev] [PATCH v2] f2fs: Add undiscard_blks_range and pending_discard_range sysfs node
2026-03-05 13:40 [f2fs-dev] [PATCH v2] f2fs: Add undiscard_blks_range and pending_discard_range sysfs node liujinbao1
@ 2026-03-09 6:29 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 2+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-03-09 6:29 UTC (permalink / raw)
To: liujinbao1, jaegeuk; +Cc: liujinbao1, linux-f2fs-devel
On 3/5/26 21:40, liujinbao1 wrote:
> From: liujinbao1 <liujinbao1@xiaomi.com>
>
> Add the undiscard_blks_range and pending_discard_range sysfs nodes to
> expose the size distribution of undiscard blocks and pending discard
> commands. These nodes categorize blocks into three ranges:
>
> small: 1-15 blocks,middle: 16-511 blocks,large: 512 and above blocks
>
> This classification helps better understand the fragmentation pattern
> of discard operations. For example, when total undiscard blocks are 794,
> the undiscard_blks_range node shows: "small: 424, mid: 370, large: 0",
> indicating that most undiscard regions are small or medium sized.
>
> Signed-off-by: liujinbao1 <liujinbao1@xiaomi.com>
> ---
> v2:
> - Add pending_discard_range sysfs node.
> ---
> v1:
> - Add undiscard_blks_range sysfs node.
> ---
> Documentation/ABI/testing/sysfs-fs-f2fs | 14 +++++++++
> fs/f2fs/f2fs.h | 9 ++++++
> fs/f2fs/segment.c | 38 +++++++++++++++++++++++--
> fs/f2fs/sysfs.c | 27 ++++++++++++++++++
> 4 files changed, 86 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
> index c1d2b3fd9c65..6ea6e3693814 100644
> --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> @@ -516,6 +516,20 @@ Date: December 2023
> Contact: "Zhiguo Niu" <zhiguo.niu@unisoc.com>
> Description: Shows the total number of undiscard blocks.
>
> +What: /sys/fs/f2fs/<disk>/stat/undiscard_blks_range
> +Date: March 2026
> +Contact: "Jinbao Liu" <liujinbao1@xiaomi.com>
> +Description: Show the total number of undiscard blocks by range.
> + Ranges: small[1-15], middle[16-511], large[512+]
> + Format: "small: %u, mid: %u, large: %u\n"
Is it possible to expose undiscard blocks via /proc/fs/f2fs/<disk>/undiscard_blocks
like we did for discard_cmd_cnt in /proc/fs/f2fs/<disk>/discard_plist_info?
> +
> +What: /sys/fs/f2fs/<disk>/stat/pending_discard_range
> +Date: March 2026
> +Contact: "Jinbao Liu" <liujinbao1@xiaomi.com>
> +Description: Show the number of pending discard commands by range.
> + Ranges: small[1-15], middle[16-511], large[512+]
> + Format: "small: %u, mid: %u, large: %u\n"
What do you think of querying pending discard numbers from
/proc/fs/f2fs/<disk>/discard_plist_info?
Thanks,
> +
> What: /sys/fs/f2fs/<disk>/ckpt_thread_ioprio
> Date: January 2021
> Contact: "Daeho Jeong" <daehojeong@google.com>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index bb34e864d0ef..9d6b660c4a5f 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -494,6 +494,13 @@ enum {
> DPOLICY_IO_AWARE_MAX,
> };
>
> +enum discard_range {
> + DISCARD_RANGE_SMALL, /* cached cmd of range in [1, 15] */
> + DISCARD_RANGE_MID, /* cached cmd of range in [16, 511] */
> + DISCARD_RANGE_LARGE, /* cached cmd of range in [512+]*/
> + DISCARD_RANGE_NR
> +};
> +
> struct discard_policy {
> int type; /* type of discard */
> unsigned int min_interval; /* used for candidates exist */
> @@ -528,10 +535,12 @@ struct discard_cmd_control {
> unsigned int max_ordered_discard; /* maximum discard granularity issued by lba order */
> unsigned int discard_io_aware; /* io_aware policy */
> unsigned int undiscard_blks; /* # of undiscard blocks */
> + unsigned int undiscard_blks_range[DISCARD_RANGE_NR]; /* of undiscard blocks by range */
> unsigned int next_pos; /* next discard position */
> atomic_t issued_discard; /* # of issued discard */
> atomic_t queued_discard; /* # of queued discard */
> atomic_t discard_cmd_cnt; /* # of cached cmd count */
> + atomic_t discard_cmd_range[DISCARD_RANGE_NR]; /* of cached cmd by range */
> struct rb_root_cached root; /* root of discard rb-tree */
> bool rbtree_check; /* config for consistence check */
> bool discard_wake; /* to wake up discard thread */
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 6a97fe76712b..46bcb27281ed 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -963,6 +963,27 @@ static unsigned int get_free_segment(struct f2fs_sb_info *sbi)
> return NULL_SEGNO;
> }
>
> +static void __stat_discard_range(struct discard_cmd_control *dcc,
> + block_t len, bool inc)
> +{
> + enum discard_range range;
> +
> + if (len < DEFAULT_DISCARD_GRANULARITY)
> + range = DISCARD_RANGE_SMALL;
> + else if (len < MAX_PLIST_NUM)
> + range = DISCARD_RANGE_MID;
> + else
> + range = DISCARD_RANGE_LARGE;
> +
> + if (inc) {
> + dcc->undiscard_blks_range[range] += len;
> + atomic_inc(&dcc->discard_cmd_range[range]);
> + } else {
> + dcc->undiscard_blks_range[range] -= len;
> + atomic_dec(&dcc->discard_cmd_range[range]);
> + }
> +}
> +
> static struct discard_cmd *__create_discard_cmd(struct f2fs_sb_info *sbi,
> struct block_device *bdev, block_t lstart,
> block_t start, block_t len)
> @@ -991,7 +1012,7 @@ static struct discard_cmd *__create_discard_cmd(struct f2fs_sb_info *sbi,
> dc->bio_ref = 0;
> atomic_inc(&dcc->discard_cmd_cnt);
> dcc->undiscard_blks += len;
> -
> + __stat_discard_range(dcc, len, true);
> return dc;
> }
>
> @@ -1109,7 +1130,7 @@ static void __detach_discard_cmd(struct discard_cmd_control *dcc,
> list_del(&dc->list);
> rb_erase_cached(&dc->rb_node, &dcc->root);
> dcc->undiscard_blks -= dc->di.len;
> -
> + __stat_discard_range(dcc, dc->di.len, false);
> kmem_cache_free(discard_cmd_slab, dc);
>
> atomic_dec(&dcc->discard_cmd_cnt);
> @@ -1382,6 +1403,8 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi,
> }
>
> if (len) {
> + __stat_discard_range(dcc, (dc->di.len + len), false);
> + __stat_discard_range(dcc, dc->di.len, true);
> dcc->undiscard_blks -= len;
> __update_discard_tree_range(sbi, bdev, lstart, start, len);
> }
> @@ -1439,10 +1462,12 @@ static void __punch_discard_cmd(struct f2fs_sb_info *sbi,
> }
>
> dcc->undiscard_blks -= di.len;
> + __stat_discard_range(dcc, di.len, false);
>
> if (blkaddr > di.lstart) {
> dc->di.len = blkaddr - dc->di.lstart;
> dcc->undiscard_blks += dc->di.len;
> + __stat_discard_range(dcc, dc->di.len, true);
> __relocate_discard_cmd(dcc, dc);
> modified = true;
> }
> @@ -1457,6 +1482,7 @@ static void __punch_discard_cmd(struct f2fs_sb_info *sbi,
> dc->di.len--;
> dc->di.start++;
> dcc->undiscard_blks += dc->di.len;
> + __stat_discard_range(dcc, dc->di.len, true);
> __relocate_discard_cmd(dcc, dc);
> }
> }
> @@ -1513,8 +1539,10 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
> prev_dc->bdev == bdev &&
> __is_discard_back_mergeable(&di, &prev_dc->di,
> max_discard_blocks)) {
> + __stat_discard_range(dcc, prev_dc->di.len, false);
> prev_dc->di.len += di.len;
> dcc->undiscard_blks += di.len;
> + __stat_discard_range(dcc, prev_dc->di.len, true);
> __relocate_discard_cmd(dcc, prev_dc);
> di = prev_dc->di;
> tdc = prev_dc;
> @@ -1525,10 +1553,12 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
> next_dc->bdev == bdev &&
> __is_discard_front_mergeable(&di, &next_dc->di,
> max_discard_blocks)) {
> + __stat_discard_range(dcc, next_dc->di.len, false);
> next_dc->di.lstart = di.lstart;
> next_dc->di.len += di.len;
> next_dc->di.start = di.start;
> dcc->undiscard_blks += di.len;
> + __stat_discard_range(dcc, next_dc->di.len, true);
> __relocate_discard_cmd(dcc, next_dc);
> if (tdc)
> __remove_discard_cmd(sbi, tdc);
> @@ -2330,6 +2360,8 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
> atomic_set(&dcc->issued_discard, 0);
> atomic_set(&dcc->queued_discard, 0);
> atomic_set(&dcc->discard_cmd_cnt, 0);
> + for (i = 0; i < DISCARD_RANGE_NR; i++)
> + atomic_set(&dcc->discard_cmd_range[i], 0);
> dcc->nr_discards = 0;
> dcc->max_discards = SEGS_TO_BLKS(sbi, MAIN_SEGS(sbi));
> dcc->max_discard_request = DEF_MAX_DISCARD_REQUEST;
> @@ -2338,6 +2370,8 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
> dcc->max_discard_issue_time = DEF_MAX_DISCARD_ISSUE_TIME;
> dcc->discard_urgent_util = DEF_DISCARD_URGENT_UTIL;
> dcc->undiscard_blks = 0;
> + for (i = 0; i < DISCARD_RANGE_NR; i++)
> + dcc->undiscard_blks_range[i] = 0;
> dcc->next_pos = 0;
> dcc->root = RB_ROOT_CACHED;
> dcc->rbtree_check = false;
> diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> index 5fbfdc96e502..40b36d59802c 100644
> --- a/fs/f2fs/sysfs.c
> +++ b/fs/f2fs/sysfs.c
> @@ -152,6 +152,18 @@ static ssize_t pending_discard_show(struct f2fs_attr *a,
> &SM_I(sbi)->dcc_info->discard_cmd_cnt));
> }
>
> +static ssize_t pending_discard_range_show(struct f2fs_attr *a,
> + struct f2fs_sb_info *sbi, char *buf)
> +{
> + struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
> + if (!dcc)
> + return -EINVAL;
> + return sysfs_emit(buf, "small:%llu, mid:%llu, large:%llu\n",
> + (unsigned long long)atomic_read(&dcc->discard_cmd_range[DISCARD_RANGE_SMALL]),
> + (unsigned long long)atomic_read(&dcc->discard_cmd_range[DISCARD_RANGE_MID]),
> + (unsigned long long)atomic_read(&dcc->discard_cmd_range[DISCARD_RANGE_LARGE]));
> +}
> +
> static ssize_t issued_discard_show(struct f2fs_attr *a,
> struct f2fs_sb_info *sbi, char *buf)
> {
> @@ -179,6 +191,17 @@ static ssize_t undiscard_blks_show(struct f2fs_attr *a,
> SM_I(sbi)->dcc_info->undiscard_blks);
> }
>
> +static ssize_t undiscard_blks_range_show(struct f2fs_attr *a,
> + struct f2fs_sb_info *sbi, char *buf)
> +{
> + if (!SM_I(sbi)->dcc_info)
> + return -EINVAL;
> + return sysfs_emit(buf, "small: %u, mid: %u, large: %u\n",
> + SM_I(sbi)->dcc_info->undiscard_blks_range[DISCARD_RANGE_SMALL],
> + SM_I(sbi)->dcc_info->undiscard_blks_range[DISCARD_RANGE_MID],
> + SM_I(sbi)->dcc_info->undiscard_blks_range[DISCARD_RANGE_LARGE]);
> +}
> +
> static ssize_t atgc_enabled_show(struct f2fs_attr *a,
> struct f2fs_sb_info *sbi, char *buf)
> {
> @@ -1562,6 +1585,8 @@ F2FS_GENERAL_RO_ATTR(cp_status);
> F2FS_GENERAL_RO_ATTR(issued_discard);
> F2FS_GENERAL_RO_ATTR(queued_discard);
> F2FS_GENERAL_RO_ATTR(undiscard_blks);
> +F2FS_GENERAL_RO_ATTR(undiscard_blks_range);
> +F2FS_GENERAL_RO_ATTR(pending_discard_range);
>
> static struct attribute *f2fs_stat_attrs[] = {
> ATTR_LIST(sb_status),
> @@ -1569,6 +1594,8 @@ static struct attribute *f2fs_stat_attrs[] = {
> ATTR_LIST(issued_discard),
> ATTR_LIST(queued_discard),
> ATTR_LIST(undiscard_blks),
> + ATTR_LIST(undiscard_blks_range),
> + ATTR_LIST(pending_discard_range),
> NULL,
> };
> ATTRIBUTE_GROUPS(f2fs_stat);
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-03-09 6:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-05 13:40 [f2fs-dev] [PATCH v2] f2fs: Add undiscard_blks_range and pending_discard_range sysfs node liujinbao1
2026-03-09 6:29 ` Chao Yu via Linux-f2fs-devel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox