From: "Darrick J. Wong" <djwong@kernel.org>
To: Christoph Hellwig <hch@lst.de>
Cc: Jens Axboe <axboe@kernel.dk>,
Christian Brauner <brauner@kernel.org>,
Carlos Maiolino <cem@kernel.org>,
"Martin K. Petersen" <martin.petersen@oracle.com>,
Anuj Gupta <anuj20.g@samsung.com>,
Kanchan Joshi <joshi.k@samsung.com>,
linux-block@vger.kernel.org, nvdimm@lists.linux.dev,
linux-fsdevel@vger.kernel.org, linux-xfs@vger.kernel.org
Subject: Re: [PATCH 01/15] block: factor out a bio_integrity_action helper
Date: Wed, 28 Jan 2026 08:29:03 -0800 [thread overview]
Message-ID: <20260128162903.GX5945@frogsfrogsfrogs> (raw)
In-Reply-To: <20260128161517.666412-2-hch@lst.de>
On Wed, Jan 28, 2026 at 05:14:56PM +0100, Christoph Hellwig wrote:
> Split the logic to see if a bio needs integrity metadata from
> bio_integrity_prep into a reusable helper than can be called from
> file system code.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
> Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
> Tested-by: Anuj Gupta <anuj20.g@samsung.com>
Looks good to me now, thanks for clarifying the kerneldoc
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> block/bio-integrity-auto.c | 64 +++++------------------------------
> block/bio-integrity.c | 48 ++++++++++++++++++++++++++
> block/blk-mq.c | 6 ++--
> drivers/nvdimm/btt.c | 6 ++--
> include/linux/bio-integrity.h | 5 ++-
> include/linux/blk-integrity.h | 23 +++++++++++++
> 6 files changed, 89 insertions(+), 63 deletions(-)
>
> diff --git a/block/bio-integrity-auto.c b/block/bio-integrity-auto.c
> index 44dcdf7520c5..e16f669dbf1e 100644
> --- a/block/bio-integrity-auto.c
> +++ b/block/bio-integrity-auto.c
> @@ -50,11 +50,6 @@ static bool bip_should_check(struct bio_integrity_payload *bip)
> return bip->bip_flags & BIP_CHECK_FLAGS;
> }
>
> -static bool bi_offload_capable(struct blk_integrity *bi)
> -{
> - return bi->metadata_size == bi->pi_tuple_size;
> -}
> -
> /**
> * __bio_integrity_endio - Integrity I/O completion function
> * @bio: Protected bio
> @@ -84,69 +79,27 @@ bool __bio_integrity_endio(struct bio *bio)
> /**
> * bio_integrity_prep - Prepare bio for integrity I/O
> * @bio: bio to prepare
> + * @action: preparation action needed (BI_ACT_*)
> + *
> + * Allocate the integrity payload. For writes, generate the integrity metadata
> + * and for reads, setup the completion handler to verify the metadata.
> *
> - * Checks if the bio already has an integrity payload attached. If it does, the
> - * payload has been generated by another kernel subsystem, and we just pass it
> - * through.
> - * Otherwise allocates integrity payload and for writes the integrity metadata
> - * will be generated. For reads, the completion handler will verify the
> - * metadata.
> + * This is used for bios that do not have user integrity payloads attached.
> */
> -bool bio_integrity_prep(struct bio *bio)
> +void bio_integrity_prep(struct bio *bio, unsigned int action)
> {
> struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
> struct bio_integrity_data *bid;
> - bool set_flags = true;
> - gfp_t gfp = GFP_NOIO;
> -
> - if (!bi)
> - return true;
> -
> - if (!bio_sectors(bio))
> - return true;
> -
> - /* Already protected? */
> - if (bio_integrity(bio))
> - return true;
> -
> - switch (bio_op(bio)) {
> - case REQ_OP_READ:
> - if (bi->flags & BLK_INTEGRITY_NOVERIFY) {
> - if (bi_offload_capable(bi))
> - return true;
> - set_flags = false;
> - }
> - break;
> - case REQ_OP_WRITE:
> - /*
> - * Zero the memory allocated to not leak uninitialized kernel
> - * memory to disk for non-integrity metadata where nothing else
> - * initializes the memory.
> - */
> - if (bi->flags & BLK_INTEGRITY_NOGENERATE) {
> - if (bi_offload_capable(bi))
> - return true;
> - set_flags = false;
> - gfp |= __GFP_ZERO;
> - } else if (bi->metadata_size > bi->pi_tuple_size)
> - gfp |= __GFP_ZERO;
> - break;
> - default:
> - return true;
> - }
> -
> - if (WARN_ON_ONCE(bio_has_crypt_ctx(bio)))
> - return true;
>
> bid = mempool_alloc(&bid_pool, GFP_NOIO);
> bio_integrity_init(bio, &bid->bip, &bid->bvec, 1);
> bid->bio = bio;
> bid->bip.bip_flags |= BIP_BLOCK_INTEGRITY;
> - bio_integrity_alloc_buf(bio, gfp & __GFP_ZERO);
> + bio_integrity_alloc_buf(bio, action & BI_ACT_ZERO);
>
> bip_set_seed(&bid->bip, bio->bi_iter.bi_sector);
>
> - if (set_flags) {
> + if (action & BI_ACT_CHECK) {
> if (bi->csum_type == BLK_INTEGRITY_CSUM_IP)
> bid->bip.bip_flags |= BIP_IP_CHECKSUM;
> if (bi->csum_type)
> @@ -160,7 +113,6 @@ bool bio_integrity_prep(struct bio *bio)
> blk_integrity_generate(bio);
> else
> bid->saved_bio_iter = bio->bi_iter;
> - return true;
> }
> EXPORT_SYMBOL(bio_integrity_prep);
>
> diff --git a/block/bio-integrity.c b/block/bio-integrity.c
> index 09eeaf6e74b8..6bdbb4ed2d1a 100644
> --- a/block/bio-integrity.c
> +++ b/block/bio-integrity.c
> @@ -7,6 +7,7 @@
> */
>
> #include <linux/blk-integrity.h>
> +#include <linux/t10-pi.h>
> #include "blk.h"
>
> struct bio_integrity_alloc {
> @@ -16,6 +17,53 @@ struct bio_integrity_alloc {
>
> static mempool_t integrity_buf_pool;
>
> +static bool bi_offload_capable(struct blk_integrity *bi)
> +{
> + return bi->metadata_size == bi->pi_tuple_size;
> +}
> +
> +unsigned int __bio_integrity_action(struct bio *bio)
> +{
> + struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
> +
> + if (WARN_ON_ONCE(bio_has_crypt_ctx(bio)))
> + return 0;
> +
> + switch (bio_op(bio)) {
> + case REQ_OP_READ:
> + if (bi->flags & BLK_INTEGRITY_NOVERIFY) {
> + if (bi_offload_capable(bi))
> + return 0;
> + return BI_ACT_BUFFER;
> + }
> + return BI_ACT_BUFFER | BI_ACT_CHECK;
> + case REQ_OP_WRITE:
> + /*
> + * Flush masquerading as write?
> + */
> + if (!bio_sectors(bio))
> + return 0;
> +
> + /*
> + * Zero the memory allocated to not leak uninitialized kernel
> + * memory to disk for non-integrity metadata where nothing else
> + * initializes the memory.
> + */
> + if (bi->flags & BLK_INTEGRITY_NOGENERATE) {
> + if (bi_offload_capable(bi))
> + return 0;
> + return BI_ACT_BUFFER | BI_ACT_ZERO;
> + }
> +
> + if (bi->metadata_size > bi->pi_tuple_size)
> + return BI_ACT_BUFFER | BI_ACT_CHECK | BI_ACT_ZERO;
> + return BI_ACT_BUFFER | BI_ACT_CHECK;
> + default:
> + return 0;
> + }
> +}
> +EXPORT_SYMBOL_GPL(__bio_integrity_action);
> +
> void bio_integrity_alloc_buf(struct bio *bio, bool zero_buffer)
> {
> struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index cf1daedbb39f..d40942bafd02 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -3134,6 +3134,7 @@ void blk_mq_submit_bio(struct bio *bio)
> struct request_queue *q = bdev_get_queue(bio->bi_bdev);
> struct blk_plug *plug = current->plug;
> const int is_sync = op_is_sync(bio->bi_opf);
> + unsigned int integrity_action;
> struct blk_mq_hw_ctx *hctx;
> unsigned int nr_segs;
> struct request *rq;
> @@ -3186,8 +3187,9 @@ void blk_mq_submit_bio(struct bio *bio)
> if (!bio)
> goto queue_exit;
>
> - if (!bio_integrity_prep(bio))
> - goto queue_exit;
> + integrity_action = bio_integrity_action(bio);
> + if (integrity_action)
> + bio_integrity_prep(bio, integrity_action);
>
> blk_mq_bio_issue_init(q, bio);
> if (blk_mq_attempt_bio_merge(q, bio, nr_segs))
> diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
> index a933db961ed7..9cc4b659de1a 100644
> --- a/drivers/nvdimm/btt.c
> +++ b/drivers/nvdimm/btt.c
> @@ -1437,14 +1437,16 @@ static void btt_submit_bio(struct bio *bio)
> {
> struct bio_integrity_payload *bip = bio_integrity(bio);
> struct btt *btt = bio->bi_bdev->bd_disk->private_data;
> + unsigned int integrity_action;
> struct bvec_iter iter;
> unsigned long start;
> struct bio_vec bvec;
> int err = 0;
> bool do_acct;
>
> - if (!bio_integrity_prep(bio))
> - return;
> + integrity_action = bio_integrity_action(bio);
> + if (integrity_action)
> + bio_integrity_prep(bio, integrity_action);
>
> do_acct = blk_queue_io_stat(bio->bi_bdev->bd_disk->queue);
> if (do_acct)
> diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h
> index 21e4652dcfd2..276cbbdd2c9d 100644
> --- a/include/linux/bio-integrity.h
> +++ b/include/linux/bio-integrity.h
> @@ -78,7 +78,7 @@ int bio_integrity_add_page(struct bio *bio, struct page *page, unsigned int len,
> int bio_integrity_map_user(struct bio *bio, struct iov_iter *iter);
> int bio_integrity_map_iter(struct bio *bio, struct uio_meta *meta);
> void bio_integrity_unmap_user(struct bio *bio);
> -bool bio_integrity_prep(struct bio *bio);
> +void bio_integrity_prep(struct bio *bio, unsigned int action);
> void bio_integrity_advance(struct bio *bio, unsigned int bytes_done);
> void bio_integrity_trim(struct bio *bio);
> int bio_integrity_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp_mask);
> @@ -104,9 +104,8 @@ static inline void bio_integrity_unmap_user(struct bio *bio)
> {
> }
>
> -static inline bool bio_integrity_prep(struct bio *bio)
> +static inline void bio_integrity_prep(struct bio *bio, unsigned int action)
> {
> - return true;
> }
>
> static inline int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
> diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h
> index c15b1ac62765..fd3f3c8c0fcd 100644
> --- a/include/linux/blk-integrity.h
> +++ b/include/linux/blk-integrity.h
> @@ -180,4 +180,27 @@ static inline struct bio_vec rq_integrity_vec(struct request *rq)
> }
> #endif /* CONFIG_BLK_DEV_INTEGRITY */
>
> +enum bio_integrity_action {
> + BI_ACT_BUFFER = (1u << 0), /* allocate buffer */
> + BI_ACT_CHECK = (1u << 1), /* generate / verify PI */
> + BI_ACT_ZERO = (1u << 2), /* zero buffer */
> +};
> +
> +/**
> + * bio_integrity_action - return the integrity action needed for a bio
> + * @bio: bio to operate on
> + *
> + * Returns the mask of integrity actions (BI_ACT_*) that need to be performed
> + * for @bio.
> + */
> +unsigned int __bio_integrity_action(struct bio *bio);
> +static inline unsigned int bio_integrity_action(struct bio *bio)
> +{
> + if (!blk_get_integrity(bio->bi_bdev->bd_disk))
> + return 0;
> + if (bio_integrity(bio))
> + return 0;
> + return __bio_integrity_action(bio);
> +}
> +
> #endif /* _LINUX_BLK_INTEGRITY_H */
> --
> 2.47.3
>
>
next prev parent reply other threads:[~2026-01-28 16:29 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-28 16:14 support file system generated / verified integrity information v2 Christoph Hellwig
2026-01-28 16:14 ` [PATCH 01/15] block: factor out a bio_integrity_action helper Christoph Hellwig
2026-01-28 16:29 ` Darrick J. Wong [this message]
2026-01-28 16:14 ` [PATCH 02/15] block: factor out a bio_integrity_setup_default helper Christoph Hellwig
2026-01-28 16:14 ` [PATCH 03/15] block: add a bdev_has_integrity_csum helper Christoph Hellwig
2026-01-28 16:14 ` [PATCH 04/15] block: prepare generation / verification helpers for fs usage Christoph Hellwig
2026-01-28 16:15 ` [PATCH 05/15] block: make max_integrity_io_size public Christoph Hellwig
2026-01-28 16:15 ` [PATCH 06/15] block: add fs_bio_integrity helpers Christoph Hellwig
2026-01-30 16:08 ` Kanchan Joshi
2026-01-28 16:15 ` [PATCH 07/15] block: pass a maxlen argument to bio_iov_iter_bounce Christoph Hellwig
2026-01-28 16:15 ` [PATCH 08/15] iomap: refactor iomap_bio_read_folio_range Christoph Hellwig
2026-01-28 16:15 ` [PATCH 09/15] iomap: pass the iomap_iter to ->submit_read Christoph Hellwig
2026-01-28 16:15 ` [PATCH 10/15] iomap: only call into ->submit_read when there is a read_ctx Christoph Hellwig
2026-01-28 16:15 ` [PATCH 11/15] iomap: allow file systems to hook into buffered read bio submission Christoph Hellwig
2026-01-28 16:15 ` [PATCH 12/15] iomap: add a bioset pointer to iomap_read_folio_ops Christoph Hellwig
2026-01-28 16:15 ` [PATCH 13/15] iomap: support ioends for buffered reads Christoph Hellwig
2026-01-28 16:15 ` [PATCH 14/15] iomap: support T10 protection information Christoph Hellwig
2026-01-28 16:30 ` Darrick J. Wong
2026-01-28 16:15 ` [PATCH 15/15] xfs: " Christoph Hellwig
2026-01-29 14:51 ` Andrey Albershteyn
2026-01-30 5:14 ` Christoph Hellwig
-- strict thread matches above, loose matches on Subject: below --
2026-02-18 6:11 support file system generated / verified integrity information v3 Christoph Hellwig
2026-02-18 6:11 ` [PATCH 01/15] block: factor out a bio_integrity_action helper Christoph Hellwig
2026-01-21 6:43 support file system generated / verified integrity information Christoph Hellwig
2026-01-21 6:43 ` [PATCH 01/15] block: factor out a bio_integrity_action helper Christoph Hellwig
2026-01-23 0:01 ` Darrick J. Wong
2026-01-23 6:03 ` Christoph Hellwig
2026-01-23 7:13 ` Darrick J. Wong
2026-01-26 5:03 ` Christoph Hellwig
2026-01-25 19:46 ` Kanchan Joshi
2026-01-27 14:07 ` Martin K. Petersen
2026-01-27 14:55 ` Anuj gupta
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=20260128162903.GX5945@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=anuj20.g@samsung.com \
--cc=axboe@kernel.dk \
--cc=brauner@kernel.org \
--cc=cem@kernel.org \
--cc=hch@lst.de \
--cc=joshi.k@samsung.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=nvdimm@lists.linux.dev \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox