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
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"
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
}
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
/* Already protected? */
if (bio_integrity(bio))
return true;
-
if (bio_data_dir(bio) == READ) {
if (!(bi->flags & BLK_INTEGRITY_VERIFY))
return true;
/* 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;
}
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);
}
queue_work(kintegrityd_wq, &bip->bip_work);
return false;
}
-
bio_integrity_free(bio);
return true;
}
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)))
#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);
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) {
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;
}
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)
char *p = (char *) page;
unsigned long val = simple_strtoul(p, &p, 10);
- if (!bi->profile->verify_fn)
+ if (!bi->type)
return -EINVAL;
if (val)
char *p = (char *) page;
unsigned long val = simple_strtoul(p, &p, 10);
- if (!bi->profile->generate_fn)
+ if (!bi->type)
return -EINVAL;
if (val)
.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
{
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));
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);
#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"
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)
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);
#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));
}
/*
* 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);
+ }
}
/**
* 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;
* 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;
}
}
-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
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);
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;
#endif
}
EXPORT_SYMBOL(t10_pi_register);
-
-MODULE_LICENSE("GPL");
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;
}
# 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"
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
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;
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;
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,
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");
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 *);
{
struct blk_integrity *bi = &disk->queue->integrity;
- if (!bi->profile)
+ if (!(bi->flags & BLK_INTEGRITY_ENABLED))
return NULL;
-
return bi;
}
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)
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;
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