* misc cleanups
@ 2026-09-24 9:57 Christoph Hellwig
2026-09-24 9:57 ` [PATCH 1/9] xfs: centralize setting of buf_ops/buf_type/magic for rtblocks Christoph Hellwig
` (9 more replies)
0 siblings, 10 replies; 21+ messages in thread
From: Christoph Hellwig @ 2026-09-24 9:57 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Darrick J . Wong, linux-xfs
Hi all,
this series has various cleanups developed as part of the data checksum
series that should be useful on their own.
Diffstat:
libxfs/xfs_rtbitmap.c | 79 ++++++++++++++++++++++++------------------
libxfs/xfs_rtbitmap.h | 45 +++++++++---------------
scrub/rtbitmap_repair.c | 15 --------
scrub/rtsummary_repair.c | 15 --------
xfs_ioend.c | 81 +++++++++++++++++++++++++------------------
xfs_iomap.c | 53 ++++++++++++++++++----------
xfs_verify_media.c | 87 ++++++++++++++++++-----------------------------
7 files changed, 181 insertions(+), 194 deletions(-)
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/9] xfs: centralize setting of buf_ops/buf_type/magic for rtblocks
2026-09-24 9:57 misc cleanups Christoph Hellwig
@ 2026-09-24 9:57 ` Christoph Hellwig
2026-09-24 19:01 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 2/9] xfs: factor out a xfs_rtfile_initialize_buf helper Christoph Hellwig
` (8 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2026-09-24 9:57 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Darrick J . Wong, linux-xfs
Add two tables for the buf_ops and buf_type, and derive the magic from
the buf_ops to make have a single source of truth for the different RT
block variants. This cleans up the existing code and makes adding another
type of block/file easier.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/libxfs/xfs_rtbitmap.c | 40 +++++++++++++++++++++---------------
fs/xfs/libxfs/xfs_rtbitmap.h | 15 ++------------
2 files changed, 25 insertions(+), 30 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index e62786e90f7b..3f7877220e05 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -125,6 +125,26 @@ const struct xfs_buf_ops xfs_rtsummary_buf_ops = {
.verify_struct = xfs_rtbuf_verify,
};
+static const struct xfs_buf_ops *xfs_rtblock_buf_ops[XFS_RTGI_MAX] = {
+ [XFS_RTGI_SUMMARY] = &xfs_rtsummary_buf_ops,
+ [XFS_RTGI_BITMAP] = &xfs_rtbitmap_buf_ops,
+};
+
+const struct xfs_buf_ops *
+xfs_rtblock_ops(
+ struct xfs_mount *mp,
+ enum xfs_rtg_inodes type)
+{
+ if (!xfs_has_rtgroups(mp))
+ return &xfs_rtbuf_ops;
+ return xfs_rtblock_buf_ops[type];
+}
+
+static enum xfs_blft xfs_rtblock_buf_types[XFS_RTGI_MAX] = {
+ [XFS_RTGI_SUMMARY] = XFS_BLFT_RTSUMMARY_BUF,
+ [XFS_RTGI_BITMAP] = XFS_BLFT_RTBITMAP_BUF,
+};
+
/* Release cached rt bitmap and summary buffers. */
void
xfs_rtbuf_cache_relse(
@@ -158,7 +178,6 @@ xfs_rtbuf_get(
xfs_fileoff_t *coffp; /* cached block number */
struct xfs_buf *bp; /* block buffer, result */
struct xfs_bmbt_irec map;
- enum xfs_blft buf_type;
int nmap = 1;
int error;
@@ -166,12 +185,10 @@ xfs_rtbuf_get(
case XFS_RTGI_SUMMARY:
cbpp = &args->sumbp;
coffp = &args->sumoff;
- buf_type = XFS_BLFT_RTSUMMARY_BUF;
break;
case XFS_RTGI_BITMAP:
cbpp = &args->rbmbp;
coffp = &args->rbmoff;
- buf_type = XFS_BLFT_RTBITMAP_BUF;
break;
default:
return -EINVAL;
@@ -222,7 +239,7 @@ xfs_rtbuf_get(
}
}
- xfs_trans_buf_set_type(args->tp, bp, buf_type);
+ xfs_trans_buf_set_type(args->tp, bp, xfs_rtblock_buf_types[type]);
*cbpp = bp;
*coffp = block;
return 0;
@@ -1375,16 +1392,8 @@ xfs_rtfile_initialize_block(
struct xfs_buf *bp;
void *bufdata;
const size_t copylen = mp->m_blockwsize << XFS_WORDLOG;
- enum xfs_blft buf_type;
int error;
- if (type == XFS_RTGI_BITMAP)
- buf_type = XFS_BLFT_RTBITMAP_BUF;
- else if (type == XFS_RTGI_SUMMARY)
- buf_type = XFS_BLFT_RTSUMMARY_BUF;
- else
- return -EINVAL;
-
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero, 0, 0, 0, &tp);
if (error)
return error;
@@ -1399,16 +1408,13 @@ xfs_rtfile_initialize_block(
}
bufdata = bp->b_addr;
- xfs_trans_buf_set_type(tp, bp, buf_type);
+ xfs_trans_buf_set_type(tp, bp, xfs_rtblock_buf_types[type]);
bp->b_ops = xfs_rtblock_ops(mp, type);
if (xfs_has_rtgroups(mp)) {
struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
- if (type == XFS_RTGI_BITMAP)
- hdr->rt_magic = cpu_to_be32(XFS_RTBITMAP_MAGIC);
- else
- hdr->rt_magic = cpu_to_be32(XFS_RTSUMMARY_MAGIC);
+ hdr->rt_magic = bp->b_ops->magic[1];
hdr->rt_owner = cpu_to_be64(I_INO(ip));
hdr->rt_blkno = cpu_to_be64(XFS_FSB_TO_DADDR(mp, fsbno));
hdr->rt_lsn = 0;
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
index 22e5d9cd95f4..375cc48e1a53 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -354,19 +354,6 @@ xfs_suminfo_add(
return info->old;
}
-static inline const struct xfs_buf_ops *
-xfs_rtblock_ops(
- struct xfs_mount *mp,
- enum xfs_rtg_inodes type)
-{
- if (xfs_has_rtgroups(mp)) {
- if (type == XFS_RTGI_SUMMARY)
- return &xfs_rtsummary_buf_ops;
- return &xfs_rtbitmap_buf_ops;
- }
- return &xfs_rtbuf_ops;
-}
-
/*
* Functions for walking free space rtextents in the realtime bitmap.
*/
@@ -419,6 +406,8 @@ xfs_filblks_t xfs_rtbitmap_blockcount_len(struct xfs_mount *mp,
xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
unsigned int *rsumlevels);
+const struct xfs_buf_ops *xfs_rtblock_ops(struct xfs_mount *mp,
+ enum xfs_rtg_inodes type);
int xfs_rtfile_initialize_blocks(struct xfs_rtgroup *rtg,
enum xfs_rtg_inodes type, xfs_fileoff_t offset_fsb,
xfs_fileoff_t end_fsb, void *data);
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/9] xfs: factor out a xfs_rtfile_initialize_buf helper
2026-09-24 9:57 misc cleanups Christoph Hellwig
2026-09-24 9:57 ` [PATCH 1/9] xfs: centralize setting of buf_ops/buf_type/magic for rtblocks Christoph Hellwig
@ 2026-09-24 9:57 ` Christoph Hellwig
2026-09-24 19:02 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 3/9] xfs: add a xfs_rtblock_payload helper Christoph Hellwig
` (7 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2026-09-24 9:57 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Darrick J . Wong, linux-xfs
Share the code to initialize the header and buf ops for rtfile blocks
into a single helper.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/libxfs/xfs_rtbitmap.c | 38 +++++++++++++++++++++------------
fs/xfs/libxfs/xfs_rtbitmap.h | 3 +++
fs/xfs/scrub/rtbitmap_repair.c | 15 +------------
fs/xfs/scrub/rtsummary_repair.c | 15 +------------
4 files changed, 29 insertions(+), 42 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 3f7877220e05..5cadde81b5da 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -1378,6 +1378,27 @@ xfs_rtfile_alloc_blocks(
return error;
}
+void
+xfs_rtfile_initialize_buf(
+ struct xfs_rtgroup *rtg,
+ enum xfs_rtg_inodes type,
+ struct xfs_buf *bp,
+ struct xfs_trans *tp)
+{
+ bp->b_ops = xfs_rtblock_ops(bp->b_mount, type);
+ if (tp)
+ xfs_trans_buf_set_type(tp, bp, xfs_rtblock_buf_types[type]);
+ if (xfs_has_rtgroups(bp->b_mount)) {
+ struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
+
+ hdr->rt_magic = bp->b_ops->magic[1];
+ hdr->rt_owner = cpu_to_be64(I_INO(rtg->rtg_inodes[type]));
+ hdr->rt_blkno = cpu_to_be64(xfs_buf_daddr(bp));
+ hdr->rt_lsn = 0;
+ uuid_copy(&hdr->rt_uuid, &bp->b_mount->m_sb.sb_meta_uuid);
+ }
+}
+
/* Get a buffer for the block. */
static int
xfs_rtfile_initialize_block(
@@ -1408,21 +1429,10 @@ xfs_rtfile_initialize_block(
}
bufdata = bp->b_addr;
- xfs_trans_buf_set_type(tp, bp, xfs_rtblock_buf_types[type]);
- bp->b_ops = xfs_rtblock_ops(mp, type);
-
- if (xfs_has_rtgroups(mp)) {
- struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
-
- hdr->rt_magic = bp->b_ops->magic[1];
- hdr->rt_owner = cpu_to_be64(I_INO(ip));
- hdr->rt_blkno = cpu_to_be64(XFS_FSB_TO_DADDR(mp, fsbno));
- hdr->rt_lsn = 0;
- uuid_copy(&hdr->rt_uuid, &mp->m_sb.sb_meta_uuid);
-
- bufdata += sizeof(*hdr);
- }
+ xfs_rtfile_initialize_buf(rtg, type, bp, tp);
+ if (xfs_has_rtgroups(mp))
+ bufdata += sizeof(struct xfs_rtbuf_blkinfo);
if (data)
memcpy(bufdata, data, copylen);
else
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
index 375cc48e1a53..4a87e1fd3e99 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -408,6 +408,9 @@ xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
const struct xfs_buf_ops *xfs_rtblock_ops(struct xfs_mount *mp,
enum xfs_rtg_inodes type);
+void xfs_rtfile_initialize_buf(struct xfs_rtgroup *rtg,
+ enum xfs_rtg_inodes type, struct xfs_buf *bp,
+ struct xfs_trans *tp);
int xfs_rtfile_initialize_blocks(struct xfs_rtgroup *rtg,
enum xfs_rtg_inodes type, xfs_fileoff_t offset_fsb,
xfs_fileoff_t end_fsb, void *data);
diff --git a/fs/xfs/scrub/rtbitmap_repair.c b/fs/xfs/scrub/rtbitmap_repair.c
index 442a17bf9720..6a2efe3115f4 100644
--- a/fs/xfs/scrub/rtbitmap_repair.c
+++ b/fs/xfs/scrub/rtbitmap_repair.c
@@ -383,21 +383,8 @@ xrep_rtbitmap_prep_buf(
if (error)
return error;
- if (xfs_has_rtgroups(sc->mp)) {
- struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
-
- hdr->rt_magic = cpu_to_be32(XFS_RTBITMAP_MAGIC);
- hdr->rt_owner = cpu_to_be64(I_INO(sc->ip));
- hdr->rt_blkno = cpu_to_be64(xfs_buf_daddr(bp));
- hdr->rt_lsn = 0;
- uuid_copy(&hdr->rt_uuid, &sc->mp->m_sb.sb_meta_uuid);
- bp->b_ops = &xfs_rtbitmap_buf_ops;
- } else {
- bp->b_ops = &xfs_rtbuf_ops;
- }
-
+ xfs_rtfile_initialize_buf(sc->sr.rtg, XFS_RTGI_BITMAP, bp, sc->tp);
rtb->prep_wordoff += mp->m_blockwsize;
- xfs_trans_buf_set_type(sc->tp, bp, XFS_BLFT_RTBITMAP_BUF);
return 0;
}
diff --git a/fs/xfs/scrub/rtsummary_repair.c b/fs/xfs/scrub/rtsummary_repair.c
index f065c3e51ce2..6a66113f6562 100644
--- a/fs/xfs/scrub/rtsummary_repair.c
+++ b/fs/xfs/scrub/rtsummary_repair.c
@@ -87,21 +87,8 @@ xrep_rtsummary_prep_buf(
if (error)
return error;
- if (xfs_has_rtgroups(sc->mp)) {
- struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
-
- hdr->rt_magic = cpu_to_be32(XFS_RTSUMMARY_MAGIC);
- hdr->rt_owner = cpu_to_be64(I_INO(sc->ip));
- hdr->rt_blkno = cpu_to_be64(xfs_buf_daddr(bp));
- hdr->rt_lsn = 0;
- uuid_copy(&hdr->rt_uuid, &sc->mp->m_sb.sb_meta_uuid);
- bp->b_ops = &xfs_rtsummary_buf_ops;
- } else {
- bp->b_ops = &xfs_rtbuf_ops;
- }
-
+ xfs_rtfile_initialize_buf(sc->sr.rtg, XFS_RTGI_SUMMARY, bp, sc->tp);
rts->prep_wordoff += mp->m_blockwsize;
- xfs_trans_buf_set_type(sc->tp, bp, XFS_BLFT_RTSUMMARY_BUF);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 3/9] xfs: add a xfs_rtblock_payload helper
2026-09-24 9:57 misc cleanups Christoph Hellwig
2026-09-24 9:57 ` [PATCH 1/9] xfs: centralize setting of buf_ops/buf_type/magic for rtblocks Christoph Hellwig
2026-09-24 9:57 ` [PATCH 2/9] xfs: factor out a xfs_rtfile_initialize_buf helper Christoph Hellwig
@ 2026-09-24 9:57 ` Christoph Hellwig
2026-09-24 20:13 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 4/9] xfs: cleanup xfs_verify_media_error Christoph Hellwig
` (6 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2026-09-24 9:57 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Darrick J . Wong, linux-xfs
Add a helper to calculate the rtblock payload start with or without the
self-describing metadata header.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/libxfs/xfs_rtbitmap.c | 9 ++-------
fs/xfs/libxfs/xfs_rtbitmap.h | 27 ++++++++++++---------------
2 files changed, 14 insertions(+), 22 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 5cadde81b5da..01536f4fb386 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -1411,7 +1411,6 @@ xfs_rtfile_initialize_block(
struct xfs_inode *ip = rtg->rtg_inodes[type];
struct xfs_trans *tp;
struct xfs_buf *bp;
- void *bufdata;
const size_t copylen = mp->m_blockwsize << XFS_WORDLOG;
int error;
@@ -1427,16 +1426,12 @@ xfs_rtfile_initialize_block(
xfs_trans_cancel(tp);
return error;
}
- bufdata = bp->b_addr;
xfs_rtfile_initialize_buf(rtg, type, bp, tp);
-
- if (xfs_has_rtgroups(mp))
- bufdata += sizeof(struct xfs_rtbuf_blkinfo);
if (data)
- memcpy(bufdata, data, copylen);
+ memcpy(xfs_rtblock_payload(bp), data, copylen);
else
- memset(bufdata, 0, copylen);
+ memset(xfs_rtblock_payload(bp), 0, copylen);
xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
return xfs_trans_commit(tp);
}
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
index 4a87e1fd3e99..750d74fbf4ed 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -20,6 +20,16 @@ struct xfs_rtalloc_args {
xfs_fileoff_t sumoff; /* summary block number */
};
+/* Return the payload of the buffer after the optional header. */
+static inline void *
+xfs_rtblock_payload(
+ struct xfs_buf *bp)
+{
+ if (!xfs_has_rtgroups(bp->b_mount))
+ return bp->b_addr;
+ return bp->b_addr + sizeof(struct xfs_rtbuf_blkinfo);
+}
+
static inline xfs_rtblock_t
xfs_rtx_to_rtb(
struct xfs_rtgroup *rtg,
@@ -221,14 +231,7 @@ xfs_rbmblock_wordptr(
struct xfs_rtalloc_args *args,
unsigned int index)
{
- struct xfs_mount *mp = args->mp;
- union xfs_rtword_raw *words;
- struct xfs_rtbuf_blkinfo *hdr = args->rbmbp->b_addr;
-
- if (xfs_has_rtgroups(mp))
- words = (union xfs_rtword_raw *)(hdr + 1);
- else
- words = args->rbmbp->b_addr;
+ union xfs_rtword_raw *words = xfs_rtblock_payload(args->rbmbp);
return words + index;
}
@@ -312,13 +315,7 @@ xfs_rsumblock_infoptr(
struct xfs_rtalloc_args *args,
unsigned int index)
{
- union xfs_suminfo_raw *info;
- struct xfs_rtbuf_blkinfo *hdr = args->sumbp->b_addr;
-
- if (xfs_has_rtgroups(args->mp))
- info = (union xfs_suminfo_raw *)(hdr + 1);
- else
- info = args->sumbp->b_addr;
+ union xfs_suminfo_raw *info = xfs_rtblock_payload(args->sumbp);
return info + index;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 4/9] xfs: cleanup xfs_verify_media_error
2026-09-24 9:57 misc cleanups Christoph Hellwig
` (2 preceding siblings ...)
2026-09-24 9:57 ` [PATCH 3/9] xfs: add a xfs_rtblock_payload helper Christoph Hellwig
@ 2026-09-24 9:57 ` Christoph Hellwig
2026-09-24 20:14 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 5/9] xfs: use bdev_rw_virt in xfs_verify_media Christoph Hellwig
` (5 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2026-09-24 9:57 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Darrick J . Wong, linux-xfs
Move all the reporting logic into xfs_verify_report_losses, and pass the
enum xfs_device instead of the group type to it. This keeps all the
reporting related conditions and translation confined to one place.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/xfs_verify_media.c | 46 +++++++++++++++++++--------------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/fs/xfs/xfs_verify_media.c b/fs/xfs/xfs_verify_media.c
index 5ead3976d511..8ce3773aa875 100644
--- a/fs/xfs/xfs_verify_media.c
+++ b/fs/xfs/xfs_verify_media.c
@@ -84,11 +84,14 @@ xfs_verify_report_data_lost(
return 0;
}
-/* Walk reverse mappings to look for all file data loss */
-static int
+/*
+ * Report data loss on the physical sectors, and if possible, walk the reverse
+ * mappings to also report the loss to the files mapped to these sectors.
+ */
+static void
xfs_verify_report_losses(
struct xfs_mount *mp,
- enum xfs_group_type type,
+ enum xfs_device dev,
xfs_daddr_t daddr,
u64 bblen)
{
@@ -97,13 +100,25 @@ xfs_verify_report_losses(
xfs_fsblock_t start_bno, end_bno;
uint32_t start_gno, end_gno;
int error;
+ enum xfs_group_type type;
+
+ xfs_healthmon_report_media(mp, dev, daddr, bblen);
+ if (!xfs_has_rmapbt(mp))
+ return;
- if (type == XG_TYPE_RTG) {
+ switch (dev) {
+ case XFS_DEV_RT:
start_bno = xfs_daddr_to_rtb(mp, daddr);
end_bno = xfs_daddr_to_rtb(mp, daddr + bblen - 1);
- } else {
+ type = XG_TYPE_RTG;
+ break;
+ case XFS_DEV_DATA:
start_bno = XFS_DADDR_TO_FSB(mp, daddr);
end_bno = XFS_DADDR_TO_FSB(mp, daddr + bblen - 1);
+ type = XG_TYPE_AG;
+ break;
+ default:
+ return;
}
tp = xfs_trans_alloc_empty(mp);
@@ -164,7 +179,6 @@ xfs_verify_report_losses(
}
xfs_trans_cancel(tp);
- return 0;
}
/*
@@ -236,25 +250,11 @@ xfs_verify_media_error(
case BLK_STS_PROTECTION:
case BLK_STS_IOERR:
case BLK_STS_MEDIUM:
+ if (me->me_flags & XFS_VERIFY_MEDIA_REPORT)
+ xfs_verify_report_losses(mp, me->me_dev, daddr,
+ bio_bbcount);
break;
default:
- return;
- }
-
- if (!(me->me_flags & XFS_VERIFY_MEDIA_REPORT))
- return;
-
- xfs_healthmon_report_media(mp, me->me_dev, daddr, bio_bbcount);
-
- if (!xfs_has_rmapbt(mp))
- return;
-
- switch (me->me_dev) {
- case XFS_DEV_DATA:
- xfs_verify_report_losses(mp, XG_TYPE_AG, daddr, bio_bbcount);
- break;
- case XFS_DEV_RT:
- xfs_verify_report_losses(mp, XG_TYPE_RTG, daddr, bio_bbcount);
break;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 5/9] xfs: use bdev_rw_virt in xfs_verify_media
2026-09-24 9:57 misc cleanups Christoph Hellwig
` (3 preceding siblings ...)
2026-09-24 9:57 ` [PATCH 4/9] xfs: cleanup xfs_verify_media_error Christoph Hellwig
@ 2026-09-24 9:57 ` Christoph Hellwig
2026-09-24 20:18 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 6/9] xfs: lift setting the NOFS context to xfs_end_io Christoph Hellwig
` (4 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2026-09-24 9:57 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Darrick J . Wong, linux-xfs
Use bdev_rw_virt for reading data from disk. This simply uses an
on-stack bio and bio_vec and removes the need to allocate an bio and
reset it for each iteration. Because bdev_rw_virt returns a negative
errno, pass that on to xfs_verify_media_error to avoid a double
conversion.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/xfs_verify_media.c | 41 +++++++++++----------------------------
1 file changed, 11 insertions(+), 30 deletions(-)
diff --git a/fs/xfs/xfs_verify_media.c b/fs/xfs/xfs_verify_media.c
index 8ce3773aa875..71f4d6c832a9 100644
--- a/fs/xfs/xfs_verify_media.c
+++ b/fs/xfs/xfs_verify_media.c
@@ -229,8 +229,10 @@ xfs_verify_media_error(
struct xfs_buftarg *btp,
xfs_daddr_t daddr,
unsigned int bio_bbcount,
- blk_status_t bio_status)
+ int error)
{
+ blk_status_t bio_status = errno_to_blk_status(error);
+
trace_xfs_verify_media_error(mp, me, btp->bt_dev, daddr, bio_bbcount,
bio_status);
@@ -239,7 +241,7 @@ xfs_verify_media_error(
* successfully verify any bytes at all.
*/
if (me->me_start_daddr == daddr)
- me->me_ioerror = -blk_status_to_errno(bio_status);
+ me->me_ioerror = -error;
/*
* PI validation failures, medium errors, or general IO errors are
@@ -266,7 +268,6 @@ xfs_verify_media(
struct xfs_verify_media *me)
{
struct xfs_buftarg *btp = NULL;
- struct bio *bio;
struct folio *folio;
xfs_daddr_t daddr;
uint64_t bbcount;
@@ -332,33 +333,16 @@ xfs_verify_media(
trace_xfs_verify_media(mp, me, btp->bt_dev, daddr, bbcount, folio);
- bio = bio_alloc(btp->bt_bdev, 1, REQ_OP_READ, GFP_KERNEL);
- if (!bio) {
- error = -ENOMEM;
- goto out_folio;
- }
-
- while (bbcount > 0) {
+ for (;;) {
unsigned int bio_bbcount;
- blk_status_t bio_status;
-
- bio_reset(bio, btp->bt_bdev, REQ_OP_READ);
- bio->bi_iter.bi_sector = daddr;
- bio_add_folio_nofail(bio, folio,
- min(bbcount << SECTOR_SHIFT, folio_size(folio)),
- 0);
- /*
- * Save the length of the bio before we submit it, because we
- * need the original daddr and length for reporting IO errors
- * if the bio fails.
- */
- bio_bbcount = bio->bi_iter.bi_size >> SECTOR_SHIFT;
- submit_bio_wait(bio);
- bio_status = bio->bi_status;
- if (bio_status != BLK_STS_OK) {
+ bio_bbcount = min(bbcount, folio_size(folio) >> SECTOR_SHIFT);
+ error = bdev_rw_virt(btp->bt_bdev, daddr, folio_address(folio),
+ bio_bbcount << SECTOR_SHIFT,
+ REQ_OP_READ);
+ if (error) {
xfs_verify_media_error(mp, me, btp, daddr, bio_bbcount,
- bio_status);
+ error);
error = 0;
break;
}
@@ -386,10 +370,7 @@ xfs_verify_media(
cond_resched();
}
- bio_put(bio);
-out_folio:
folio_put(folio);
-
if (error)
return error;
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 6/9] xfs: lift setting the NOFS context to xfs_end_io
2026-09-24 9:57 misc cleanups Christoph Hellwig
` (4 preceding siblings ...)
2026-09-24 9:57 ` [PATCH 5/9] xfs: use bdev_rw_virt in xfs_verify_media Christoph Hellwig
@ 2026-09-24 9:57 ` Christoph Hellwig
2026-09-24 20:18 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 7/9] xfs: split xfs_end_ioend_write Christoph Hellwig
` (3 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2026-09-24 9:57 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Darrick J . Wong, linux-xfs
No point in clearing and restoring it for every processed bio.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/xfs_ioend.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/fs/xfs/xfs_ioend.c b/fs/xfs/xfs_ioend.c
index e70be5b86f0b..258c6130bee8 100644
--- a/fs/xfs/xfs_ioend.c
+++ b/fs/xfs/xfs_ioend.c
@@ -175,16 +175,8 @@ xfs_end_ioend_write(
bool is_zoned = xfs_is_zoned_inode(ip);
xfs_off_t offset = ioend->io_offset;
size_t size = ioend->io_size;
- unsigned int nofs_flag;
int error;
- /*
- * We can allocate memory here while doing writeback on behalf of
- * memory reclaim. To avoid memory allocation deadlocks set the
- * task-wide nofs context for the following operations.
- */
- nofs_flag = memalloc_nofs_save();
-
/*
* Just clean up the in-memory structures if the fs has been shut down.
*/
@@ -241,7 +233,6 @@ xfs_end_ioend_write(
if (is_zoned)
xfs_ioend_put_open_zones(ioend);
iomap_finish_ioends(ioend, error);
- memalloc_nofs_restore(nofs_flag);
}
/*
@@ -266,6 +257,7 @@ xfs_end_io(
container_of(work, struct xfs_inode, i_ioend_work);
struct iomap_ioend *ioend;
struct list_head tmp;
+ unsigned int nofs_flag;
unsigned long flags;
spin_lock_irqsave(&ip->i_ioend_lock, flags);
@@ -273,6 +265,13 @@ xfs_end_io(
spin_unlock_irqrestore(&ip->i_ioend_lock, flags);
iomap_sort_ioends(&tmp);
+
+ /*
+ * We can allocate memory here while doing writeback on behalf of
+ * memory reclaim. To avoid memory allocation deadlocks set the
+ * task-wide nofs context for the following operations.
+ */
+ nofs_flag = memalloc_nofs_save();
while ((ioend = list_first_entry_or_null(&tmp, struct iomap_ioend,
io_list))) {
list_del_init(&ioend->io_list);
@@ -280,6 +279,7 @@ xfs_end_io(
xfs_end_ioend_write(ioend);
cond_resched();
}
+ memalloc_nofs_restore(nofs_flag);
}
void
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 7/9] xfs: split xfs_end_ioend_write
2026-09-24 9:57 misc cleanups Christoph Hellwig
` (5 preceding siblings ...)
2026-09-24 9:57 ` [PATCH 6/9] xfs: lift setting the NOFS context to xfs_end_io Christoph Hellwig
@ 2026-09-24 9:57 ` Christoph Hellwig
2026-09-24 20:26 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 8/9] xfs: factor out a xfs_zoned_fill_srcmap helper Christoph Hellwig
` (2 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2026-09-24 9:57 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Darrick J . Wong, linux-xfs
Split out a separate helper for the zoned I/O completions as the code
flow is pretty different already and will become even more so soon.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/xfs_ioend.c | 63 ++++++++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 24 deletions(-)
diff --git a/fs/xfs/xfs_ioend.c b/fs/xfs/xfs_ioend.c
index 258c6130bee8..f0e01ac34de8 100644
--- a/fs/xfs/xfs_ioend.c
+++ b/fs/xfs/xfs_ioend.c
@@ -147,11 +147,40 @@ xfs_ioend_submit_read(
}
static void
-xfs_ioend_put_open_zones(
+xfs_end_ioend_write_zoned(
struct iomap_ioend *ioend)
{
- struct iomap_ioend *tmp;
+ struct xfs_inode *ip = XFS_I(ioend->io_inode);
+ struct xfs_open_zone *oz = ioend->io_private;
+ struct iomap_ioend *tmp;
+ int error = -EIO;
+
+ ASSERT(!(ioend->io_flags & IOMAP_IOEND_SHARED));
+
+ if (xfs_is_shutdown(ip->i_mount))
+ goto done;
+ /*
+ * Zoned writes update the in-core open zone accounting before I/O
+ * submission. A failed write leaves that state inconsistent, so shut
+ * down the filesystem instead of letting later writers wait forever for
+ * open zone space to become available.
+ */
+ error = blk_status_to_errno(ioend->io_bio.bi_status);
+ if (unlikely(error)) {
+ xfs_force_shutdown(ip->i_mount, SHUTDOWN_META_IO_ERROR);
+ goto done;
+ }
+
+ error = xfs_zoned_end_io(ip, ioend->io_offset, ioend->io_size,
+ ioend->io_sector, oz, NULLFSBLOCK);
+ if (error)
+ goto done;
+
+ if (!(ioend->io_flags & IOMAP_IOEND_DIRECT) &&
+ xfs_ioend_is_append(ioend))
+ error = xfs_setfilesize(ip, ioend->io_offset, ioend->io_size);
+done:
/*
* Put the open zone for all ioends merged into this one (if any).
*/
@@ -162,8 +191,9 @@ xfs_ioend_put_open_zones(
* The main ioend might not have an open zone if the submission failed
* before xfs_zone_alloc_and_submit got called.
*/
- if (ioend->io_private)
- xfs_open_zone_put(ioend->io_private);
+ if (oz)
+ xfs_open_zone_put(oz);
+ iomap_finish_ioends(ioend, error);
}
static void
@@ -172,7 +202,6 @@ xfs_end_ioend_write(
{
struct xfs_inode *ip = XFS_I(ioend->io_inode);
struct xfs_mount *mp = ip->i_mount;
- bool is_zoned = xfs_is_zoned_inode(ip);
xfs_off_t offset = ioend->io_offset;
size_t size = ioend->io_size;
int error;
@@ -194,19 +223,7 @@ xfs_end_ioend_write(
*/
error = blk_status_to_errno(ioend->io_bio.bi_status);
if (unlikely(error)) {
- /*
- * Zoned writes update the in-core open zone accounting before
- * I/O submission. A failed write leaves that state
- * inconsistent, so shut down the filesystem instead of letting
- * later writers wait forever for open zone space to become
- * available.
- */
- if (is_zoned) {
- xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
- goto done;
- }
if (ioend->io_flags & IOMAP_IOEND_SHARED) {
- ASSERT(!is_zoned);
xfs_reflink_cancel_cow_range(ip, offset, size, true);
xfs_bmap_punch_delalloc_range(ip, XFS_DATA_FORK, offset,
offset + size, NULL);
@@ -217,10 +234,7 @@ xfs_end_ioend_write(
/*
* Success: commit the COW or unwritten blocks if needed.
*/
- if (is_zoned)
- error = xfs_zoned_end_io(ip, offset, size, ioend->io_sector,
- ioend->io_private, NULLFSBLOCK);
- else if (ioend->io_flags & IOMAP_IOEND_SHARED)
+ if (ioend->io_flags & IOMAP_IOEND_SHARED)
error = xfs_reflink_end_cow(ip, offset, size);
else if (ioend->io_flags & IOMAP_IOEND_UNWRITTEN)
error = xfs_iomap_write_unwritten(ip, offset, size, false);
@@ -230,8 +244,6 @@ xfs_end_ioend_write(
xfs_ioend_is_append(ioend))
error = xfs_setfilesize(ip, offset, size);
done:
- if (is_zoned)
- xfs_ioend_put_open_zones(ioend);
iomap_finish_ioends(ioend, error);
}
@@ -276,7 +288,10 @@ xfs_end_io(
io_list))) {
list_del_init(&ioend->io_list);
iomap_ioend_try_merge(ioend, &tmp);
- xfs_end_ioend_write(ioend);
+ if (xfs_is_zoned_inode(ip))
+ xfs_end_ioend_write_zoned(ioend);
+ else
+ xfs_end_ioend_write(ioend);
cond_resched();
}
memalloc_nofs_restore(nofs_flag);
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 8/9] xfs: factor out a xfs_zoned_fill_srcmap helper
2026-09-24 9:57 misc cleanups Christoph Hellwig
` (6 preceding siblings ...)
2026-09-24 9:57 ` [PATCH 7/9] xfs: split xfs_end_ioend_write Christoph Hellwig
@ 2026-09-24 9:57 ` Christoph Hellwig
2026-09-24 20:27 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 9/9] xfs: calculate end_fsb later in xfs_zoned_fill_srcmap Christoph Hellwig
2026-10-05 18:06 ` misc cleanups Carlos Maiolino
9 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2026-09-24 9:57 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Darrick J . Wong, linux-xfs
The code filling the srcmap in xfs_zoned_buffered_write_iomap_begin isn't
terribly complicated, but fairly deeply indented and will become a bit
more complex soon. Factor it into a helper and add some comments.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/xfs_iomap.c | 53 ++++++++++++++++++++++++++++++----------------
1 file changed, 35 insertions(+), 18 deletions(-)
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 7c6238fed61e..7bc17f179be7 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -1588,6 +1588,37 @@ xfs_bmapi_reserve_delalloc(
return error;
}
+static int
+xfs_zoned_fill_srcmap(
+ struct xfs_inode *ip,
+ xfs_fileoff_t offset_fsb,
+ xfs_fileoff_t *end_fsb,
+ unsigned flags,
+ struct iomap *srcmap)
+{
+ struct xfs_bmbt_irec smap;
+ struct xfs_iext_cursor scur;
+
+ if (!xfs_iext_lookup_extent(ip, &ip->i_df, offset_fsb, &scur, &smap))
+ smap.br_startoff = *end_fsb; /* fake hole until EOF */
+ if (smap.br_startoff > offset_fsb) {
+ /*
+ * There is a hole at @offset_fsb. Only map until the end of
+ * the of it.
+ */
+ *end_fsb = min(*end_fsb, smap.br_startoff);
+ return 0;
+ }
+
+ /*
+ * There is a data fork mapping, only map until the end of it.
+ */
+ *end_fsb = min(*end_fsb, smap.br_startoff + smap.br_blockcount);
+ xfs_trim_extent(&smap, offset_fsb, *end_fsb - offset_fsb);
+ return xfs_bmbt_to_iomap(ip, srcmap, &smap, flags, 0,
+ xfs_iomap_inode_sequence(ip, 0));
+}
+
static int
xfs_zoned_buffered_write_iomap_begin(
struct inode *inode,
@@ -1655,24 +1686,10 @@ xfs_zoned_buffered_write_iomap_begin(
if (!IS_ALIGNED(offset, mp->m_sb.sb_blocksize) ||
!IS_ALIGNED(offset + count, mp->m_sb.sb_blocksize) ||
(flags & IOMAP_ZERO)) {
- struct xfs_bmbt_irec smap;
- struct xfs_iext_cursor scur;
-
- if (!xfs_iext_lookup_extent(ip, &ip->i_df, offset_fsb, &scur,
- &smap))
- smap.br_startoff = end_fsb; /* fake hole until EOF */
- if (smap.br_startoff > offset_fsb) {
- end_fsb = min(end_fsb, smap.br_startoff);
- } else {
- end_fsb = min(end_fsb,
- smap.br_startoff + smap.br_blockcount);
- xfs_trim_extent(&smap, offset_fsb,
- end_fsb - offset_fsb);
- error = xfs_bmbt_to_iomap(ip, srcmap, &smap, flags, 0,
- xfs_iomap_inode_sequence(ip, 0));
- if (error)
- goto out_unlock;
- }
+ error = xfs_zoned_fill_srcmap(ip, offset_fsb, &end_fsb, flags,
+ srcmap);
+ if (error)
+ goto out_unlock;
}
if (!ip->i_cowfp)
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 9/9] xfs: calculate end_fsb later in xfs_zoned_fill_srcmap
2026-09-24 9:57 misc cleanups Christoph Hellwig
` (7 preceding siblings ...)
2026-09-24 9:57 ` [PATCH 8/9] xfs: factor out a xfs_zoned_fill_srcmap helper Christoph Hellwig
@ 2026-09-24 9:57 ` Christoph Hellwig
2026-09-24 20:29 ` Darrick J. Wong
2026-10-05 18:06 ` misc cleanups Carlos Maiolino
9 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2026-09-24 9:57 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Darrick J . Wong, linux-xfs
xfs_trim_extent doesn't need the updated end_fsb as it already is
limited by the smap range. Move the end_fsb calculation later to
prepare additional reasons that could reduce the smap range.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/xfs_iomap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 7bc17f179be7..6701be9325ef 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -1613,8 +1613,8 @@ xfs_zoned_fill_srcmap(
/*
* There is a data fork mapping, only map until the end of it.
*/
- *end_fsb = min(*end_fsb, smap.br_startoff + smap.br_blockcount);
xfs_trim_extent(&smap, offset_fsb, *end_fsb - offset_fsb);
+ *end_fsb = min(*end_fsb, smap.br_startoff + smap.br_blockcount);
return xfs_bmbt_to_iomap(ip, srcmap, &smap, flags, 0,
xfs_iomap_inode_sequence(ip, 0));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 1/9] xfs: centralize setting of buf_ops/buf_type/magic for rtblocks
2026-09-24 9:57 ` [PATCH 1/9] xfs: centralize setting of buf_ops/buf_type/magic for rtblocks Christoph Hellwig
@ 2026-09-24 19:01 ` Darrick J. Wong
0 siblings, 0 replies; 21+ messages in thread
From: Darrick J. Wong @ 2026-09-24 19:01 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Carlos Maiolino, linux-xfs
On Thu, Sep 24, 2026 at 11:57:02AM +0200, Christoph Hellwig wrote:
> Add two tables for the buf_ops and buf_type, and derive the magic from
> the buf_ops to make have a single source of truth for the different RT
> block variants. This cleans up the existing code and makes adding another
> type of block/file easier.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Seems like a reasonable hoist here.
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> fs/xfs/libxfs/xfs_rtbitmap.c | 40 +++++++++++++++++++++---------------
> fs/xfs/libxfs/xfs_rtbitmap.h | 15 ++------------
> 2 files changed, 25 insertions(+), 30 deletions(-)
>
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
> index e62786e90f7b..3f7877220e05 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.c
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.c
> @@ -125,6 +125,26 @@ const struct xfs_buf_ops xfs_rtsummary_buf_ops = {
> .verify_struct = xfs_rtbuf_verify,
> };
>
> +static const struct xfs_buf_ops *xfs_rtblock_buf_ops[XFS_RTGI_MAX] = {
> + [XFS_RTGI_SUMMARY] = &xfs_rtsummary_buf_ops,
> + [XFS_RTGI_BITMAP] = &xfs_rtbitmap_buf_ops,
> +};
> +
> +const struct xfs_buf_ops *
> +xfs_rtblock_ops(
> + struct xfs_mount *mp,
> + enum xfs_rtg_inodes type)
> +{
> + if (!xfs_has_rtgroups(mp))
> + return &xfs_rtbuf_ops;
> + return xfs_rtblock_buf_ops[type];
> +}
> +
> +static enum xfs_blft xfs_rtblock_buf_types[XFS_RTGI_MAX] = {
> + [XFS_RTGI_SUMMARY] = XFS_BLFT_RTSUMMARY_BUF,
> + [XFS_RTGI_BITMAP] = XFS_BLFT_RTBITMAP_BUF,
> +};
> +
> /* Release cached rt bitmap and summary buffers. */
> void
> xfs_rtbuf_cache_relse(
> @@ -158,7 +178,6 @@ xfs_rtbuf_get(
> xfs_fileoff_t *coffp; /* cached block number */
> struct xfs_buf *bp; /* block buffer, result */
> struct xfs_bmbt_irec map;
> - enum xfs_blft buf_type;
> int nmap = 1;
> int error;
>
> @@ -166,12 +185,10 @@ xfs_rtbuf_get(
> case XFS_RTGI_SUMMARY:
> cbpp = &args->sumbp;
> coffp = &args->sumoff;
> - buf_type = XFS_BLFT_RTSUMMARY_BUF;
> break;
> case XFS_RTGI_BITMAP:
> cbpp = &args->rbmbp;
> coffp = &args->rbmoff;
> - buf_type = XFS_BLFT_RTBITMAP_BUF;
> break;
> default:
> return -EINVAL;
> @@ -222,7 +239,7 @@ xfs_rtbuf_get(
> }
> }
>
> - xfs_trans_buf_set_type(args->tp, bp, buf_type);
> + xfs_trans_buf_set_type(args->tp, bp, xfs_rtblock_buf_types[type]);
> *cbpp = bp;
> *coffp = block;
> return 0;
> @@ -1375,16 +1392,8 @@ xfs_rtfile_initialize_block(
> struct xfs_buf *bp;
> void *bufdata;
> const size_t copylen = mp->m_blockwsize << XFS_WORDLOG;
> - enum xfs_blft buf_type;
> int error;
>
> - if (type == XFS_RTGI_BITMAP)
> - buf_type = XFS_BLFT_RTBITMAP_BUF;
> - else if (type == XFS_RTGI_SUMMARY)
> - buf_type = XFS_BLFT_RTSUMMARY_BUF;
> - else
> - return -EINVAL;
> -
> error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero, 0, 0, 0, &tp);
> if (error)
> return error;
> @@ -1399,16 +1408,13 @@ xfs_rtfile_initialize_block(
> }
> bufdata = bp->b_addr;
>
> - xfs_trans_buf_set_type(tp, bp, buf_type);
> + xfs_trans_buf_set_type(tp, bp, xfs_rtblock_buf_types[type]);
> bp->b_ops = xfs_rtblock_ops(mp, type);
>
> if (xfs_has_rtgroups(mp)) {
> struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
>
> - if (type == XFS_RTGI_BITMAP)
> - hdr->rt_magic = cpu_to_be32(XFS_RTBITMAP_MAGIC);
> - else
> - hdr->rt_magic = cpu_to_be32(XFS_RTSUMMARY_MAGIC);
> + hdr->rt_magic = bp->b_ops->magic[1];
> hdr->rt_owner = cpu_to_be64(I_INO(ip));
> hdr->rt_blkno = cpu_to_be64(XFS_FSB_TO_DADDR(mp, fsbno));
> hdr->rt_lsn = 0;
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
> index 22e5d9cd95f4..375cc48e1a53 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.h
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.h
> @@ -354,19 +354,6 @@ xfs_suminfo_add(
> return info->old;
> }
>
> -static inline const struct xfs_buf_ops *
> -xfs_rtblock_ops(
> - struct xfs_mount *mp,
> - enum xfs_rtg_inodes type)
> -{
> - if (xfs_has_rtgroups(mp)) {
> - if (type == XFS_RTGI_SUMMARY)
> - return &xfs_rtsummary_buf_ops;
> - return &xfs_rtbitmap_buf_ops;
> - }
> - return &xfs_rtbuf_ops;
> -}
> -
> /*
> * Functions for walking free space rtextents in the realtime bitmap.
> */
> @@ -419,6 +406,8 @@ xfs_filblks_t xfs_rtbitmap_blockcount_len(struct xfs_mount *mp,
> xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
> unsigned int *rsumlevels);
>
> +const struct xfs_buf_ops *xfs_rtblock_ops(struct xfs_mount *mp,
> + enum xfs_rtg_inodes type);
> int xfs_rtfile_initialize_blocks(struct xfs_rtgroup *rtg,
> enum xfs_rtg_inodes type, xfs_fileoff_t offset_fsb,
> xfs_fileoff_t end_fsb, void *data);
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/9] xfs: factor out a xfs_rtfile_initialize_buf helper
2026-09-24 9:57 ` [PATCH 2/9] xfs: factor out a xfs_rtfile_initialize_buf helper Christoph Hellwig
@ 2026-09-24 19:02 ` Darrick J. Wong
0 siblings, 0 replies; 21+ messages in thread
From: Darrick J. Wong @ 2026-09-24 19:02 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Carlos Maiolino, linux-xfs
On Thu, Sep 24, 2026 at 11:57:03AM +0200, Christoph Hellwig wrote:
> Share the code to initialize the header and buf ops for rtfile blocks
> into a single helper.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> fs/xfs/libxfs/xfs_rtbitmap.c | 38 +++++++++++++++++++++------------
> fs/xfs/libxfs/xfs_rtbitmap.h | 3 +++
> fs/xfs/scrub/rtbitmap_repair.c | 15 +------------
> fs/xfs/scrub/rtsummary_repair.c | 15 +------------
> 4 files changed, 29 insertions(+), 42 deletions(-)
Nice cleanup!
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
>
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
> index 3f7877220e05..5cadde81b5da 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.c
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.c
> @@ -1378,6 +1378,27 @@ xfs_rtfile_alloc_blocks(
> return error;
> }
>
> +void
> +xfs_rtfile_initialize_buf(
> + struct xfs_rtgroup *rtg,
> + enum xfs_rtg_inodes type,
> + struct xfs_buf *bp,
> + struct xfs_trans *tp)
> +{
> + bp->b_ops = xfs_rtblock_ops(bp->b_mount, type);
> + if (tp)
> + xfs_trans_buf_set_type(tp, bp, xfs_rtblock_buf_types[type]);
> + if (xfs_has_rtgroups(bp->b_mount)) {
> + struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
> +
> + hdr->rt_magic = bp->b_ops->magic[1];
> + hdr->rt_owner = cpu_to_be64(I_INO(rtg->rtg_inodes[type]));
> + hdr->rt_blkno = cpu_to_be64(xfs_buf_daddr(bp));
> + hdr->rt_lsn = 0;
> + uuid_copy(&hdr->rt_uuid, &bp->b_mount->m_sb.sb_meta_uuid);
> + }
> +}
> +
> /* Get a buffer for the block. */
> static int
> xfs_rtfile_initialize_block(
> @@ -1408,21 +1429,10 @@ xfs_rtfile_initialize_block(
> }
> bufdata = bp->b_addr;
>
> - xfs_trans_buf_set_type(tp, bp, xfs_rtblock_buf_types[type]);
> - bp->b_ops = xfs_rtblock_ops(mp, type);
> -
> - if (xfs_has_rtgroups(mp)) {
> - struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
> -
> - hdr->rt_magic = bp->b_ops->magic[1];
> - hdr->rt_owner = cpu_to_be64(I_INO(ip));
> - hdr->rt_blkno = cpu_to_be64(XFS_FSB_TO_DADDR(mp, fsbno));
> - hdr->rt_lsn = 0;
> - uuid_copy(&hdr->rt_uuid, &mp->m_sb.sb_meta_uuid);
> -
> - bufdata += sizeof(*hdr);
> - }
> + xfs_rtfile_initialize_buf(rtg, type, bp, tp);
>
> + if (xfs_has_rtgroups(mp))
> + bufdata += sizeof(struct xfs_rtbuf_blkinfo);
> if (data)
> memcpy(bufdata, data, copylen);
> else
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
> index 375cc48e1a53..4a87e1fd3e99 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.h
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.h
> @@ -408,6 +408,9 @@ xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
>
> const struct xfs_buf_ops *xfs_rtblock_ops(struct xfs_mount *mp,
> enum xfs_rtg_inodes type);
> +void xfs_rtfile_initialize_buf(struct xfs_rtgroup *rtg,
> + enum xfs_rtg_inodes type, struct xfs_buf *bp,
> + struct xfs_trans *tp);
> int xfs_rtfile_initialize_blocks(struct xfs_rtgroup *rtg,
> enum xfs_rtg_inodes type, xfs_fileoff_t offset_fsb,
> xfs_fileoff_t end_fsb, void *data);
> diff --git a/fs/xfs/scrub/rtbitmap_repair.c b/fs/xfs/scrub/rtbitmap_repair.c
> index 442a17bf9720..6a2efe3115f4 100644
> --- a/fs/xfs/scrub/rtbitmap_repair.c
> +++ b/fs/xfs/scrub/rtbitmap_repair.c
> @@ -383,21 +383,8 @@ xrep_rtbitmap_prep_buf(
> if (error)
> return error;
>
> - if (xfs_has_rtgroups(sc->mp)) {
> - struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
> -
> - hdr->rt_magic = cpu_to_be32(XFS_RTBITMAP_MAGIC);
> - hdr->rt_owner = cpu_to_be64(I_INO(sc->ip));
> - hdr->rt_blkno = cpu_to_be64(xfs_buf_daddr(bp));
> - hdr->rt_lsn = 0;
> - uuid_copy(&hdr->rt_uuid, &sc->mp->m_sb.sb_meta_uuid);
> - bp->b_ops = &xfs_rtbitmap_buf_ops;
> - } else {
> - bp->b_ops = &xfs_rtbuf_ops;
> - }
> -
> + xfs_rtfile_initialize_buf(sc->sr.rtg, XFS_RTGI_BITMAP, bp, sc->tp);
> rtb->prep_wordoff += mp->m_blockwsize;
> - xfs_trans_buf_set_type(sc->tp, bp, XFS_BLFT_RTBITMAP_BUF);
> return 0;
> }
>
> diff --git a/fs/xfs/scrub/rtsummary_repair.c b/fs/xfs/scrub/rtsummary_repair.c
> index f065c3e51ce2..6a66113f6562 100644
> --- a/fs/xfs/scrub/rtsummary_repair.c
> +++ b/fs/xfs/scrub/rtsummary_repair.c
> @@ -87,21 +87,8 @@ xrep_rtsummary_prep_buf(
> if (error)
> return error;
>
> - if (xfs_has_rtgroups(sc->mp)) {
> - struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
> -
> - hdr->rt_magic = cpu_to_be32(XFS_RTSUMMARY_MAGIC);
> - hdr->rt_owner = cpu_to_be64(I_INO(sc->ip));
> - hdr->rt_blkno = cpu_to_be64(xfs_buf_daddr(bp));
> - hdr->rt_lsn = 0;
> - uuid_copy(&hdr->rt_uuid, &sc->mp->m_sb.sb_meta_uuid);
> - bp->b_ops = &xfs_rtsummary_buf_ops;
> - } else {
> - bp->b_ops = &xfs_rtbuf_ops;
> - }
> -
> + xfs_rtfile_initialize_buf(sc->sr.rtg, XFS_RTGI_SUMMARY, bp, sc->tp);
> rts->prep_wordoff += mp->m_blockwsize;
> - xfs_trans_buf_set_type(sc->tp, bp, XFS_BLFT_RTSUMMARY_BUF);
> return 0;
> }
>
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/9] xfs: add a xfs_rtblock_payload helper
2026-09-24 9:57 ` [PATCH 3/9] xfs: add a xfs_rtblock_payload helper Christoph Hellwig
@ 2026-09-24 20:13 ` Darrick J. Wong
0 siblings, 0 replies; 21+ messages in thread
From: Darrick J. Wong @ 2026-09-24 20:13 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Carlos Maiolino, linux-xfs
On Thu, Sep 24, 2026 at 11:57:04AM +0200, Christoph Hellwig wrote:
> Add a helper to calculate the rtblock payload start with or without the
> self-describing metadata header.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Nice refactoring!
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> fs/xfs/libxfs/xfs_rtbitmap.c | 9 ++-------
> fs/xfs/libxfs/xfs_rtbitmap.h | 27 ++++++++++++---------------
> 2 files changed, 14 insertions(+), 22 deletions(-)
>
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
> index 5cadde81b5da..01536f4fb386 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.c
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.c
> @@ -1411,7 +1411,6 @@ xfs_rtfile_initialize_block(
> struct xfs_inode *ip = rtg->rtg_inodes[type];
> struct xfs_trans *tp;
> struct xfs_buf *bp;
> - void *bufdata;
> const size_t copylen = mp->m_blockwsize << XFS_WORDLOG;
> int error;
>
> @@ -1427,16 +1426,12 @@ xfs_rtfile_initialize_block(
> xfs_trans_cancel(tp);
> return error;
> }
> - bufdata = bp->b_addr;
>
> xfs_rtfile_initialize_buf(rtg, type, bp, tp);
> -
> - if (xfs_has_rtgroups(mp))
> - bufdata += sizeof(struct xfs_rtbuf_blkinfo);
> if (data)
> - memcpy(bufdata, data, copylen);
> + memcpy(xfs_rtblock_payload(bp), data, copylen);
> else
> - memset(bufdata, 0, copylen);
> + memset(xfs_rtblock_payload(bp), 0, copylen);
> xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
> return xfs_trans_commit(tp);
> }
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
> index 4a87e1fd3e99..750d74fbf4ed 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.h
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.h
> @@ -20,6 +20,16 @@ struct xfs_rtalloc_args {
> xfs_fileoff_t sumoff; /* summary block number */
> };
>
> +/* Return the payload of the buffer after the optional header. */
> +static inline void *
> +xfs_rtblock_payload(
> + struct xfs_buf *bp)
> +{
> + if (!xfs_has_rtgroups(bp->b_mount))
> + return bp->b_addr;
> + return bp->b_addr + sizeof(struct xfs_rtbuf_blkinfo);
> +}
> +
> static inline xfs_rtblock_t
> xfs_rtx_to_rtb(
> struct xfs_rtgroup *rtg,
> @@ -221,14 +231,7 @@ xfs_rbmblock_wordptr(
> struct xfs_rtalloc_args *args,
> unsigned int index)
> {
> - struct xfs_mount *mp = args->mp;
> - union xfs_rtword_raw *words;
> - struct xfs_rtbuf_blkinfo *hdr = args->rbmbp->b_addr;
> -
> - if (xfs_has_rtgroups(mp))
> - words = (union xfs_rtword_raw *)(hdr + 1);
> - else
> - words = args->rbmbp->b_addr;
> + union xfs_rtword_raw *words = xfs_rtblock_payload(args->rbmbp);
>
> return words + index;
> }
> @@ -312,13 +315,7 @@ xfs_rsumblock_infoptr(
> struct xfs_rtalloc_args *args,
> unsigned int index)
> {
> - union xfs_suminfo_raw *info;
> - struct xfs_rtbuf_blkinfo *hdr = args->sumbp->b_addr;
> -
> - if (xfs_has_rtgroups(args->mp))
> - info = (union xfs_suminfo_raw *)(hdr + 1);
> - else
> - info = args->sumbp->b_addr;
> + union xfs_suminfo_raw *info = xfs_rtblock_payload(args->sumbp);
>
> return info + index;
> }
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/9] xfs: cleanup xfs_verify_media_error
2026-09-24 9:57 ` [PATCH 4/9] xfs: cleanup xfs_verify_media_error Christoph Hellwig
@ 2026-09-24 20:14 ` Darrick J. Wong
0 siblings, 0 replies; 21+ messages in thread
From: Darrick J. Wong @ 2026-09-24 20:14 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Carlos Maiolino, linux-xfs
On Thu, Sep 24, 2026 at 11:57:05AM +0200, Christoph Hellwig wrote:
> Move all the reporting logic into xfs_verify_report_losses, and pass the
> enum xfs_device instead of the group type to it. This keeps all the
> reporting related conditions and translation confined to one place.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks good,
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> fs/xfs/xfs_verify_media.c | 46 +++++++++++++++++++--------------------
> 1 file changed, 23 insertions(+), 23 deletions(-)
>
> diff --git a/fs/xfs/xfs_verify_media.c b/fs/xfs/xfs_verify_media.c
> index 5ead3976d511..8ce3773aa875 100644
> --- a/fs/xfs/xfs_verify_media.c
> +++ b/fs/xfs/xfs_verify_media.c
> @@ -84,11 +84,14 @@ xfs_verify_report_data_lost(
> return 0;
> }
>
> -/* Walk reverse mappings to look for all file data loss */
> -static int
> +/*
> + * Report data loss on the physical sectors, and if possible, walk the reverse
> + * mappings to also report the loss to the files mapped to these sectors.
> + */
> +static void
> xfs_verify_report_losses(
> struct xfs_mount *mp,
> - enum xfs_group_type type,
> + enum xfs_device dev,
> xfs_daddr_t daddr,
> u64 bblen)
> {
> @@ -97,13 +100,25 @@ xfs_verify_report_losses(
> xfs_fsblock_t start_bno, end_bno;
> uint32_t start_gno, end_gno;
> int error;
> + enum xfs_group_type type;
> +
> + xfs_healthmon_report_media(mp, dev, daddr, bblen);
> + if (!xfs_has_rmapbt(mp))
> + return;
>
> - if (type == XG_TYPE_RTG) {
> + switch (dev) {
> + case XFS_DEV_RT:
> start_bno = xfs_daddr_to_rtb(mp, daddr);
> end_bno = xfs_daddr_to_rtb(mp, daddr + bblen - 1);
> - } else {
> + type = XG_TYPE_RTG;
> + break;
> + case XFS_DEV_DATA:
> start_bno = XFS_DADDR_TO_FSB(mp, daddr);
> end_bno = XFS_DADDR_TO_FSB(mp, daddr + bblen - 1);
> + type = XG_TYPE_AG;
> + break;
> + default:
> + return;
> }
>
> tp = xfs_trans_alloc_empty(mp);
> @@ -164,7 +179,6 @@ xfs_verify_report_losses(
> }
>
> xfs_trans_cancel(tp);
> - return 0;
> }
>
> /*
> @@ -236,25 +250,11 @@ xfs_verify_media_error(
> case BLK_STS_PROTECTION:
> case BLK_STS_IOERR:
> case BLK_STS_MEDIUM:
> + if (me->me_flags & XFS_VERIFY_MEDIA_REPORT)
> + xfs_verify_report_losses(mp, me->me_dev, daddr,
> + bio_bbcount);
> break;
> default:
> - return;
> - }
> -
> - if (!(me->me_flags & XFS_VERIFY_MEDIA_REPORT))
> - return;
> -
> - xfs_healthmon_report_media(mp, me->me_dev, daddr, bio_bbcount);
> -
> - if (!xfs_has_rmapbt(mp))
> - return;
> -
> - switch (me->me_dev) {
> - case XFS_DEV_DATA:
> - xfs_verify_report_losses(mp, XG_TYPE_AG, daddr, bio_bbcount);
> - break;
> - case XFS_DEV_RT:
> - xfs_verify_report_losses(mp, XG_TYPE_RTG, daddr, bio_bbcount);
> break;
> }
> }
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 5/9] xfs: use bdev_rw_virt in xfs_verify_media
2026-09-24 9:57 ` [PATCH 5/9] xfs: use bdev_rw_virt in xfs_verify_media Christoph Hellwig
@ 2026-09-24 20:18 ` Darrick J. Wong
0 siblings, 0 replies; 21+ messages in thread
From: Darrick J. Wong @ 2026-09-24 20:18 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Carlos Maiolino, linux-xfs
On Thu, Sep 24, 2026 at 11:57:06AM +0200, Christoph Hellwig wrote:
> Use bdev_rw_virt for reading data from disk. This simply uses an
> on-stack bio and bio_vec and removes the need to allocate an bio and
> reset it for each iteration. Because bdev_rw_virt returns a negative
> errno, pass that on to xfs_verify_media_error to avoid a double
> conversion.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Nice cleanup!
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> fs/xfs/xfs_verify_media.c | 41 +++++++++++----------------------------
> 1 file changed, 11 insertions(+), 30 deletions(-)
>
> diff --git a/fs/xfs/xfs_verify_media.c b/fs/xfs/xfs_verify_media.c
> index 8ce3773aa875..71f4d6c832a9 100644
> --- a/fs/xfs/xfs_verify_media.c
> +++ b/fs/xfs/xfs_verify_media.c
> @@ -229,8 +229,10 @@ xfs_verify_media_error(
> struct xfs_buftarg *btp,
> xfs_daddr_t daddr,
> unsigned int bio_bbcount,
> - blk_status_t bio_status)
> + int error)
> {
> + blk_status_t bio_status = errno_to_blk_status(error);
> +
> trace_xfs_verify_media_error(mp, me, btp->bt_dev, daddr, bio_bbcount,
> bio_status);
>
> @@ -239,7 +241,7 @@ xfs_verify_media_error(
> * successfully verify any bytes at all.
> */
> if (me->me_start_daddr == daddr)
> - me->me_ioerror = -blk_status_to_errno(bio_status);
> + me->me_ioerror = -error;
>
> /*
> * PI validation failures, medium errors, or general IO errors are
> @@ -266,7 +268,6 @@ xfs_verify_media(
> struct xfs_verify_media *me)
> {
> struct xfs_buftarg *btp = NULL;
> - struct bio *bio;
> struct folio *folio;
> xfs_daddr_t daddr;
> uint64_t bbcount;
> @@ -332,33 +333,16 @@ xfs_verify_media(
>
> trace_xfs_verify_media(mp, me, btp->bt_dev, daddr, bbcount, folio);
>
> - bio = bio_alloc(btp->bt_bdev, 1, REQ_OP_READ, GFP_KERNEL);
> - if (!bio) {
> - error = -ENOMEM;
> - goto out_folio;
> - }
> -
> - while (bbcount > 0) {
> + for (;;) {
> unsigned int bio_bbcount;
> - blk_status_t bio_status;
> -
> - bio_reset(bio, btp->bt_bdev, REQ_OP_READ);
> - bio->bi_iter.bi_sector = daddr;
> - bio_add_folio_nofail(bio, folio,
> - min(bbcount << SECTOR_SHIFT, folio_size(folio)),
> - 0);
>
> - /*
> - * Save the length of the bio before we submit it, because we
> - * need the original daddr and length for reporting IO errors
> - * if the bio fails.
> - */
> - bio_bbcount = bio->bi_iter.bi_size >> SECTOR_SHIFT;
> - submit_bio_wait(bio);
> - bio_status = bio->bi_status;
> - if (bio_status != BLK_STS_OK) {
> + bio_bbcount = min(bbcount, folio_size(folio) >> SECTOR_SHIFT);
> + error = bdev_rw_virt(btp->bt_bdev, daddr, folio_address(folio),
> + bio_bbcount << SECTOR_SHIFT,
> + REQ_OP_READ);
> + if (error) {
> xfs_verify_media_error(mp, me, btp, daddr, bio_bbcount,
> - bio_status);
> + error);
> error = 0;
> break;
> }
> @@ -386,10 +370,7 @@ xfs_verify_media(
> cond_resched();
> }
>
> - bio_put(bio);
> -out_folio:
> folio_put(folio);
> -
> if (error)
> return error;
>
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 6/9] xfs: lift setting the NOFS context to xfs_end_io
2026-09-24 9:57 ` [PATCH 6/9] xfs: lift setting the NOFS context to xfs_end_io Christoph Hellwig
@ 2026-09-24 20:18 ` Darrick J. Wong
0 siblings, 0 replies; 21+ messages in thread
From: Darrick J. Wong @ 2026-09-24 20:18 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Carlos Maiolino, linux-xfs
On Thu, Sep 24, 2026 at 11:57:07AM +0200, Christoph Hellwig wrote:
> No point in clearing and restoring it for every processed bio.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Agreed.
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> fs/xfs/xfs_ioend.c | 18 +++++++++---------
> 1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/fs/xfs/xfs_ioend.c b/fs/xfs/xfs_ioend.c
> index e70be5b86f0b..258c6130bee8 100644
> --- a/fs/xfs/xfs_ioend.c
> +++ b/fs/xfs/xfs_ioend.c
> @@ -175,16 +175,8 @@ xfs_end_ioend_write(
> bool is_zoned = xfs_is_zoned_inode(ip);
> xfs_off_t offset = ioend->io_offset;
> size_t size = ioend->io_size;
> - unsigned int nofs_flag;
> int error;
>
> - /*
> - * We can allocate memory here while doing writeback on behalf of
> - * memory reclaim. To avoid memory allocation deadlocks set the
> - * task-wide nofs context for the following operations.
> - */
> - nofs_flag = memalloc_nofs_save();
> -
> /*
> * Just clean up the in-memory structures if the fs has been shut down.
> */
> @@ -241,7 +233,6 @@ xfs_end_ioend_write(
> if (is_zoned)
> xfs_ioend_put_open_zones(ioend);
> iomap_finish_ioends(ioend, error);
> - memalloc_nofs_restore(nofs_flag);
> }
>
> /*
> @@ -266,6 +257,7 @@ xfs_end_io(
> container_of(work, struct xfs_inode, i_ioend_work);
> struct iomap_ioend *ioend;
> struct list_head tmp;
> + unsigned int nofs_flag;
> unsigned long flags;
>
> spin_lock_irqsave(&ip->i_ioend_lock, flags);
> @@ -273,6 +265,13 @@ xfs_end_io(
> spin_unlock_irqrestore(&ip->i_ioend_lock, flags);
>
> iomap_sort_ioends(&tmp);
> +
> + /*
> + * We can allocate memory here while doing writeback on behalf of
> + * memory reclaim. To avoid memory allocation deadlocks set the
> + * task-wide nofs context for the following operations.
> + */
> + nofs_flag = memalloc_nofs_save();
> while ((ioend = list_first_entry_or_null(&tmp, struct iomap_ioend,
> io_list))) {
> list_del_init(&ioend->io_list);
> @@ -280,6 +279,7 @@ xfs_end_io(
> xfs_end_ioend_write(ioend);
> cond_resched();
> }
> + memalloc_nofs_restore(nofs_flag);
> }
>
> void
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 7/9] xfs: split xfs_end_ioend_write
2026-09-24 9:57 ` [PATCH 7/9] xfs: split xfs_end_ioend_write Christoph Hellwig
@ 2026-09-24 20:26 ` Darrick J. Wong
2026-09-25 5:46 ` Christoph Hellwig
0 siblings, 1 reply; 21+ messages in thread
From: Darrick J. Wong @ 2026-09-24 20:26 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Carlos Maiolino, linux-xfs
On Thu, Sep 24, 2026 at 11:57:08AM +0200, Christoph Hellwig wrote:
> Split out a separate helper for the zoned I/O completions as the code
> flow is pretty different already and will become even more so soon.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks ok,
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> fs/xfs/xfs_ioend.c | 63 ++++++++++++++++++++++++++++------------------
> 1 file changed, 39 insertions(+), 24 deletions(-)
>
> diff --git a/fs/xfs/xfs_ioend.c b/fs/xfs/xfs_ioend.c
> index 258c6130bee8..f0e01ac34de8 100644
> --- a/fs/xfs/xfs_ioend.c
> +++ b/fs/xfs/xfs_ioend.c
> @@ -147,11 +147,40 @@ xfs_ioend_submit_read(
> }
>
> static void
> -xfs_ioend_put_open_zones(
> +xfs_end_ioend_write_zoned(
> struct iomap_ioend *ioend)
> {
> - struct iomap_ioend *tmp;
> + struct xfs_inode *ip = XFS_I(ioend->io_inode);
> + struct xfs_open_zone *oz = ioend->io_private;
> + struct iomap_ioend *tmp;
> + int error = -EIO;
> +
> + ASSERT(!(ioend->io_flags & IOMAP_IOEND_SHARED));
> +
> + if (xfs_is_shutdown(ip->i_mount))
> + goto done;
>
> + /*
> + * Zoned writes update the in-core open zone accounting before I/O
> + * submission. A failed write leaves that state inconsistent, so shut
> + * down the filesystem instead of letting later writers wait forever for
> + * open zone space to become available.
> + */
> + error = blk_status_to_errno(ioend->io_bio.bi_status);
> + if (unlikely(error)) {
> + xfs_force_shutdown(ip->i_mount, SHUTDOWN_META_IO_ERROR);
> + goto done;
> + }
> +
> + error = xfs_zoned_end_io(ip, ioend->io_offset, ioend->io_size,
> + ioend->io_sector, oz, NULLFSBLOCK);
> + if (error)
> + goto done;
> +
> + if (!(ioend->io_flags & IOMAP_IOEND_DIRECT) &&
> + xfs_ioend_is_append(ioend))
> + error = xfs_setfilesize(ip, ioend->io_offset, ioend->io_size);
> +done:
> /*
> * Put the open zone for all ioends merged into this one (if any).
> */
> @@ -162,8 +191,9 @@ xfs_ioend_put_open_zones(
> * The main ioend might not have an open zone if the submission failed
> * before xfs_zone_alloc_and_submit got called.
> */
> - if (ioend->io_private)
> - xfs_open_zone_put(ioend->io_private);
> + if (oz)
> + xfs_open_zone_put(oz);
> + iomap_finish_ioends(ioend, error);
> }
>
> static void
> @@ -172,7 +202,6 @@ xfs_end_ioend_write(
> {
> struct xfs_inode *ip = XFS_I(ioend->io_inode);
> struct xfs_mount *mp = ip->i_mount;
> - bool is_zoned = xfs_is_zoned_inode(ip);
> xfs_off_t offset = ioend->io_offset;
> size_t size = ioend->io_size;
> int error;
> @@ -194,19 +223,7 @@ xfs_end_ioend_write(
> */
> error = blk_status_to_errno(ioend->io_bio.bi_status);
> if (unlikely(error)) {
> - /*
> - * Zoned writes update the in-core open zone accounting before
> - * I/O submission. A failed write leaves that state
> - * inconsistent, so shut down the filesystem instead of letting
> - * later writers wait forever for open zone space to become
> - * available.
> - */
> - if (is_zoned) {
> - xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
> - goto done;
> - }
> if (ioend->io_flags & IOMAP_IOEND_SHARED) {
> - ASSERT(!is_zoned);
> xfs_reflink_cancel_cow_range(ip, offset, size, true);
> xfs_bmap_punch_delalloc_range(ip, XFS_DATA_FORK, offset,
> offset + size, NULL);
> @@ -217,10 +234,7 @@ xfs_end_ioend_write(
> /*
> * Success: commit the COW or unwritten blocks if needed.
> */
> - if (is_zoned)
> - error = xfs_zoned_end_io(ip, offset, size, ioend->io_sector,
> - ioend->io_private, NULLFSBLOCK);
> - else if (ioend->io_flags & IOMAP_IOEND_SHARED)
> + if (ioend->io_flags & IOMAP_IOEND_SHARED)
> error = xfs_reflink_end_cow(ip, offset, size);
> else if (ioend->io_flags & IOMAP_IOEND_UNWRITTEN)
> error = xfs_iomap_write_unwritten(ip, offset, size, false);
> @@ -230,8 +244,6 @@ xfs_end_ioend_write(
> xfs_ioend_is_append(ioend))
> error = xfs_setfilesize(ip, offset, size);
> done:
> - if (is_zoned)
> - xfs_ioend_put_open_zones(ioend);
> iomap_finish_ioends(ioend, error);
> }
>
> @@ -276,7 +288,10 @@ xfs_end_io(
> io_list))) {
> list_del_init(&ioend->io_list);
> iomap_ioend_try_merge(ioend, &tmp);
> - xfs_end_ioend_write(ioend);
> + if (xfs_is_zoned_inode(ip))
> + xfs_end_ioend_write_zoned(ioend);
> + else
> + xfs_end_ioend_write(ioend);
> cond_resched();
> }
> memalloc_nofs_restore(nofs_flag);
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 8/9] xfs: factor out a xfs_zoned_fill_srcmap helper
2026-09-24 9:57 ` [PATCH 8/9] xfs: factor out a xfs_zoned_fill_srcmap helper Christoph Hellwig
@ 2026-09-24 20:27 ` Darrick J. Wong
0 siblings, 0 replies; 21+ messages in thread
From: Darrick J. Wong @ 2026-09-24 20:27 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Carlos Maiolino, linux-xfs
On Thu, Sep 24, 2026 at 11:57:09AM +0200, Christoph Hellwig wrote:
> The code filling the srcmap in xfs_zoned_buffered_write_iomap_begin isn't
> terribly complicated, but fairly deeply indented and will become a bit
> more complex soon. Factor it into a helper and add some comments.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
This hoist looks fine. :)
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> fs/xfs/xfs_iomap.c | 53 ++++++++++++++++++++++++++++++----------------
> 1 file changed, 35 insertions(+), 18 deletions(-)
>
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 7c6238fed61e..7bc17f179be7 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -1588,6 +1588,37 @@ xfs_bmapi_reserve_delalloc(
> return error;
> }
>
> +static int
> +xfs_zoned_fill_srcmap(
> + struct xfs_inode *ip,
> + xfs_fileoff_t offset_fsb,
> + xfs_fileoff_t *end_fsb,
> + unsigned flags,
> + struct iomap *srcmap)
> +{
> + struct xfs_bmbt_irec smap;
> + struct xfs_iext_cursor scur;
> +
> + if (!xfs_iext_lookup_extent(ip, &ip->i_df, offset_fsb, &scur, &smap))
> + smap.br_startoff = *end_fsb; /* fake hole until EOF */
> + if (smap.br_startoff > offset_fsb) {
> + /*
> + * There is a hole at @offset_fsb. Only map until the end of
> + * the of it.
> + */
> + *end_fsb = min(*end_fsb, smap.br_startoff);
> + return 0;
> + }
> +
> + /*
> + * There is a data fork mapping, only map until the end of it.
> + */
> + *end_fsb = min(*end_fsb, smap.br_startoff + smap.br_blockcount);
> + xfs_trim_extent(&smap, offset_fsb, *end_fsb - offset_fsb);
> + return xfs_bmbt_to_iomap(ip, srcmap, &smap, flags, 0,
> + xfs_iomap_inode_sequence(ip, 0));
> +}
> +
> static int
> xfs_zoned_buffered_write_iomap_begin(
> struct inode *inode,
> @@ -1655,24 +1686,10 @@ xfs_zoned_buffered_write_iomap_begin(
> if (!IS_ALIGNED(offset, mp->m_sb.sb_blocksize) ||
> !IS_ALIGNED(offset + count, mp->m_sb.sb_blocksize) ||
> (flags & IOMAP_ZERO)) {
> - struct xfs_bmbt_irec smap;
> - struct xfs_iext_cursor scur;
> -
> - if (!xfs_iext_lookup_extent(ip, &ip->i_df, offset_fsb, &scur,
> - &smap))
> - smap.br_startoff = end_fsb; /* fake hole until EOF */
> - if (smap.br_startoff > offset_fsb) {
> - end_fsb = min(end_fsb, smap.br_startoff);
> - } else {
> - end_fsb = min(end_fsb,
> - smap.br_startoff + smap.br_blockcount);
> - xfs_trim_extent(&smap, offset_fsb,
> - end_fsb - offset_fsb);
> - error = xfs_bmbt_to_iomap(ip, srcmap, &smap, flags, 0,
> - xfs_iomap_inode_sequence(ip, 0));
> - if (error)
> - goto out_unlock;
> - }
> + error = xfs_zoned_fill_srcmap(ip, offset_fsb, &end_fsb, flags,
> + srcmap);
> + if (error)
> + goto out_unlock;
> }
>
> if (!ip->i_cowfp)
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 9/9] xfs: calculate end_fsb later in xfs_zoned_fill_srcmap
2026-09-24 9:57 ` [PATCH 9/9] xfs: calculate end_fsb later in xfs_zoned_fill_srcmap Christoph Hellwig
@ 2026-09-24 20:29 ` Darrick J. Wong
0 siblings, 0 replies; 21+ messages in thread
From: Darrick J. Wong @ 2026-09-24 20:29 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Carlos Maiolino, linux-xfs
On Thu, Sep 24, 2026 at 11:57:10AM +0200, Christoph Hellwig wrote:
> xfs_trim_extent doesn't need the updated end_fsb as it already is
> limited by the smap range. Move the end_fsb calculation later to
> prepare additional reasons that could reduce the smap range.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Make sense. Constricting *end_fsb to the smap and then trimming the
smap to *end_fsb is (for now anyway) commutable.
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> fs/xfs/xfs_iomap.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 7bc17f179be7..6701be9325ef 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -1613,8 +1613,8 @@ xfs_zoned_fill_srcmap(
> /*
> * There is a data fork mapping, only map until the end of it.
> */
> - *end_fsb = min(*end_fsb, smap.br_startoff + smap.br_blockcount);
> xfs_trim_extent(&smap, offset_fsb, *end_fsb - offset_fsb);
> + *end_fsb = min(*end_fsb, smap.br_startoff + smap.br_blockcount);
> return xfs_bmbt_to_iomap(ip, srcmap, &smap, flags, 0,
> xfs_iomap_inode_sequence(ip, 0));
> }
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 7/9] xfs: split xfs_end_ioend_write
2026-09-24 20:26 ` Darrick J. Wong
@ 2026-09-25 5:46 ` Christoph Hellwig
0 siblings, 0 replies; 21+ messages in thread
From: Christoph Hellwig @ 2026-09-25 5:46 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: Christoph Hellwig, Carlos Maiolino, linux-xfs
FYI, it turns out this actually needs some changes only queued up
in the block tree right now. So I'll resend with the bits that
actually apply against xfs/for-next after waiting for a few more
reviews.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: misc cleanups
2026-09-24 9:57 misc cleanups Christoph Hellwig
` (8 preceding siblings ...)
2026-09-24 9:57 ` [PATCH 9/9] xfs: calculate end_fsb later in xfs_zoned_fill_srcmap Christoph Hellwig
@ 2026-10-05 18:06 ` Carlos Maiolino
9 siblings, 0 replies; 21+ messages in thread
From: Carlos Maiolino @ 2026-10-05 18:06 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Darrick J . Wong, linux-xfs
On Thu, 24 Sep 2026 11:57:01 +0200, Christoph Hellwig wrote:
> this series has various cleanups developed as part of the data checksum
> series that should be useful on their own.
>
> Diffstat:
>
> libxfs/xfs_rtbitmap.c | 79 ++++++++++++++++++++++++------------------
> libxfs/xfs_rtbitmap.h | 45 +++++++++---------------
> scrub/rtbitmap_repair.c | 15 --------
> scrub/rtsummary_repair.c | 15 --------
> xfs_ioend.c | 81 +++++++++++++++++++++++++------------------
> xfs_iomap.c | 53 ++++++++++++++++++----------
> xfs_verify_media.c | 87 ++++++++++++++++++-----------------------------
> 7 files changed, 181 insertions(+), 194 deletions(-)
>
> [...]
Applied to for-next, thanks!
[1/9] xfs: centralize setting of buf_ops/buf_type/magic for rtblocks
commit: c110639a1c9f36ce5382e9e70fccaa3f922ef35d
[2/9] xfs: factor out a xfs_rtfile_initialize_buf helper
commit: 724b5e3a549233bf71e3ff5a90255e8c04dfed1e
[3/9] xfs: add a xfs_rtblock_payload helper
commit: 46db7dec8bae04b2721c9d3e9e4fc75c14654754
[4/9] xfs: cleanup xfs_verify_media_error
commit: dfe2d2d92df34f6ca9e19548fcc26b2e52a38552
[5/9] xfs: use bdev_rw_virt in xfs_verify_media
commit: 89572b7fdc7bf10806e1bcde0d9aeccc0d8b3fdb
[6/9] xfs: lift setting the NOFS context to xfs_end_io
commit: b5a96a9877a5c7426054ccf82528d5de795cb25a
[7/9] xfs: split xfs_end_ioend_write
commit: 0c94f5499d694a99c2fae3106daaec66971b8b1a
[8/9] xfs: factor out a xfs_zoned_fill_srcmap helper
commit: b74d34fa3cc7e8f35f1b969c68837ae99566749b
[9/9] xfs: calculate end_fsb later in xfs_zoned_fill_srcmap
commit: b942c6919ac39870f8327d3123a2912d96e7e617
Best regards,
--
Carlos Maiolino <cem@kernel.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-10-05 18:06 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-24 9:57 misc cleanups Christoph Hellwig
2026-09-24 9:57 ` [PATCH 1/9] xfs: centralize setting of buf_ops/buf_type/magic for rtblocks Christoph Hellwig
2026-09-24 19:01 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 2/9] xfs: factor out a xfs_rtfile_initialize_buf helper Christoph Hellwig
2026-09-24 19:02 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 3/9] xfs: add a xfs_rtblock_payload helper Christoph Hellwig
2026-09-24 20:13 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 4/9] xfs: cleanup xfs_verify_media_error Christoph Hellwig
2026-09-24 20:14 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 5/9] xfs: use bdev_rw_virt in xfs_verify_media Christoph Hellwig
2026-09-24 20:18 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 6/9] xfs: lift setting the NOFS context to xfs_end_io Christoph Hellwig
2026-09-24 20:18 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 7/9] xfs: split xfs_end_ioend_write Christoph Hellwig
2026-09-24 20:26 ` Darrick J. Wong
2026-09-25 5:46 ` Christoph Hellwig
2026-09-24 9:57 ` [PATCH 8/9] xfs: factor out a xfs_zoned_fill_srcmap helper Christoph Hellwig
2026-09-24 20:27 ` Darrick J. Wong
2026-09-24 9:57 ` [PATCH 9/9] xfs: calculate end_fsb later in xfs_zoned_fill_srcmap Christoph Hellwig
2026-09-24 20:29 ` Darrick J. Wong
2026-10-05 18:06 ` misc cleanups Carlos Maiolino
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.