From: "Darrick J. Wong" <djwong@kernel.org>
To: Christoph Hellwig <hch@lst.de>
Cc: Carlos Maiolino <cem@kernel.org>, Jens Axboe <axboe@kernel.dk>,
Christian Brauner <brauner@kernel.org>,
linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH 14/21] xfs: add support for reading with data checksums
Date: Mon, 28 Sep 2026 17:42:04 -0700 [thread overview]
Message-ID: <20260929004204.GV2705364@frogsfrogsfrogs> (raw)
In-Reply-To: <20260924100032.2733101-15-hch@lst.de>
On Thu, Sep 24, 2026 at 11:59:46AM +0200, Christoph Hellwig wrote:
> All reads from files with data checksums have the returned iomaps for
> data blocks limited to be inside a single RT csum file block, so that
> each data read only needs to deal with a single checksum buffer.
>
> All reads on checksummed files need to use ioends so that the checksum
> can be verified from process context. The ioend submission path looks
> up the checksum buffer and kicks of an asynchronous read of it. The
> completion path waits for the buffer if needed and verifies the checksum.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> fs/xfs/xfs_aops.c | 4 +-
> fs/xfs/xfs_ioend.c | 108 +++++++++++++++++++++++++++++++++++++++------
> fs/xfs/xfs_iomap.c | 23 ++++++++--
> 3 files changed, 114 insertions(+), 21 deletions(-)
>
> diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
> index c30e688cfc9f..931795316de4 100644
> --- a/fs/xfs/xfs_aops.c
> +++ b/fs/xfs/xfs_aops.c
> @@ -599,9 +599,7 @@ static inline const struct iomap_read_ops *
> xfs_get_iomap_read_ops(
> const struct address_space *mapping)
> {
> - struct xfs_inode *ip = XFS_I(mapping->host);
> -
> - if (bdev_has_integrity_csum(xfs_inode_buftarg(ip)->bt_bdev))
> + if (mapping_stable_writes(mapping))
> return &xfs_iomap_read_ops;
> return &iomap_bio_read_ops;
> }
> diff --git a/fs/xfs/xfs_ioend.c b/fs/xfs/xfs_ioend.c
> index 54bd0995ac29..7570a1b915c0 100644
> --- a/fs/xfs/xfs_ioend.c
> +++ b/fs/xfs/xfs_ioend.c
> @@ -14,12 +14,72 @@
> #include "xfs_trace.h"
> #include "xfs_bmap_util.h"
> #include "xfs_reflink.h"
> +#include "xfs_rtcsum.h"
> #include "xfs_zone_alloc.h"
> #include "xfs_ioend.h"
> #include "xfs_error.h"
> #include "xfs_errortag.h"
> #include <linux/bio-integrity.h>
>
> +static bool
> +xfs_rtcsum_prepare_read(
> + struct iomap_ioend *ioend)
> +{
> + struct xfs_inode *ip = XFS_I(ioend->io_inode);
> + struct xfs_mount *mp = ip->i_mount;
> + struct xfs_buf *bp;
> + int error;
> +
> + error = -EIO;
> + if (WARN_ON_ONCE(ioend->io_bio.bi_iter.bi_idx))
What does this warning mean? That we've somehow already advanced the
bvec iterator?
> + goto fail;
> +
> + error = xfs_rtcsum_read_async(mp,
> + xfs_daddr_to_rtb(mp, ioend->io_sector), &bp);
> + if (error)
> + goto fail;
> + ioend->io_private = bp;
> + return true;
> +
> +fail:
> + ioend->io_bio.bi_status = errno_to_blk_status(error);
> + bio_endio(&ioend->io_bio);
> + return false;
> +}
> +
> +static int
> +xfs_rtcsum_verify_ioend(
> + struct iomap_ioend *ioend,
> + int error)
> +{
> + struct xfs_inode *ip = XFS_I(ioend->io_inode);
> + struct xfs_mount *mp = ip->i_mount;
> + xfs_rtblock_t bno = xfs_daddr_to_rtb(mp, ioend->io_sector);
> + unsigned int bsize = mp->m_sb.sb_blocksize;
> + struct xfs_buf *bp = ioend->io_private;
> + struct bvec_iter iter = {
> + .bi_size = roundup(ioend->io_size, bsize),
> + .bi_offset = ioend->io_bvec_offset,
> + };
> +
> + /* No bp for early xfs_rtcsum_prepare_read failures. */
> + if (!bp)
> + return error;
Is it possible for error to be zero here?
> +
> + if (error)
> + goto out_rele;
> + error = xfs_buf_read_async_wait(bp);
> + if (error)
> + goto out_rele;
> +
> + error = xfs_csum_verify(mp, &ioend->io_bio, &iter,
> + bp->b_addr + xfs_rtb_to_rtcsumoff(mp, bno), bno,
> + true);
You only need two tab indent here.
> +out_rele:
> + xfs_buf_rele(bp);
> + return error;
> +}
> +
> static void
> xfs_dio_bounce_end_io(
> struct bio *bio)
> @@ -30,6 +90,9 @@ xfs_dio_bounce_end_io(
>
> if ((ioend->io_flags & IOMAP_IOEND_INTEGRITY) && !bio->bi_status)
> error = iomap_ioend_integrity_verify(ioend);
> + if (xfs_is_rtcsum_inode(XFS_I(ioend->io_inode)))
> + error = xfs_rtcsum_verify_ioend(ioend, error);
> +
> iomap_bounce_read_end_io(ioend, orig_bio, error);
> }
>
> @@ -39,6 +102,9 @@ xfs_bounce_submit_ioend(
> {
> if (ioend->io_flags & IOMAP_IOEND_INTEGRITY)
> fs_bio_integrity_alloc(&ioend->io_bio);
> + if (xfs_is_rtcsum_inode(XFS_I(ioend->io_inode)) &&
> + !xfs_rtcsum_prepare_read(ioend))
> + return;
> ioend->io_bio.bi_end_io = xfs_dio_bounce_end_io;
> bio_set_flag(&ioend->io_bio, BIO_COMPLETE_IN_TASK);
> submit_bio(&ioend->io_bio);
> @@ -108,25 +174,36 @@ xfs_end_io_read(
> struct xfs_inode *ip = XFS_I(ioend->io_inode);
> struct xfs_mount *mp = ip->i_mount;
> int error = blk_status_to_errno(bio->bi_status);
> + bool is_csum_error = false;
>
> if (!error && (ioend->io_flags & IOMAP_IOEND_INTEGRITY)) {
> error = iomap_ioend_integrity_verify(ioend);
> - if ((ioend->io_flags & IOMAP_IOEND_DIRECT) &&
> - READ_ONCE(mp->m_read_bounce) == XFS_READ_BOUNCE_LAZY) {
> - /*
> - * We only really need to retry for guard tag errors,
> - * but right now we can't distinguish them from other
> - * (i.e, reftag) errors.
> - */
> - if (error ||
> - XFS_TEST_ERROR(mp, XFS_ERRTAG_BOUNCE_REREAD)) {
> - xfs_read_bounce_and_resubmit(ioend);
> - return;
> - }
> - }
> + /*
> + * We only really need to retry for guard tag errors, but right
> + * now we can't distinguish them from other (i.e, reftag) errors.
> + */
> + if (error)
> + is_csum_error = true;
> }
>
> - iomap_finish_ioends(ioend, error);
> + if (xfs_is_rtcsum_inode(ip)) {
> + error = xfs_rtcsum_verify_ioend(ioend, error);
> + if (error && !bio->bi_status)
> + is_csum_error = true;
> + }
> +
> + /*
> + * If we saw a checksum failure on a direct I/O read that uses lazy
> + * bouncing, resubmit the read using a bounce buffer so that we can
> + * guarantee this was not caused by the user corrupting the buffer.
> + */
> + if ((ioend->io_flags & IOMAP_IOEND_DIRECT) &&
> + READ_ONCE(mp->m_read_bounce) == XFS_READ_BOUNCE_LAZY &&
> + (is_csum_error ||
> + (!error && XFS_TEST_ERROR(mp, XFS_ERRTAG_BOUNCE_REREAD))))
> + xfs_read_bounce_and_resubmit(ioend);
Ok, so now we bounce the read on PI verification errors or fs checksum
verification errors. Makes sense.
--D
> + else
> + iomap_finish_ioends(ioend, error);
> }
>
> void
> @@ -148,6 +225,9 @@ xfs_ioend_submit_read(
> return;
> }
>
> + if (xfs_is_rtcsum_inode(ip) && !xfs_rtcsum_prepare_read(ioend))
> + return;
> +
> if (ioend_flags & IOMAP_IOEND_INTEGRITY)
> fs_bio_integrity_alloc(bio);
> bio->bi_end_io = xfs_end_io_read;
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 6701be9325ef..0e4396e52809 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -32,6 +32,7 @@
> #include "xfs_rtbitmap.h"
> #include "xfs_icache.h"
> #include "xfs_zone_alloc.h"
> +#include "xfs_rtcsum.h"
>
> #define XFS_ALLOC_ALIGN(mp, off) \
> (((off) >> mp->m_allocsize_log) << mp->m_allocsize_log)
> @@ -166,6 +167,8 @@ xfs_bmbt_to_iomap(
> }
>
> iomap->validity_cookie = sequence_cookie;
> + if (xfs_is_rtcsum_inode(ip))
> + iomap->csum_shift = mp->m_rtcsum_shift;
> return 0;
> }
>
> @@ -2227,16 +2230,28 @@ xfs_read_iomap_begin(
> return error;
> error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap,
> &nimaps, 0);
> - if (!error && ((flags & IOMAP_REPORT) || IS_DAX(inode)))
> + if (error)
> + goto out_unlock;
> +
> + if ((flags & IOMAP_REPORT) || IS_DAX(inode)) {
> error = xfs_reflink_trim_around_shared(ip, &imap, &shared);
> + if (error)
> + goto out_unlock;
> + } else if (!isnullstartblock(imap.br_startblock) &&
> + xfs_is_rtcsum_inode(ip)) {
> + imap.br_blockcount = min(imap.br_blockcount,
> + xfs_rtcsum_max_len(mp, imap.br_startblock));
> + }
> +
> seq = xfs_iomap_inode_sequence(ip, shared ? IOMAP_F_SHARED : 0);
> xfs_iunlock(ip, lockmode);
> -
> - if (error)
> - return error;
> trace_xfs_iomap_found(ip, offset, length, XFS_DATA_FORK, &imap);
> return xfs_bmbt_to_iomap(ip, iomap, &imap, flags,
> shared ? IOMAP_F_SHARED : 0, seq);
> +
> +out_unlock:
> + xfs_iunlock(ip, lockmode);
> + return error;
> }
>
> static DEFINE_IOMAP_ITER_NEXT(xfs_read_iomap_next, xfs_read_iomap_begin);
> --
> 2.53.0
>
>
next prev parent reply other threads:[~2026-09-29 0:42 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 9:59 support for RT data checksums Christoph Hellwig
2026-09-24 9:59 ` [PATCH 01/21] block: export fs_bio_integrity_verify Christoph Hellwig
2026-09-24 20:29 ` Darrick J. Wong
2026-09-24 9:59 ` [PATCH 02/21] iomap: add support for data checksumming Christoph Hellwig
2026-09-24 21:39 ` Darrick J. Wong
2026-09-25 5:53 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 03/21] xfs: add a xfs_buf_read_async buffer cache API Christoph Hellwig
2026-09-24 21:43 ` Darrick J. Wong
2026-09-25 5:54 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 04/21] xfs: add xfs_daddr_to_rgno and xfs_daddr_to_rgbno helpers Christoph Hellwig
2026-09-24 21:44 ` Darrick J. Wong
2026-09-24 9:59 ` [PATCH 05/21] xfs: introduce XFS_BLI_PREALLOC Christoph Hellwig
2026-09-24 21:49 ` Darrick J. Wong
2026-09-25 5:57 ` Christoph Hellwig
2026-10-08 11:46 ` Anuj gupta
2026-09-24 9:59 ` [PATCH 06/21] xfs: prepare xfs_rtfile_initialize_blocks for larger than FSB blocks Christoph Hellwig
2026-09-24 22:03 ` Darrick J. Wong
2026-09-25 5:58 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 07/21] xfs: relase zi_open_zones_lock over xfs_open_zone_put on unmount Christoph Hellwig
2026-09-24 9:59 ` [PATCH 08/21] xfs: define the RT data checksum on-disk format Christoph Hellwig
2026-09-24 22:13 ` Darrick J. Wong
2026-09-25 0:04 ` Eric Biggers
2026-09-25 6:01 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 09/21] xfs: add support for per-RTG csum files Christoph Hellwig
2026-09-24 22:24 ` Darrick J. Wong
2026-09-25 6:10 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 10/21] xfs: calculate the log reservation for logging data checksum buffers Christoph Hellwig
2026-09-24 22:30 ` Darrick J. Wong
2026-09-25 6:12 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 11/21] xfs: core RT data checksum support Christoph Hellwig
2026-09-25 23:20 ` Darrick J. Wong
2026-09-26 6:13 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 12/21] xfs: data checksums require stable writes Christoph Hellwig
2026-09-25 23:21 ` Darrick J. Wong
2026-09-24 9:59 ` [PATCH 13/21] xfs: require file system block size alignment when using data checksums Christoph Hellwig
2026-09-25 23:24 ` Darrick J. Wong
2026-09-26 6:15 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 14/21] xfs: add support for reading with " Christoph Hellwig
2026-09-29 0:42 ` Darrick J. Wong [this message]
2026-10-05 12:59 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 15/21] xfs: add support for writing " Christoph Hellwig
2026-09-29 1:01 ` Darrick J. Wong
2026-10-05 13:00 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 16/21] xfs: add data checksum support to zoned garbage collection Christoph Hellwig
2026-09-29 1:06 ` Darrick J. Wong
2026-10-05 13:11 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 17/21] xfs: verify data checksums during media verification Christoph Hellwig
2026-09-29 1:19 ` Darrick J. Wong
2026-10-05 13:13 ` Christoph Hellwig
2026-09-24 9:59 ` [PATCH 18/21] xfs: don't try to verify checksums on empty zones Christoph Hellwig
2026-09-29 1:25 ` Darrick J. Wong
2026-10-05 13:14 ` Christoph Hellwig
2026-10-08 11:43 ` Anuj gupta
2026-09-24 9:59 ` [PATCH 19/21] xfs: report RT data checksum information via XFS_FSOP_GEOM Christoph Hellwig
2026-09-29 1:26 ` Darrick J. Wong
2026-09-24 9:59 ` [PATCH 20/21] xfs: add an experimental feature warning for RT data checksums Christoph Hellwig
2026-09-29 1:27 ` Darrick J. Wong
2026-09-24 9:59 ` [PATCH 21/21] xfs: enable " Christoph Hellwig
2026-09-29 1:27 ` Darrick J. Wong
2026-10-05 13:16 ` Christoph Hellwig
2026-09-24 22:52 ` support for " Dave Chinner
2026-09-25 6:27 ` Christoph Hellwig
2026-09-27 22:59 ` Dave Chinner
2026-09-28 5:24 ` Christoph Hellwig
2026-09-29 14:11 ` Dave Chinner
2026-09-30 7:11 ` Dave Chinner
2026-10-05 13:53 ` Christoph Hellwig
2026-10-06 5:31 ` Dave Chinner
2026-10-07 13:46 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260929004204.GV2705364@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=axboe@kernel.dk \
--cc=brauner@kernel.org \
--cc=cem@kernel.org \
--cc=hch@lst.de \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.