block: Consolidate static integrity profile properties
authorMartin K. Petersen <martin.petersen@oracle.com>
Wed, 21 Oct 2015 17:19:33 +0000 (13:19 -0400)
committerJens Axboe <axboe@fb.com>
Wed, 21 Oct 2015 20:42:38 +0000 (14:42 -0600)
We previously made a complete copy of a device's data integrity profile
even though several of the fields inside the blk_integrity struct are
pointers to fixed template entries in t10-pi.c.

Split the static and per-device portions so that we can reference the
template directly.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Reported-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
block/bio-integrity.c
block/blk-integrity.c
block/t10-pi.c
drivers/nvdimm/core.c
drivers/nvme/host/pci.c
drivers/scsi/sd_dif.c
drivers/target/target_core_iblock.c
include/linux/blkdev.h
include/linux/t10-pi.h

index 14b8faf8b09d48937985713e10ed25745aad2dc2..a10ffe19a8dd4fee668abd1de87accf1663f21fc 100644 (file)
@@ -177,11 +177,11 @@ bool bio_integrity_enabled(struct bio *bio)
        if (bi == NULL)
                return false;
 
-       if (bio_data_dir(bio) == READ && bi->verify_fn != NULL &&
+       if (bio_data_dir(bio) == READ && bi->profile->verify_fn != NULL &&
            (bi->flags & BLK_INTEGRITY_VERIFY))
                return true;
 
-       if (bio_data_dir(bio) == WRITE && bi->generate_fn != NULL &&
+       if (bio_data_dir(bio) == WRITE && bi->profile->generate_fn != NULL &&
            (bi->flags & BLK_INTEGRITY_GENERATE))
                return true;
 
@@ -340,7 +340,7 @@ int 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, bi->generate_fn);
+               bio_integrity_process(bio, bi->profile->generate_fn);
 
        return 0;
 }
@@ -361,7 +361,7 @@ static void bio_integrity_verify_fn(struct work_struct *work)
        struct bio *bio = bip->bip_bio;
        struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
 
-       bio->bi_error = bio_integrity_process(bio, bi->verify_fn);
+       bio->bi_error = bio_integrity_process(bio, bi->profile->verify_fn);
 
        /* Restore original bio completion handler */
        bio->bi_end_io = bip->bip_end_io;
index 182bfd2383eaf92201b5afb36406de98f86a3ccc..daf590ab3b4600c216d7ad6829ef953ee99c6867 100644 (file)
@@ -176,10 +176,10 @@ int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2)
                return -1;
        }
 
-       if (strcmp(b1->name, b2->name)) {
+       if (b1->profile != b2->profile) {
                printk(KERN_ERR "%s: %s/%s type %s != %s\n", __func__,
                       gd1->disk_name, gd2->disk_name,
-                      b1->name, b2->name);
+                      b1->profile->name, b2->profile->name);
                return -1;
        }
 
@@ -275,8 +275,8 @@ static ssize_t integrity_attr_store(struct kobject *kobj,
 
 static ssize_t integrity_format_show(struct blk_integrity *bi, char *page)
 {
-       if (bi != NULL && bi->name != NULL)
-               return sprintf(page, "%s\n", bi->name);
+       if (bi != NULL && bi->profile->name != NULL)
+               return sprintf(page, "%s\n", bi->profile->name);
        else
                return sprintf(page, "none\n");
 }
@@ -401,7 +401,8 @@ bool blk_integrity_is_initialized(struct gendisk *disk)
 {
        struct blk_integrity *bi = blk_get_integrity(disk);
 
-       return (bi && bi->name && strcmp(bi->name, bi_unsupported_name) != 0);
+       return (bi && bi->profile->name && strcmp(bi->profile->name,
+                                                 bi_unsupported_name) != 0);
 }
 EXPORT_SYMBOL(blk_integrity_is_initialized);
 
@@ -446,14 +447,12 @@ int blk_integrity_register(struct gendisk *disk, struct blk_integrity *template)
 
        /* Use the provided profile as template */
        if (template != NULL) {
-               bi->name = template->name;
-               bi->generate_fn = template->generate_fn;
-               bi->verify_fn = template->verify_fn;
+               bi->profile = template->profile;
                bi->tuple_size = template->tuple_size;
                bi->tag_size = template->tag_size;
                bi->flags |= template->flags;
        } else
-               bi->name = bi_unsupported_name;
+               bi->profile->name = bi_unsupported_name;
 
        disk->queue->backing_dev_info.capabilities |= BDI_CAP_STABLE_WRITES;
 
index 24d6e9715318e682e21607119358f9582038ceff..2c97912335a90944e04927eb7be8219f361e92e0 100644 (file)
@@ -160,38 +160,30 @@ static int t10_pi_type3_verify_ip(struct blk_integrity_iter *iter)
        return t10_pi_verify(iter, t10_pi_ip_fn, 3);
 }
 
