aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
authorChristoph Hellwig <hch@lst.de>2026-02-23 05:20:06 -0800
committerJens Axboe <axboe@kernel.dk>2026-03-09 07:47:02 -0600
commit0bde8a12b5540572a7fd6d2867bee6de15e4f289 (patch)
tree3d09729647e63802fc894abff639e144d45f5857 /block
parent8c56ef10150ed7650cf4105539242c94c156148c (diff)
downloadath-0bde8a12b5540572a7fd6d2867bee6de15e4f289.tar.gz
block: add fs_bio_integrity helpers
Add a set of helpers for file system initiated integrity information. These include mempool backed allocations and verifying based on a passed in sector and size which is often available from file system completion routines. 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> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r--block/Makefile2
-rw-r--r--block/bio-integrity-fs.c81
2 files changed, 82 insertions, 1 deletions
diff --git a/block/Makefile b/block/Makefile
index c65f4da937026..7dce2e44276c4 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -26,7 +26,7 @@ bfq-y := bfq-iosched.o bfq-wf2q.o bfq-cgroup.o
obj-$(CONFIG_IOSCHED_BFQ) += bfq.o
obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o blk-integrity.o t10-pi.o \
- bio-integrity-auto.o
+ bio-integrity-auto.o bio-integrity-fs.o
obj-$(CONFIG_BLK_DEV_ZONED) += blk-zoned.o
obj-$(CONFIG_BLK_WBT) += blk-wbt.o
obj-$(CONFIG_BLK_DEBUG_FS) += blk-mq-debugfs.o
diff --git a/block/bio-integrity-fs.c b/block/bio-integrity-fs.c
new file mode 100644
index 0000000000000..acb1e5f270d2b
--- /dev/null
+++ b/block/bio-integrity-fs.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 Christoph Hellwig.
+ */
+#include <linux/blk-integrity.h>
+#include <linux/bio-integrity.h>
+#include "blk.h"
+
+struct fs_bio_integrity_buf {
+ struct bio_integrity_payload bip;
+ struct bio_vec bvec;
+};
+
+static struct kmem_cache *fs_bio_integrity_cache;
+static mempool_t fs_bio_integrity_pool;
+
+unsigned int fs_bio_integrity_alloc(struct bio *bio)
+{
+ struct fs_bio_integrity_buf *iib;
+ unsigned int action;
+
+ action = bio_integrity_action(bio);
+ if (!action)
+ return 0;
+
+ iib = mempool_alloc(&fs_bio_integrity_pool, GFP_NOIO);
+ bio_integrity_init(bio, &iib->bip, &iib->bvec, 1);
+
+ bio_integrity_alloc_buf(bio, action & BI_ACT_ZERO);
+ if (action & BI_ACT_CHECK)
+ bio_integrity_setup_default(bio);
+ return action;
+}
+
+void fs_bio_integrity_free(struct bio *bio)
+{
+ struct bio_integrity_payload *bip = bio_integrity(bio);
+
+ bio_integrity_free_buf(bip);
+ mempool_free(container_of(bip, struct fs_bio_integrity_buf, bip),
+ &fs_bio_integrity_pool);
+
+ bio->bi_integrity = NULL;
+ bio->bi_opf &= ~REQ_INTEGRITY;
+}
+
+void fs_bio_integrity_generate(struct bio *bio)
+{
+ if (fs_bio_integrity_alloc(bio))
+ bio_integrity_generate(bio);
+}
+EXPORT_SYMBOL_GPL(fs_bio_integrity_generate);
+
+int fs_bio_integrity_verify(struct bio *bio, sector_t sector, unsigned int size)
+{
+ struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
+ struct bio_integrity_payload *bip = bio_integrity(bio);
+
+ /*
+ * Reinitialize bip->bip_iter.
+ *
+ * This is for use in the submitter after the driver is done with the
+ * bio. Requires the submitter to remember the sector and the size.
+ */
+ memset(&bip->bip_iter, 0, sizeof(bip->bip_iter));
+ bip->bip_iter.bi_sector = sector;
+ bip->bip_iter.bi_size = bio_integrity_bytes(bi, size >> SECTOR_SHIFT);
+ return blk_status_to_errno(bio_integrity_verify(bio, &bip->bip_iter));
+}
+
+static int __init fs_bio_integrity_init(void)
+{
+ fs_bio_integrity_cache = kmem_cache_create("fs_bio_integrity",
+ sizeof(struct fs_bio_integrity_buf), 0,
+ SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
+ if (mempool_init_slab_pool(&fs_bio_integrity_pool, BIO_POOL_SIZE,
+ fs_bio_integrity_cache))
+ panic("fs_bio_integrity: can't create pool\n");
+ return 0;
+}
+fs_initcall(fs_bio_integrity_init);