| 1 | |
| 2 | |
| 3 | * Copyright (c) 2025 Christoph Hellwig.
|
| 4 |
|
| 5 | #include <linux/blk-integrity.h>
|
| 6 | #include <linux/bio-integrity.h>
|
| 7 | #include "blk.h"
|
| 8 |
|
| 9 | struct fs_bio_integrity_buf {
|
| 10 | struct bio_integrity_payload bip;
|
| 11 | struct bio_vec bvec;
|
| 12 | };
|
| 13 |
|
| 14 | static struct kmem_cache *fs_bio_integrity_cache;
|
| 15 | static mempool_t fs_bio_integrity_pool;
|
| 16 |
|
| 17 | unsigned int fs_bio_integrity_alloc(struct bio *bio)
|
| 18 | {
|
| 19 | struct fs_bio_integrity_buf *iib;
|
| 20 | unsigned int action;
|
| 21 |
|
| 22 | action = bio_integrity_action(bio);
|
| 23 | if (!action)
|
| 24 | return 0;
|
| 25 |
|
| 26 | iib = mempool_alloc(&fs_bio_integrity_pool, GFP_NOFS);
|
| 27 | bio_integrity_init(bio, &iib->bip, &iib->bvec, 1);
|
| 28 |
|
| 29 | bio_integrity_alloc_buf(bio, GFP_NOFS, action & BI_ACT_ZERO);
|
| 30 | if (action & BI_ACT_CHECK)
|
| 31 | bio_integrity_setup_default(bio);
|
| 32 | return action;
|
| 33 | }
|
| 34 | EXPORT_SYMBOL_GPL(fs_bio_integrity_alloc);
|
| 35 |
|
| 36 | void fs_bio_integrity_free(struct bio *bio)
|
| 37 | {
|
| 38 | struct bio_integrity_payload *bip = bio_integrity(bio);
|
| 39 |
|
| 40 | bio_integrity_free_buf(bip);
|
| 41 | mempool_free(container_of(bip, struct fs_bio_integrity_buf, bip),
|
| 42 | &fs_bio_integrity_pool);
|
| 43 |
|
| 44 | bio->bi_integrity = NULL;
|
| 45 | bio->bi_opf &= ~REQ_INTEGRITY;
|
| 46 | }
|
| 47 | EXPORT_SYMBOL_GPL(fs_bio_integrity_free);
|
| 48 |
|
| 49 | void fs_bio_integrity_generate(struct bio *bio)
|
| 50 | {
|
| 51 | if (fs_bio_integrity_alloc(bio) &&
|
| 52 | (bio_integrity(bio)->bip_flags & BIP_CHECK_FLAGS))
|
| 53 | bio_integrity_generate(bio);
|
| 54 | }
|
| 55 | EXPORT_SYMBOL_GPL(fs_bio_integrity_generate);
|
| 56 |
|
| 57 | int fs_bio_integrity_verify(struct bio *bio, struct bvec_iter *data_iter)
|
| 58 | {
|
| 59 | struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
|
| 60 | struct bio_integrity_payload *bip = bio_integrity(bio);
|
| 61 |
|
| 62 | if (!bip || !(bip->bip_flags & BIP_CHECK_FLAGS))
|
| 63 | return 0;
|
| 64 |
|
| 65 | |
| 66 | * Reinitialize bip->bip_iter.
|
| 67 | *
|
| 68 | * This is for use in the submitter after the driver is done with the
|
| 69 | * bio. Requires the submitter to remember the sector and the size.
|
| 70 |
|
| 71 | memset(&bip->bip_iter, 0, sizeof(bip->bip_iter));
|
| 72 | bip->bip_iter.bi_sector = data_iter->bi_sector;
|
| 73 | bip->bip_iter.bi_size =
|
| 74 | bio_integrity_bytes(bi, data_iter->bi_size >> SECTOR_SHIFT);
|
| 75 | return blk_status_to_errno(bio_integrity_verify(bio, data_iter));
|
| 76 | }
|
| 77 |
|
| 78 | static int __init fs_bio_integrity_init(void)
|
| 79 | {
|
| 80 | fs_bio_integrity_cache = kmem_cache_create("fs_bio_integrity",
|
| 81 | sizeof(struct fs_bio_integrity_buf), 0,
|
| 82 | SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
|
| 83 | if (mempool_init_slab_pool(&fs_bio_integrity_pool, BIO_POOL_SIZE,
|
| 84 | fs_bio_integrity_cache))
|
| 85 | panic("fs_bio_integrity: can't create pool\n");
|
| 86 | return 0;
|
| 87 | }
|
| 88 | fs_initcall(fs_bio_integrity_init);
|