-struct blk_integrity t10_pi_type1_crc = {
+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,
-       .tuple_size             = sizeof(struct t10_pi_tuple),
-       .tag_size               = 0,
 };
 EXPORT_SYMBOL(t10_pi_type1_crc);
 
-struct blk_integrity t10_pi_type1_ip = {
+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,
-       .tuple_size             = sizeof(struct t10_pi_tuple),
-       .tag_size               = 0,
 };
 EXPORT_SYMBOL(t10_pi_type1_ip);
 
-struct blk_integrity t10_pi_type3_crc = {
+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,
-       .tuple_size             = sizeof(struct t10_pi_tuple),
-       .tag_size               = 0,
 };
 EXPORT_SYMBOL(t10_pi_type3_crc);
 
-struct blk_integrity t10_pi_type3_ip = {
+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,
-       .tuple_size             = sizeof(struct t10_pi_tuple),
-       .tag_size               = 0,
 };
 EXPORT_SYMBOL(t10_pi_type3_ip);
index cb62ec6a12d073cf1abd5422e151636d57d6f781..7df89b547ae1a809d859bac1f13efea18c22c7c2 100644 (file)
@@ -399,19 +399,22 @@ static int nd_pi_nop_generate_verify(struct blk_integrity_iter *iter)
 
 int nd_integrity_init(struct gendisk *disk, unsigned long meta_size)
 {
-       struct blk_integrity integrity = {
+       struct blk_integrity bi;
+       static struct blk_integrity_profile profile = {
                .name = "ND-PI-NOP",
                .generate_fn = nd_pi_nop_generate_verify,
                .verify_fn = nd_pi_nop_generate_verify,
-               .tuple_size = meta_size,
-               .tag_size = meta_size,
        };
        int ret;
 
        if (meta_size == 0)
                return 0;
 
-       ret = blk_integrity_register(disk, &integrity);
+       bi.profile = &profile;
+       bi.tuple_size = meta_size;
+       bi.tag_size = meta_size;
+
+       ret = blk_integrity_register(disk, &bi);
        if (ret)
                return ret;
 
index 22d83752ae87d91e0cb7689c5e99de50e3d0080a..04e3d60a1e453f27da74f7aa6a293d8c314f1f7c 100644 (file)
@@ -558,7 +558,7 @@ static int nvme_noop_generate(struct blk_integrity_iter *iter)
        return 0;
 }
 
-struct blk_integrity nvme_meta_noop = {
+struct blk_integrity_profile nvme_meta_noop = {
        .name                   = "NVME_META_NOOP",
        .generate_fn            = nvme_noop_generate,
        .verify_fn              = nvme_noop_verify,
@@ -570,14 +570,14 @@ static void nvme_init_integrity(struct nvme_ns *ns)
 
        switch (ns->pi_type) {
        case NVME_NS_DPS_PI_TYPE3:
-               integrity = t10_pi_type3_crc;
+               integrity.profile = &t10_pi_type3_crc;
                break;
        case NVME_NS_DPS_PI_TYPE1:
        case NVME_NS_DPS_PI_TYPE2:
-               integrity = t10_pi_type1_crc;
+               integrity.profile = &t10_pi_type1_crc;
                break;
        default:
-               integrity = nvme_meta_noop;
+               integrity.profile = &nvme_meta_noop;
                break;
        }
        integrity.tuple_size = ns->ms;
index 5c06d292b94c704a5dd96f8549aa732baf8b69c9..987bf392c336181036f19debf282be2c2f9d1ffa 100644 (file)
@@ -43,6 +43,7 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
        struct scsi_device *sdp = sdkp->device;
        struct gendisk *disk = sdkp->disk;
        u8 type = sdkp->protection_type;
+       struct blk_integrity bi;
        int dif, dix;
 
        dif = scsi_host_dif_capable(sdp->host, type);
@@ -55,39 +56,43 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
        if (!dix)
                return;
 
+       memset(&bi, 0, sizeof(bi));
+
        /* Enable DMA of protection information */
        if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) {
                if (type == SD_DIF_TYPE3_PROTECTION)
-                       blk_integrity_register(disk, &t10_pi_type3_ip);
+                       bi.profile = &t10_pi_type3_ip;
                else
-                       blk_integrity_register(disk, &t10_pi_type1_ip);
+                       bi.profile = &t10_pi_type1_ip;
 
-               disk->integrity->flags |= BLK_INTEGRITY_IP_CHECKSUM;
+               bi.flags |= BLK_INTEGRITY_IP_CHECKSUM;
        } else
                if (type == SD_DIF_TYPE3_PROTECTION)
-                       blk_integrity_register(disk, &t10_pi_type3_crc);
+                       bi.profile = &t10_pi_type3_crc;
                else
-                       blk_integrity_register(disk, &t10_pi_type1_crc);
+                       bi.profile = &t10_pi_type1_crc;
 
+       bi.tuple_size = sizeof(struct t10_pi_tuple);
        sd_printk(KERN_NOTICE, sdkp,
-                 "Enabling DIX %s protection\n", disk->integrity->name);
+                 "Enabling DIX %s protection\n", bi.profile->name);
 
-       /* Signal to block layer that we support sector tagging */
        if (dif && type) {
-
-               disk->integrity->flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
+               bi.flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
 
                if (!sdkp->ATO)
-                       return;
+                       goto out;
 
                if (type == SD_DIF_TYPE3_PROTECTION)
-                       disk->integrity->tag_size = sizeof(u16) + sizeof(u32);
+                       bi.tag_size = sizeof(u16) + sizeof(u32);
                else
-                       disk->integrity->tag_size = sizeof(u16);
+                       bi.tag_size = sizeof(u16);
 
                sd_printk(KERN_NOTICE, sdkp, "DIF application tag size %u\n",
-                         disk->integrity->tag_size);
+                         bi.tag_size);
        }
