]> www.infradead.org Git - users/hch/block.git/commitdiff
block: devirtualize the integrity processing integrity-devirtualize
authorChristoph Hellwig <hch@lst.de>
Mon, 7 Jun 2021 06:10:36 +0000 (08:10 +0200)
committerChristoph Hellwig <hch@lst.de>
Wed, 9 Jun 2021 13:01:27 +0000 (15:01 +0200)
Replace the profile with a simple integer indicating the PI
type and a new flag to signal that any integrity/metadata
processing is enabled and remove the various indirect calls.

To make this work t10-pi.c is not always built into the core kernel
when BLK_DEV_INTEGRITY is enabled, but it is down to a few hundred
lines of code and thus not very efficient when built as a separate
module anyway.

Signed-off-by: Christoph Hellwig <hch@lst.de>
17 files changed:
block/Kconfig
block/Makefile
block/bio-integrity.c
block/blk-core.c
block/blk-integrity.c
block/blk-mq.c
block/blk.h
block/t10-pi.c
drivers/md/dm-crypt.c
drivers/nvme/host/Kconfig
drivers/nvme/target/Kconfig
drivers/nvme/target/io-cmd-bdev.c
drivers/scsi/Kconfig
drivers/target/target_core_iblock.c
include/linux/blkdev.h
include/linux/genhd.h
include/linux/t10-pi.h

index a2297edfdde88d1a6390cf22211fe4bbb863105a..8f666552b165b97bf386174b767985a360248b61 100644 (file)
@@ -66,6 +66,7 @@ config BLK_DEV_BSGLIB
 
 config BLK_DEV_INTEGRITY
        bool "Block layer data integrity support"
+       select CRC_T10DIF
        help
        Some storage devices allow extra information to be
        stored/retrieved to help protect the data.  The block layer
@@ -73,13 +74,7 @@ config BLK_DEV_INTEGRITY
        filesystems to ensure better data integrity.
 
        Say yes here if you have a storage device that provides the
-       T10/SCSI Data Integrity Field or the T13/ATA External Path
-       Protection.  If in doubt, say N.
-
-config BLK_DEV_INTEGRITY_T10
-       tristate
-       depends on BLK_DEV_INTEGRITY
-       select CRC_T10DIF
+       T10/SCSI Data Integrity Field. If in doubt, say N.
 
 config BLK_DEV_ZONED
        bool "Zoned block device support"
index 8d841f5f986fe4fb673a3ccfd81ed79fcc325a7a..0cbbdf5dbe67867d40e5a2b14dd192576f545851 100644 (file)
@@ -25,8 +25,7 @@ bfq-y                         := bfq-iosched.o bfq-wf2q.o bfq-cgroup.o
 obj-$(CONFIG_IOSCHED_BFQ)      += bfq.o
 
 obj-$(CONFIG_BLK_CMDLINE_PARSER)       += cmdline-parser.o
-obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o blk-integrity.o
-obj-$(CONFIG_BLK_DEV_INTEGRITY_T10)    += t10-pi.o
+obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o blk-integrity.o t10-pi.o
 obj-$(CONFIG_BLK_MQ_PCI)       += blk-mq-pci.o
 obj-$(CONFIG_BLK_MQ_VIRTIO)    += blk-mq-virtio.o
 obj-$(CONFIG_BLK_MQ_RDMA)      += blk-mq-rdma.o
index f17682164ea0e850893c1142521b5aa6226754f7..de48d27788d0b1ad1d8a0f1401fd3ab8862639bb 100644 (file)
@@ -148,44 +148,6 @@ int bio_integrity_add_page(struct bio *bio, struct page *page,
 }
 EXPORT_SYMBOL(bio_integrity_add_page);
 
-/**
- * bio_integrity_process - Process integrity metadata for a bio
- * @bio:       bio to generate/verify integrity metadata for
- * @proc_iter:  iterator to process
- * @proc_fn:   Pointer to the relevant processing function
- */
-static blk_status_t bio_integrity_process(struct bio *bio,
-               struct bvec_iter *proc_iter, integrity_processing_fn *proc_fn)
-{
-       struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
-       struct blk_integrity_iter iter;
-       struct bvec_iter bviter;
-       struct bio_vec bv;
-       struct bio_integrity_payload *bip = bio_integrity(bio);
-       blk_status_t ret = BLK_STS_OK;
-       void *prot_buf = page_address(bip->bip_vec->bv_page) +
-               bip->bip_vec->bv_offset;
-
-       iter.disk_name = bio->bi_bdev->bd_disk->disk_name;
-       iter.interval = 1 << bi->interval_exp;
-       iter.seed = proc_iter->bi_sector;
-       iter.prot_buf = prot_buf;
-
-       __bio_for_each_segment(bv, bio, bviter, *proc_iter) {
-               void *kaddr = bvec_kmap_local(&bv);
-
-               iter.data_buf = kaddr;
-               iter.data_size = bv.bv_len;
-               ret = proc_fn(&iter);
-               kunmap_local(kaddr);
-
-               if (ret)
-                       break;
-
-       }
-       return ret;
-}
-
 /**
  * bio_integrity_prep - Prepare bio for integrity I/O
  * @bio:       bio to prepare
@@ -221,7 +183,6 @@ bool bio_integrity_prep(struct bio *bio)
        /* Already protected? */
        if (bio_integrity(bio))
                return true;
