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;
/* 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;
}
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;
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;
}
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");
}
{
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);
/* 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;
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);
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;
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,
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;
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);
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);
}
/*
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;
}
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 *);
};
-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