]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
block: add fs_bio_integrity helpers
authorChristoph Hellwig <hch@lst.de>
Mon, 23 Feb 2026 13:20:06 +0000 (05:20 -0800)
committerJens Axboe <axboe@kernel.dk>
Mon, 9 Mar 2026 13:47:02 +0000 (07:47 -0600)
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>
block/Makefile
block/bio-integrity-fs.c [new file with mode: 0644]
include/linux/bio-integrity.h

index c65f4da937026fb1ac6f114078fc0ef60a8325b3..7dce2e44276c4274c11a0a61121c83d9c43d6e0c 100644 (file)
@@ -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 (file)
index 0000000..acb1e5f
--- /dev/null
@@ -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);
index 232b86b9bbcb59247ac2c6c33db5aec93998e5e6..af5178434ec615d556a24fc1b6eb2a20501548df 100644 (file)
@@ -145,4 +145,10 @@ void bio_integrity_alloc_buf(struct bio *bio, bool zero_buffer);
 void bio_integrity_free_buf(struct bio_integrity_payload *bip);
 void bio_integrity_setup_default(struct bio *bio);
 
+unsigned int fs_bio_integrity_alloc(struct bio *bio);
+void fs_bio_integrity_free(struct bio *bio);
+void fs_bio_integrity_generate(struct bio *bio);
+int fs_bio_integrity_verify(struct bio *bio, sector_t sector,
+               unsigned int size);
+
 #endif /* _LINUX_BIO_INTEGRITY_H */