-
        if (bio_data_dir(bio) == READ) {
                if (!(bi->flags & BLK_INTEGRITY_VERIFY))
                        return true;
@@ -288,8 +249,8 @@ bool bio_integrity_prep(struct bio *bio)
 
        /* Auto-generate integrity metadata if this is a write */
        if (bio_data_dir(bio) == WRITE) {
-               bio_integrity_process(bio, &bio->bi_iter,
-                                     bi->profile->generate_fn);
+               if (bi->type > 0)
+                       t10_pi_generate(bio);
        } else {
                bip->bio_iter = bio->bi_iter;
        }
@@ -316,15 +277,9 @@ static void bio_integrity_verify_fn(struct work_struct *work)
        struct bio_integrity_payload *bip =
                container_of(work, struct bio_integrity_payload, bip_work);
        struct bio *bio = bip->bip_bio;
-       struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
 
-       /*
-        * At the moment verify is called bio's iterator was advanced
-        * during split and completion, we need to rewind iterator to
-        * it's original position.
-        */
-       bio->bi_status = bio_integrity_process(bio, &bip->bio_iter,
-                                               bi->profile->verify_fn);
+       if (blk_get_integrity(bio->bi_bdev->bd_disk)->type > 0)
+               t10_pi_verify(bio);
        bio_integrity_free(bio);
        bio_endio(bio);
 }
@@ -351,7 +306,6 @@ bool __bio_integrity_endio(struct bio *bio)
                queue_work(kintegrityd_wq, &bip->bip_work);
                return false;
        }
-
        bio_integrity_free(bio);
        return true;
 }
index 3515a66022d761361d4802cffea66cef17c6a64a..450ea66637785b73e50705bbc4df29d4a913aa04 100644 (file)
@@ -1419,11 +1419,9 @@ bool blk_update_request(struct request *req, blk_status_t error,
        if (!req->bio)
                return false;
 
-#ifdef CONFIG_BLK_DEV_INTEGRITY
-       if (blk_integrity_rq(req) && req_op(req) == REQ_OP_READ &&
-           error == BLK_STS_OK)
-               req->q->integrity.profile->complete_fn(req, nr_bytes);
-#endif
+       if (req_op(req) == REQ_OP_READ && error == BLK_STS_OK &&
+           t10_pi_need_remap(req))
+               t10_pi_type1_complete(req, nr_bytes);
 
        if (unlikely(error && !blk_rq_is_passthrough(req) &&
                     !(req->rq_flags & RQF_QUIET)))
index 607600299334a0797e8ea161d217dd1758e8c979..b5129c23ab1bb9d2900f2027dc8d77c9029f91f8 100644 (file)
 #include <linux/scatterlist.h>
 #include <linux/export.h>
 #include <linux/slab.h>
+#include <linux/t10-pi.h>
 
 #include "blk.h"
 
 const char *blk_integrity_type_str(struct blk_integrity *bi)
 {
-       return bi->profile->name;
+       switch (bi->type) {
+       case 0:
+               return "nop";
+       case T10_PI_TYPE1_PROTECTION:
+       case T10_PI_TYPE2_PROTECTION:
+               if (bi->flags & BLK_INTEGRITY_IP_CHECKSUM)
+                       return "T10-DIF-TYPE1-IP";
+               return "T10-DIF-TYPE1-CRC";
+       case T10_PI_TYPE3_PROTECTION:
+               if (bi->flags & BLK_INTEGRITY_IP_CHECKSUM)
+                       return "T10-DIF-TYPE3-IP";
+               return "T10-DIF-TYPE3-CRC";
+       default:
+               return "invalid";
+       }
 }
 EXPORT_SYMBOL_GPL(blk_integrity_type_str);
 
@@ -129,10 +144,10 @@ int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2)
        struct blk_integrity *b1 = &gd1->queue->integrity;
        struct blk_integrity *b2 = &gd2->queue->integrity;
 
-       if (!b1->profile && !b2->profile)
+       if (!b1->type && !b2->type)
                return 0;
 
