[PATCH 34/36] xfs: port the perag discard code to handle generic groups

Darrick J. Wong
2024-10-11T01:10:32Z

Port xfs_discard_extents and its tracepoints to handle generic groups
instead of just perags. This is needed to enable busy extent tracking
for rtgroups.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/xfs_discard.c | 35 ++++++++++++++++++++++++++---------
fs/xfs/xfs_trace.h | 19 +++++++++++--------
2 files changed, 37 insertions(+), 17 deletions(-)

diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c
index bcc904e749b276..2200b119e55b6b 100644
--- a/fs/xfs/xfs_discard.c
+++ b/fs/xfs/xfs_discard.c
@@ -101,6 +101,24 @@ xfs_discard_endio(
bio_put(bio);
}

+static inline struct block_device *
+xfs_group_bdev(
+ const struct xfs_group *xg)
+{
+ struct xfs_mount *mp = xg->xg_mount;
+
+ switch (xg->xg_type) {
+ case XG_TYPE_AG:
+ return mp->m_ddev_targp->bt_bdev;
+ case XG_TYPE_RTG:
+ return mp->m_rtdev_targp->bt_bdev;
+ default:
+ ASSERT(0);
+ break;
+ }
+ return NULL;
+}
+
/*
* Walk the discard list and issue discards on all the busy extents in the
* list. We plug and chain the bios so that we only need a single completion
@@ -118,12 +136,11 @@ xfs_discard_extents(

blk_start_plug(&plug);
list_for_each_entry(busyp, &extents->extent_list, list) {
- struct xfs_perag *pag = to_perag(busyp->group);
+ trace_xfs_discard_extent(busyp->group, busyp->bno,
+ busyp->length);

- trace_xfs_discard_extent(pag, busyp->bno, busyp->length);
-
- error = __blkdev_issue_discard(mp->m_ddev_targp->bt_bdev,
- xfs_agbno_to_daddr(pag, busyp->bno),
+ error = __blkdev_issue_discard(xfs_group_bdev(busyp->group),
+ xfs_gbno_to_daddr(busyp->group, busyp->bno),
XFS_FSB_TO_BB(mp, busyp->length),
GFP_KERNEL, &bio);
if (error && error != -EOPNOTSUPP) {
@@ -241,11 +258,11 @@ xfs_trim_gather_extents(
* overlapping ranges for now.
*/
if (fbno + flen < tcur->start) {
- trace_xfs_discard_exclude(pag, fbno, flen);
+ trace_xfs_discard_exclude(&pag->pag_group, fbno, flen);
goto next_extent;
}
if (fbno > tcur->end) {
- trace_xfs_discard_exclude(pag, fbno, flen);
+ trace_xfs_discard_exclude(&pag->pag_group, fbno, flen);
if (tcur->by_bno) {
tcur->count = 0;
break;
@@ -263,7 +280,7 @@ xfs_trim_gather_extents(

/* Too small? Give up. */
if (flen < tcur->minlen) {
- trace_xfs_discard_toosmall(pag, fbno, flen);
+ trace_xfs_discard_toosmall(&pag->pag_group, fbno, flen);
if (tcur->by_bno)
goto next_extent;
tcur->count = 0;
@@ -275,7 +292,7 @@ xfs_trim_gather_extents(
* discard and try again the next time.
*/
if (xfs_extent_busy_search(&pag->pag_group, fbno, flen)) {
- trace_xfs_discard_busy(pag, fbno, flen);
+ trace_xfs_discard_busy(&pag->pag_group, fbno, flen);
goto next_extent;
}

diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 7beeaac0ad4cf0..64af1470b838f0 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -2480,23 +2480,26 @@ DEFINE_LOG_RECOVER_ICREATE_ITEM(xfs_log_recover_icreate_cancel);
DEFINE_LOG_RECOVER_ICREATE_ITEM(xfs_log_recover_icreate_recover);

DECLARE_EVENT_CLASS(xfs_discard_class,
- TP_PROTO(const struct xfs_perag *pag, xfs_agblock_t agbno,
+ TP_PROTO(const struct xfs_group *xg, xfs_agblock_t agbno,
xfs_extlen_t len),
- TP_ARGS(pag, agbno, len),
+ TP_ARGS(xg, agbno, len),
TP_STRUCT__entry(
__field(dev_t, dev)
+ __field(enum xfs_group_type, type)
__field(xfs_agnumber_t, agno)
__field(xfs_agblock_t, agbno)
__field(xfs_extlen_t, len)
),
TP_fast_assign(
- __entry->dev = pag_mount(pag)->m_super->s_dev;
- __entry->agno = pag_agno(pag);
+ __entry->dev = xg->xg_mount->m_super->s_dev;
+ __entry->type = xg->xg_type;
+ __entry->agno = xg->xg_index;
__entry->agbno = agbno;
__entry->len = len;
),
- TP_printk("dev %d:%d agno 0x%x agbno 0x%x fsbcount 0x%x",
+ TP_printk("dev %d:%d %sno 0x%x gbno 0x%x fsbcount 0x%x",
MAJOR(__entry->dev), MINOR(__entry->dev),
+ __print_symbolic(__entry->type, XG_TYPE_STRINGS),
__entry->agno,
__entry->agbno,
__entry->len)
@@ -2504,9 +2507,9 @@ DECLARE_EVENT_CLASS(xfs_discard_class,

#define DEFINE_DISCARD_EVENT(name) \
DEFINE_EVENT(xfs_discard_class, name, \
- TP_PROTO(const struct xfs_perag *pag, xfs_agblock_t agbno, \
- xfs_extlen_t len), \
- TP_ARGS(pag, agbno, len))
+ TP_PROTO(const struct xfs_group *xg, xfs_agblock_t agbno, \
+ xfs_extlen_t len), \
+ TP_ARGS(xg, agbno, len))
DEFINE_DISCARD_EVENT(xfs_discard_extent);
DEFINE_DISCARD_EVENT(xfs_discard_toosmall);
DEFINE_DISCARD_EVENT(xfs_discard_exclude);