From: Christoph Hellwig <hch@lst.de>
To: Jens Axboe <axboe@kernel.dk>, Christian Brauner <brauner@kernel.org>
Cc: "Darrick J. Wong" <djwong@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: [PATCH 01/15] block: factor out a bio_integrity_action helper
Date: Wed, 18 Feb 2026 07:11:55 +0100 [thread overview]
Message-ID: <20260218061238.3317841-2-hch@lst.de> (raw)
In-Reply-To: <20260218061238.3317841-1-hch@lst.de>
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>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Tested-by: Anuj Gupta <anuj20.g@samsung.com>
---
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 d5602ff62c7c..5cddfcad2381 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -3143,6 +3143,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;
@@ -3195,8 +3196,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 237edfa1c624..bb2c1b9d56ca 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-02-18 6:12 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-18 6:11 support file system generated / verified integrity information v3 Christoph Hellwig
2026-02-18 6:11 ` Christoph Hellwig [this message]
2026-02-18 6:11 ` [PATCH 02/15] block: factor out a bio_integrity_setup_default helper Christoph Hellwig
2026-02-18 6:11 ` [PATCH 03/15] block: add a bdev_has_integrity_csum helper Christoph Hellwig
2026-02-18 6:11 ` [PATCH 04/15] block: prepare generation / verification helpers for fs usage Christoph Hellwig
2026-02-18 6:11 ` [PATCH 05/15] block: make max_integrity_io_size public Christoph Hellwig
2026-02-18 6:12 ` [PATCH 06/15] block: add fs_bio_integrity helpers Christoph Hellwig
2026-02-18 6:12 ` [PATCH 07/15] block: pass a maxlen argument to bio_iov_iter_bounce Christoph Hellwig
2026-02-18 10:52 ` Kanchan Joshi
2026-02-18 6:12 ` [PATCH 08/15] iomap: refactor iomap_bio_read_folio_range Christoph Hellwig
2026-02-18 6:12 ` [PATCH 09/15] iomap: pass the iomap_iter to ->submit_read Christoph Hellwig
2026-02-18 6:12 ` [PATCH 10/15] iomap: only call into ->submit_read when there is a read_ctx Christoph Hellwig
2026-02-19 7:17 ` Christoph Hellwig
2026-02-18 6:12 ` [PATCH 11/15] iomap: allow file systems to hook into buffered read bio submission Christoph Hellwig
2026-02-18 6:12 ` [PATCH 12/15] iomap: add a bioset pointer to iomap_read_folio_ops Christoph Hellwig
2026-02-18 6:12 ` [PATCH 13/15] iomap: support ioends for buffered reads Christoph Hellwig
2026-02-18 6:12 ` [PATCH 14/15] iomap: support T10 protection information Christoph Hellwig
2026-02-18 6:12 ` [PATCH 15/15] xfs: " Christoph Hellwig
-- strict thread matches above, loose matches on Subject: below --
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
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=20260218061238.3317841-2-hch@lst.de \
--to=hch@lst.de \
--cc=anuj20.g@samsung.com \
--cc=axboe@kernel.dk \
--cc=brauner@kernel.org \
--cc=cem@kernel.org \
--cc=djwong@kernel.org \
--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