-       if (!b1->profile || !b2->profile)
+       if (!b1->type || !b2->type)
                return -1;
 
        if (b1->interval_exp != b2->interval_exp) {
@@ -152,14 +167,14 @@ int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2)
        if (b1->tag_size && b2->tag_size && (b1->tag_size != b2->tag_size)) {
                pr_err("%s: %s/%s tag sz %u != %u\n", __func__,
                       gd1->disk_name, gd2->disk_name,
-                      b1->tag_size, b2->tag_size);
+                      blk_integrity_type_str(b1), blk_integrity_type_str(b2));
                return -1;
        }
 
-       if (b1->profile != b2->profile) {
+       if (b1->type != b2->type) {
                pr_err("%s: %s/%s type %s != %s\n", __func__,
                       gd1->disk_name, gd2->disk_name,
-                      b1->profile->name, b2->profile->name);
+                      blk_integrity_type_str(b1), blk_integrity_type_str(b2));
                return -1;
        }
 
@@ -246,10 +261,9 @@ static ssize_t integrity_attr_store(struct kobject *kobj,
 
 static ssize_t integrity_format_show(struct blk_integrity *bi, char *page)
 {
-       if (bi->profile && bi->profile->name)
-               return sprintf(page, "%s\n", bi->profile->name);
-       else
+       if (!(bi->flags & BLK_INTEGRITY_ENABLED))
                return sprintf(page, "none\n");
+       return sprintf(page, "%s\n", blk_integrity_type_str(bi));
 }
 
 static ssize_t integrity_tag_size_show(struct blk_integrity *bi, char *page)
@@ -269,7 +283,7 @@ static ssize_t integrity_verify_store(struct blk_integrity *bi,
        char *p = (char *) page;
        unsigned long val = simple_strtoul(p, &p, 10);
 
-       if (!bi->profile->verify_fn)
+       if (!bi->type)
                return -EINVAL;
 
        if (val)
@@ -291,7 +305,7 @@ static ssize_t integrity_generate_store(struct blk_integrity *bi,
        char *p = (char *) page;
        unsigned long val = simple_strtoul(p, &p, 10);
 
-       if (!bi->profile->generate_fn)
+       if (!bi->type)
                return -EINVAL;
 
        if (val)
@@ -366,28 +380,6 @@ static struct kobj_type integrity_ktype = {
        .sysfs_ops      = &integrity_ops,
 };
 
-static blk_status_t blk_integrity_nop_fn(struct blk_integrity_iter *iter)
-{
-       return BLK_STS_OK;
-}
-
-static void blk_integrity_nop_prepare(struct request *rq)
-{
-}
-
-static void blk_integrity_nop_complete(struct request *rq,
-               unsigned int nr_bytes)
-{
-}
-
-static const struct blk_integrity_profile nop_profile = {
-       .name = "nop",
-       .generate_fn = blk_integrity_nop_fn,
-       .verify_fn = blk_integrity_nop_fn,
-       .prepare_fn = blk_integrity_nop_prepare,
-       .complete_fn = blk_integrity_nop_complete,
-};
-
 /**
  * blk_nointegrity_register - Register a gendisk as having non-itegrity metadata
  * @disk:      struct gendisk pointer to make integrity-aware
@@ -397,8 +389,8 @@ void blk_nointegrity_register(struct gendisk *disk, unsigned char meta_size)
 {
        struct blk_integrity *bi = &disk->queue->integrity;
 
-       bi->flags = 0;
-       bi->profile = &nop_profile;
+       bi->flags = BLK_INTEGRITY_ENABLED;
+       bi->type = 0;
        bi->tuple_size = meta_size;
        bi->tag_size = meta_size;
        bi->interval_exp = ilog2(queue_logical_block_size(disk->queue));
index f11d4018ce2eae45dee03c926cc86de19c3fe70b..a821796ec952b4ec5dd9cae0ed505c08d3635a50 100644 (file)
@@ -727,10 +727,8 @@ void blk_mq_start_request(struct request *rq)
        blk_add_timer(rq);
        WRITE_ONCE(rq->state, MQ_RQ_IN_FLIGHT);
 
-#ifdef CONFIG_BLK_DEV_INTEGRITY
-       if (blk_integrity_rq(rq) && req_op(rq) == REQ_OP_WRITE)
-               q->integrity.profile->prepare_fn(rq);
-#endif
+       if (req_op(rq) == REQ_OP_WRITE && t10_pi_need_remap(rq))
+               t10_pi_type1_prepare(rq);
 }
 EXPORT_SYMBOL(blk_mq_start_request);
 
index 3440142f029b22fcbed16b1f1ca1a701ae37f42f..39e3d9c6dfaa2c91e870586df6d4287def9e19f1 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/part_stat.h>
 #include <linux/blk-crypto.h>
 #include <linux/memblock.h>    /* for max_pfn/max_low_pfn */
+#include <linux/t10-pi.h>
 #include <xen/xen.h>
 #include "blk-crypto-internal.h"
 #include "blk-mq.h"
@@ -134,6 +135,15 @@ static inline bool integrity_req_gap_front_merge(struct request *req,
 
 void blk_integrity_add(struct gendisk *);
 void blk_integrity_del(struct gendisk *);
+
+static inline bool t10_pi_need_remap(struct request *rq)
+{
+       if (!blk_integrity_rq(rq))
+               return false;
+       /* Type 3 does not have a reference tag so no remapping is required. */
+       return rq->q->integrity.type == T10_PI_TYPE1_PROTECTION ||
+               rq->q->integrity.type == T10_PI_TYPE2_PROTECTION;
+}
 #else /* CONFIG_BLK_DEV_INTEGRITY */
 static inline bool blk_integrity_merge_rq(struct request_queue *rq,
                struct request *r1, struct request *r2)
@@ -172,8 +182,17 @@ static inline void blk_integrity_add(struct gendisk *disk)
 static inline void blk_integrity_del(struct gendisk *disk)
 {
 }
+static inline bool t10_pi_need_remap(struct request *rq)
+{
+       return false;
+}
 #endif /* CONFIG_BLK_DEV_INTEGRITY */
 
+void t10_pi_generate(struct bio *bio);
+void t10_pi_verify(struct bio *bio);
+void t10_pi_type1_prepare(struct request *rq);
+void t10_pi_type1_complete(struct request *rq, unsigned int nr_bytes);
+
 unsigned long blk_rq_timeout(unsigned long timeout);
 void blk_add_timer(struct request *req);
 
index 8c31bc859f24677745e04dadd80c5ee5207861a0..d413868fedcda3a5d3d62f23d992dab5c1d34b6f 100644 (file)
@@ -9,17 +9,15 @@
 #include <linux/crc-t10dif.h>
 #include <linux/module.h>
 #include <net/checksum.h>
+#include "blk.h"
 
-typedef __be16 (csum_fn) (void *, unsigned int);
-
-static __be16 t10_pi_crc_fn(void *data, unsigned int len)
+static __be16 t10_pi_csum(struct blk_integrity *bi, void *data)
 {
-       return cpu_to_be16(crc_t10dif(data, len));
-}
+       unsigned short interval = 1 << bi->interval_exp;
 
-static __be16 t10_pi_ip_fn(void *data, unsigned int len)
-{
-       return (__force __be16)ip_compute_csum(data, len);
+       if (bi->flags & BLK_INTEGRITY_IP_CHECKSUM)
+               return (__force __be16)ip_compute_csum(data, interval);
+       return cpu_to_be16(crc_t10dif(data, interval));
 }
 
 /*
@@ -27,97 +25,113 @@ static __be16 t10_pi_ip_fn(void *data, unsigned int len)
  * 16 bit app tag, 32 bit reference tag. Type 3 does not define the ref
  * tag.
  */
-static blk_status_t t10_pi_generate(struct blk_integrity_iter *iter,
-               csum_fn *fn, enum t10_dif_type type)
+static void t10_pi_generate_bvec(struct bio *bio, sector_t seed,
+               struct bio_vec *data_bvec, void *prot_buf)
 {
+       struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
+       unsigned short interval = 1 << bi->interval_exp;
+       void *data_buf = bvec_kmap_local(data_bvec);
        unsigned int i;
 
-       for (i = 0 ; i < iter->data_size ; i += iter->interval) {
-               struct t10_pi_tuple *pi = iter->prot_buf;
+       for (i = 0 ; i < data_bvec->bv_len ; i += interval) {
+               struct t10_pi_tuple *pi = prot_buf;
 
-               pi->guard_tag = fn(iter->data_buf, iter->interval);
+               pi->guard_tag = t10_pi_csum(bi, data_buf);
                pi->app_tag = 0;
 
-               if (type == T10_PI_TYPE1_PROTECTION)
-                       pi->ref_tag = cpu_to_be32(lower_32_bits(iter->seed));
+               if (bi->type == T10_PI_TYPE1_PROTECTION)
+                       pi->ref_tag = cpu_to_be32(lower_32_bits(seed));
                else
                        pi->ref_tag = 0;
 
-               iter->data_buf += iter->interval;
-               iter->prot_buf += sizeof(struct t10_pi_tuple);
-               iter->seed++;
+               data_buf += interval;
+               prot_buf += sizeof(struct t10_pi_tuple);
+               seed++;
        }
 
-       return BLK_STS_OK;
+       kunmap_local(data_buf);
 }
 
-static blk_status_t t10_pi_verify(struct blk_integrity_iter *iter,
-               csum_fn *fn, enum t10_dif_type type)
+void t10_pi_generate(struct bio *bio)
 {
+       void *prot_buf = bvec_virt(bio_integrity(bio)->bip_vec);
+       struct bvec_iter iter;
+       struct bio_vec bv;
+
+       __bio_for_each_segment(bv, bio, iter, bio->bi_iter)
+               t10_pi_generate_bvec(bio, iter.bi_sector, &bv, prot_buf);
+}
+
+static blk_status_t t10_pi_verify_bvec(struct bio *bio, sector_t seed,
+               struct bio_vec *data_bvec, void *prot_buf)
+{
+       struct gendisk *disk = bio->bi_bdev->bd_disk;
+       struct blk_integrity *bi = blk_get_integrity(disk);
+       unsigned short interval = 1 << bi->interval_exp;
+       void *data_buf = bvec_kmap_local(data_bvec);
+       blk_status_t ret = BLK_STS_PROTECTION;
        unsigned int i;
 
-       BUG_ON(type == T10_PI_TYPE0_PROTECTION);
+       BUG_ON(bi->type == T10_PI_TYPE0_PROTECTION);
 
-       for (i = 0 ; i < iter->data_size ; i += iter->interval) {
-               struct t10_pi_tuple *pi = iter->prot_buf;
+       for (i = 0 ; i < data_bvec->bv_len ; i += interval) {
+               struct t10_pi_tuple *pi = prot_buf;
                __be16 csum;
 
-               if (type == T10_PI_TYPE1_PROTECTION ||
-                   type == T10_PI_TYPE2_PROTECTION) {
+               if (bi->type == T10_PI_TYPE1_PROTECTION ||
+                   bi->type == T10_PI_TYPE2_PROTECTION) {
                        if (pi->app_tag == T10_PI_APP_ESCAPE)
                                goto next;
 
-                       if (be32_to_cpu(pi->ref_tag) !=
-                           lower_32_bits(iter->seed)) {
-                               pr_err("%s: ref tag error at location %llu " \
-                                      "(rcvd %u)\n", iter->disk_name,
-                                      (unsigned long long)
-                                      iter->seed, be32_to_cpu(pi->ref_tag));
-                               return BLK_STS_PROTECTION;
+                       if (be32_to_cpu(pi->ref_tag) != lower_32_bits(seed)) {
+                               pr_err("%s: ref tag error at location %llu (rcvd %u)\n",
+                                       disk->disk_name, seed,
+                                       be32_to_cpu(pi->ref_tag));
+                               goto out_unmap;
                        }
-               } else if (type == T10_PI_TYPE3_PROTECTION) {
+               } else if (bi->type == T10_PI_TYPE3_PROTECTION) {
                        if (pi->app_tag == T10_PI_APP_ESCAPE &&
                            pi->ref_tag == T10_PI_REF_ESCAPE)
                                goto next;
                }
 
-               csum = fn(iter->data_buf, iter->interval);
-
+               csum = t10_pi_csum(bi, data_buf);
                if (pi->guard_tag != csum) {
-                       pr_err("%s: guard tag error at sector %llu " \
-                              "(rcvd %04x, want %04x)\n", iter->disk_name,
-                              (unsigned long long)iter->seed,
-                              be16_to_cpu(pi->guard_tag), be16_to_cpu(csum));
-                       return BLK_STS_PROTECTION;
+                       pr_err("%s: guard tag error at sector %llu (rcvd %04x, want %04x)\n",
+                               disk->disk_name, seed,
+                               be16_to_cpu(pi->guard_tag), be16_to_cpu(csum));
+                       goto out_unmap;
                }
 
 next:
-               iter->data_buf += iter->interval;
-               iter->prot_buf += sizeof(struct t10_pi_tuple);
-               iter->seed++;
+               data_buf += interval;
+               prot_buf += sizeof(struct t10_pi_tuple);
+               seed++;
        }
 
-       return BLK_STS_OK;
-}
-
-static blk_status_t t10_pi_type1_generate_crc(struct blk_integrity_iter *iter)
-{
-       return t10_pi_generate(iter, t10_pi_crc_fn, T10_PI_TYPE1_PROTECTION);
+       ret = BLK_STS_OK;
+out_unmap:
+       kunmap_local(data_buf);
+       return ret;
 }
 
-static blk_status_t t10_pi_type1_generate_ip(struct blk_integrity_iter *iter)
+void t10_pi_verify(struct bio *bio)
 {
-       return t10_pi_generate(iter, t10_pi_ip_fn, T10_PI_TYPE1_PROTECTION);
-}
-
-static blk_status_t t10_pi_type1_verify_crc(struct blk_integrity_iter *iter)
-{
-       return t10_pi_verify(iter, t10_pi_crc_fn, T10_PI_TYPE1_PROTECTION);
-}
+       void *prot_buf = bvec_virt(bio_integrity(bio)->bip_vec);
+       struct bvec_iter iter;
+       struct bio_vec bv;
+
+       /*
+        * At this point bi_iter has already been advanced, so use the copy
+        * saved away at submission time.
+        */
+       __bio_for_each_segment(bv, bio, iter, bio->bi_integrity->bio_iter) {
+               bio->bi_status = t10_pi_verify_bvec(bio, iter.bi_sector, &bv,
+                                                   prot_buf);
+               if (bio->bi_status)
+                       break;
 
-static blk_status_t t10_pi_type1_verify_ip(struct blk_integrity_iter *iter)
-{
-       return t10_pi_verify(iter, t10_pi_ip_fn, T10_PI_TYPE1_PROTECTION);
+       }
 }
 
 /**
@@ -130,8 +144,9 @@ static blk_status_t t10_pi_type1_verify_ip(struct blk_integrity_iter *iter)
  * likely to be different. Remap protection information to match the
  * physical LBA.
  */
-static void t10_pi_type1_prepare(struct request *rq)
+void t10_pi_type1_prepare(struct request *rq)
 {
+       struct blk_integrity *bi = &rq->q->integrity;
        const int tuple_sz = rq->q->integrity.tuple_size;
        u32 ref_tag = t10_pi_ref_tag(rq);
        struct bio *bio;
@@ -179,10 +194,11 @@ static void t10_pi_type1_prepare(struct request *rq)
  * to the device, we should remap it back to virtual values expected by the
  * block layer.
  */
-static void t10_pi_type1_complete(struct request *rq, unsigned int nr_bytes)
+void t10_pi_type1_complete(struct request *rq, unsigned int nr_bytes)
 {
-       unsigned intervals = nr_bytes >> rq->q->integrity.interval_exp;
-       const int tuple_sz = rq->q->integrity.tuple_size;
+       struct blk_integrity *bi = &rq->q->integrity;
+       unsigned intervals = nr_bytes >> bi->interval_exp;
+       const int tuple_sz = bi->tuple_size;
        u32 ref_tag = t10_pi_ref_tag(rq);
        struct bio *bio;
 
@@ -212,70 +228,6 @@ static void t10_pi_type1_complete(struct request *rq, unsigned int nr_bytes)
        }
 }
 
-static blk_status_t t10_pi_type3_generate_crc(struct blk_integrity_iter *iter)
-{
-       return t10_pi_generate(iter, t10_pi_crc_fn, T10_PI_TYPE3_PROTECTION);
-}
-
-static blk_status_t t10_pi_type3_generate_ip(struct blk_integrity_iter *iter)
-{
-       return t10_pi_generate(iter, t10_pi_ip_fn, T10_PI_TYPE3_PROTECTION);
-}
-
-static blk_status_t t10_pi_type3_verify_crc(struct blk_integrity_iter *iter)
-{
-       return t10_pi_verify(iter, t10_pi_crc_fn, T10_PI_TYPE3_PROTECTION);
-}
-
-static blk_status_t t10_pi_type3_verify_ip(struct blk_integrity_iter *iter)
-{
-       return t10_pi_verify(iter, t10_pi_ip_fn, T10_PI_TYPE3_PROTECTION);
-}
-
-/* Type 3 does not have a reference tag so no remapping is required. */
-static void t10_pi_type3_prepare(struct request *rq)
-{
-}
-
-/* Type 3 does not have a reference tag so no remapping is required. */
-static void t10_pi_type3_complete(struct request *rq, unsigned int nr_bytes)
-{
-}
-
-const struct blk_integrity_profile t10_pi_type1_crc = {
-       .name                   = "T10-DIF-TYPE1-CRC",
-       .generate_fn            = t10_pi_type1_generate_crc,
-       .verify_fn              = t10_pi_type1_verify_crc,
-       .prepare_fn             = t10_pi_type1_prepare,
-       .complete_fn            = t10_pi_type1_complete,
-};
-EXPORT_SYMBOL(t10_pi_type1_crc);
-
-static const struct blk_integrity_profile t10_pi_type1_ip = {
-       .name                   = "T10-DIF-TYPE1-IP",
-       .generate_fn            = t10_pi_type1_generate_ip,
-       .verify_fn              = t10_pi_type1_verify_ip,
-       .prepare_fn             = t10_pi_type1_prepare,
-       .complete_fn            = t10_pi_type1_complete,
-};
-
-const struct blk_integrity_profile t10_pi_type3_crc = {
-       .name                   = "T10-DIF-TYPE3-CRC",
-       .generate_fn            = t10_pi_type3_generate_crc,
-       .verify_fn              = t10_pi_type3_verify_crc,
-       .prepare_fn             = t10_pi_type3_prepare,
-       .complete_fn            = t10_pi_type3_complete,
-};
-EXPORT_SYMBOL(t10_pi_type3_crc);
-
-static const struct blk_integrity_profile t10_pi_type3_ip = {
-       .name                   = "T10-DIF-TYPE3-IP",
-       .generate_fn            = t10_pi_type3_generate_ip,
-       .verify_fn              = t10_pi_type3_verify_ip,
-       .prepare_fn             = t10_pi_type3_prepare,
-       .complete_fn            = t10_pi_type3_complete,
-};
-
 /**
  * t10_pi_register - Register a gendisk as being T10-PI capable
  * @disk:      struct gendisk pointer to make integrity-aware
@@ -293,16 +245,7 @@ void t10_pi_register(struct gendisk *disk, enum t10_dif_type type,
                break;
        case T10_PI_TYPE2_PROTECTION:
        case T10_PI_TYPE1_PROTECTION:
-               if (flags & BLK_INTEGRITY_IP_CHECKSUM)
-                       bi->profile = &t10_pi_type1_ip;
-               else
-                       bi->profile = &t10_pi_type1_crc;
-               break;
        case T10_PI_TYPE3_PROTECTION:
-               if (flags & BLK_INTEGRITY_IP_CHECKSUM)
-                       bi->profile = &t10_pi_type3_ip;
-               else
-                       bi->profile = &t10_pi_type3_crc;
                break;
        default:
                WARN_ON_ONCE(1);
@@ -311,7 +254,9 @@ void t10_pi_register(struct gendisk *disk, enum t10_dif_type type,
 
        bi->tuple_size = sizeof(struct t10_pi_tuple);
        bi->interval_exp = ilog2(queue_logical_block_size(disk->queue));
-       bi->flags = flags | BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE;
+       bi->flags = flags | BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE |
+                       BLK_INTEGRITY_ENABLED;
+       bi->type = type;
 
        if (!(flags & BLK_INTEGRITY_APP_TAG))
                bi->tag_size = 0;
@@ -331,5 +276,3 @@ void t10_pi_register(struct gendisk *disk, enum t10_dif_type type,
 #endif
 }
 EXPORT_SYMBOL(t10_pi_register);
-
-MODULE_LICENSE("GPL");
index 9a956faab135e3d7dfc9ac13c287a7996c9b4e49..05c13502fb1bccefcc25054d51d816fa1a41fd2a 100644 (file)
@@ -1165,7 +1165,7 @@ static int crypt_integrity_ctr(struct crypt_config *cc, struct dm_target *ti)
        struct mapped_device *md = dm_table_get_md(ti->table);
 
        /* From now we require underlying device with our integrity profile */
-       if (!bi || strcmp(bi->profile->name, "nop")) {
+       if (!bi || bi->type != 0) {
                ti->error = "Integrity profile not supported.";
                return -EINVAL;
        }
index a44d49d63968a45a4c29f89ac9c7dadcb8890961..f7da23cf7a6f5eaec1ff3fd1240d505496470bc1 100644 (file)
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config NVME_CORE
        tristate
-       select BLK_DEV_INTEGRITY_T10 if BLK_DEV_INTEGRITY
 
 config BLK_DEV_NVME
        tristate "NVM Express block device"
index 4be2ececbc45ba8c5bfb811a4766a122d48ae35f..3d8200f8bb3774913b162741ef236c21c439f915 100644 (file)
@@ -4,7 +4,6 @@ config NVME_TARGET
        tristate "NVMe Target support"
        depends on BLOCK
        depends on CONFIGFS_FS
-       select BLK_DEV_INTEGRITY_T10 if BLK_DEV_INTEGRITY
        select SGL_ALLOC
        help
          This enabled target side support for the NVMe protocol, that is
index 429263ca9b978a6f6ebe282be1a30d19198cd6db..9e9edc972c5daa8203cb277adcb3c3a5e256d8c7 100644 (file)
@@ -53,10 +53,8 @@ static void nvmet_bdev_ns_enable_integrity(struct nvmet_ns *ns)
 
        if (bi) {
                ns->metadata_size = bi->tuple_size;
-               if (bi->profile == &t10_pi_type1_crc)
-                       ns->pi_type = NVME_NS_DPS_PI_TYPE1;
-               else if (bi->profile == &t10_pi_type3_crc)
-                       ns->pi_type = NVME_NS_DPS_PI_TYPE3;
+               if (bi->type >= 1 && bi->type <= 3)
+                       ns->pi_type = bi->type;
                else
                        /* Unsupported metadata type */
                        ns->metadata_size = 0;
@@ -83,7 +81,7 @@ int nvmet_bdev_ns_enable(struct nvmet_ns *ns)
 
        ns->pi_type = 0;
        ns->metadata_size = 0;
-       if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY_T10))
+       if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY))
                nvmet_bdev_ns_enable_integrity(ns);
 
        return 0;
index 3d114be5b662df8d69692d22537a61d00783025a..aa823795991e9336874740c841a80901dd40bc01 100644 (file)
@@ -68,7 +68,6 @@ comment "SCSI support type (disk, tape, CD-ROM)"
 config BLK_DEV_SD
        tristate "SCSI disk support"
        depends on SCSI
-       select BLK_DEV_INTEGRITY_T10 if BLK_DEV_INTEGRITY
        help
          If you want to use SCSI hard disks, Fibre Channel disks,
          Serial ATA (SATA) or Parallel ATA (PATA) hard disks,
index d6fdd1c61f90374957a2bdff0abb26b94f894abf..faabc130df2a88410dfc68146772bcadfe9e54d1 100644 (file)
@@ -139,20 +139,15 @@ static int iblock_configure_device(struct se_device *dev)
        if (bi) {
                struct bio_set *bs = &ib_dev->ibd_bio_set;
 
-               if (!strcmp(bi->profile->name, "T10-DIF-TYPE3-IP") ||
-                   !strcmp(bi->profile->name, "T10-DIF-TYPE1-IP")) {
-                       pr_err("IBLOCK export of blk_integrity: %s not"
-                              " supported\n", bi->profile->name);
+               if (bi->flags & BLK_INTEGRITY_IP_CHECKSUM) {
+                       pr_err("IBLOCK export of blk_integrity: %s not supported\n",
+                               blk_integrity_type_str(bi));
                        ret = -ENOSYS;
                        goto out_blkdev_put;
                }
 
-               if (!strcmp(bi->profile->name, "T10-DIF-TYPE3-CRC")) {
-                       dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE3_PROT;
-               } else if (!strcmp(bi->profile->name, "T10-DIF-TYPE1-CRC")) {
-                       dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE1_PROT;
-               }
-
+               if (bi->type >= 1 && bi->type <= 3)
+                       dev->dev_attrib.pi_prot_type = bi->type;
                if (dev->dev_attrib.pi_prot_type) {
                        if (bioset_integrity_create(bs, IBLOCK_BIO_POOL_SIZE) < 0) {
                                pr_err("Unable to allocate bioset for PI\n");
index 24a1a230dfd55069fe81c15f289bc4c7f5e8cc82..b2858aaa26c6f9d2dfc85c3d553c1f35e24c4475 100644 (file)
@@ -1653,30 +1653,10 @@ enum blk_integrity_flags {
        BLK_INTEGRITY_DEVICE_CAPABLE    = 1 << 2,
        BLK_INTEGRITY_IP_CHECKSUM       = 1 << 3,
        BLK_INTEGRITY_APP_TAG           = 1 << 4,
+       BLK_INTEGRITY_ENABLED           = 1 << 5,
 };
 
 #ifdef CONFIG_BLK_DEV_INTEGRITY
-struct blk_integrity_iter {
-       void                    *prot_buf;
-       void                    *data_buf;
-       sector_t                seed;
-       unsigned int            data_size;
-       unsigned short          interval;
-       const char              *disk_name;
-};
-
-typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *);
-typedef void (integrity_prepare_fn) (struct request *);
-typedef void (integrity_complete_fn) (struct request *, unsigned int);
-
-struct blk_integrity_profile {
-       integrity_processing_fn         *generate_fn;
-       integrity_processing_fn         *verify_fn;
-       integrity_prepare_fn            *prepare_fn;
-       integrity_complete_fn           *complete_fn;
-       const char                      *name;
-};
-
 void blk_integrity_copy(struct gendisk *to, struct gendisk *from);
 void blk_nointegrity_register(struct gendisk *disk, unsigned char meta_size);
 extern void blk_integrity_unregister(struct gendisk *);
@@ -1689,9 +1669,8 @@ static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk)
 {
        struct blk_integrity *bi = &disk->queue->integrity;
 
-       if (!bi->profile)
+       if (!(bi->flags & BLK_INTEGRITY_ENABLED))
                return NULL;
-
        return bi;
 }
 
@@ -1704,7 +1683,7 @@ struct blk_integrity *bdev_get_integrity(struct block_device *bdev)
 static inline bool
 blk_queue_supports_integrity(struct request_queue *q)
 {
-       return q->integrity.profile;
+       return q->integrity.flags & BLK_INTEGRITY_ENABLED;
 }
 
 static inline bool blk_integrity_rq(struct request *rq)
index 03d684f0498fb46e453bbc3891ef3706c4886da1..d85ba614b2ba754da46204fa7de9a6795805ac1e 100644 (file)
@@ -121,7 +121,7 @@ struct disk_events;
 struct badblocks;
 
 struct blk_integrity {
-       const struct blk_integrity_profile      *profile;
+       unsigned char                           type;
        unsigned char                           flags;
        unsigned char                           tuple_size;
        unsigned char                           interval_exp;
index 6758dd7844a78d1441d27a3123631c912a6a5842..0cb1e86de28e80c4deb822ef2886859472dec93c 100644 (file)
@@ -51,7 +51,4 @@ static inline u32 t10_pi_ref_tag(struct request *rq)
 void t10_pi_register(struct gendisk *disk, enum t10_dif_type type,
                unsigned int flags);
 
-extern const struct blk_integrity_profile t10_pi_type1_crc;
-extern const struct blk_integrity_profile t10_pi_type3_crc;
-
 #endif