+
+out:
+       blk_integrity_register(disk, &bi);
 }
 
 /*
index 0f19e11acac2197806eba0a42290b5067b560d73..f29c69120054463eee986c0ab6ed48ec6c504c39 100644 (file)
@@ -155,17 +155,17 @@ static int iblock_configure_device(struct se_device *dev)
        if (bi) {
                struct bio_set *bs = ib_dev->ibd_bio_set;
 
-               if (!strcmp(bi->name, "T10-DIF-TYPE3-IP") ||
-                   !strcmp(bi->name, "T10-DIF-TYPE1-IP")) {
+               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->name);
+                              " supported\n", bi->profile->name);
                        ret = -ENOSYS;
                        goto out_blkdev_put;
                }
 
-               if (!strcmp(bi->name, "T10-DIF-TYPE3-CRC")) {
+               if (!strcmp(bi->profile->name, "T10-DIF-TYPE3-CRC")) {
                        dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE3_PROT;
-               } else if (!strcmp(bi->name, "T10-DIF-TYPE1-CRC")) {
+               } else if (!strcmp(bi->profile->name, "T10-DIF-TYPE1-CRC")) {
                        dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE1_PROT;
                }
 
index 830f9c07d4bb22e35b2a4d51921ca73c76d6e2f1..f36c6476f1c728f8a787e92576545f921dcd7503 100644 (file)
@@ -1462,16 +1462,18 @@ struct blk_integrity_iter {
 
 typedef int (integrity_processing_fn) (struct blk_integrity_iter *);
 
-struct blk_integrity {
-       integrity_processing_fn *generate_fn;
-       integrity_processing_fn *verify_fn;
-
-       unsigned short          flags;
-       unsigned short          tuple_size;
-       unsigned short          interval;
-       unsigned short          tag_size;
+struct blk_integrity_profile {
+       integrity_processing_fn         *generate_fn;
+       integrity_processing_fn         *verify_fn;
+       const char                      *name;
+};
 
-       const char              *name;
+struct blk_integrity {
+       struct blk_integrity_profile    *profile;
+       unsigned short                  flags;
+       unsigned short                  tuple_size;
+       unsigned short                  interval;
+       unsigned short                  tag_size;
 };
 
 extern bool blk_integrity_is_initialized(struct gendisk *);
index 6a8b9942632dccaf6d8ef508d7e31867ac041237..dd8de82cf5b575c8aac692595068264ef0b3dce4 100644 (file)
@@ -14,9 +14,9 @@ struct t10_pi_tuple {
 };
 
 
-extern struct blk_integrity t10_pi_type1_crc;
-extern struct blk_integrity t10_pi_type1_ip;
-extern struct blk_integrity t10_pi_type3_crc;
-extern struct blk_integrity t10_pi_type3_ip;
+extern struct blk_integrity_profile t10_pi_type1_crc;
+extern struct blk_integrity_profile t10_pi_type1_ip;
+extern struct blk_integrity_profile t10_pi_type3_crc;
+extern struct blk_integrity_profile t10_pi_type3_ip;
 
 #endif