Skip to content

Commit e9f5f44

Browse files
Christoph Hellwigaxboe
authored andcommitted
block: remove the blk_integrity_profile structure
Block layer integrity configuration is a bit complex right now, as it indirects through operation vectors for a simple two-dimensional configuration: a) the checksum type of none, ip checksum, crc, crc64 b) the presence or absence of a reference tag Remove the integrity profile, and instead add a separate csum_type flag which replaces the existing ip-checksum field and a new flag that indicates the presence of the reference tag. This removes up to two layers of indirect calls, remove the need to offload the no-op verification of non-PI metadata to a workqueue and generally simplifies the code. The downside is that block/t10-pi.c now has to be built into the kernel when CONFIG_BLK_DEV_INTEGRITY is supported. Given that both nvme and SCSI require t10-pi.ko, it is loaded for all usual configurations that enabled CONFIG_BLK_DEV_INTEGRITY already, though. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Kanchan Joshi <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: Martin K. Petersen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 63e6495 commit e9f5f44

File tree

18 files changed

+215
-314
lines changed

18 files changed

+215
-314
lines changed

block/Kconfig

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ config BLK_DEV_BSGLIB
6262

6363
config BLK_DEV_INTEGRITY
6464
bool "Block layer data integrity support"
65+
select CRC_T10DIF
66+
select CRC64_ROCKSOFT
6567
help
6668
Some storage devices allow extra information to be
6769
stored/retrieved to help protect the data. The block layer
@@ -72,12 +74,6 @@ config BLK_DEV_INTEGRITY
7274
T10/SCSI Data Integrity Field or the T13/ATA External Path
7375
Protection. If in doubt, say N.
7476

75-
config BLK_DEV_INTEGRITY_T10
76-
tristate
77-
depends on BLK_DEV_INTEGRITY
78-
select CRC_T10DIF
79-
select CRC64_ROCKSOFT
80-
8177
config BLK_DEV_WRITE_MOUNTED
8278
bool "Allow writing to mounted block devices"
8379
default y

block/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ obj-$(CONFIG_MQ_IOSCHED_KYBER) += kyber-iosched.o
2626
bfq-y := bfq-iosched.o bfq-wf2q.o bfq-cgroup.o
2727
obj-$(CONFIG_IOSCHED_BFQ) += bfq.o
2828

29-
obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o blk-integrity.o
30-
obj-$(CONFIG_BLK_DEV_INTEGRITY_T10) += t10-pi.o
29+
obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o blk-integrity.o t10-pi.o
3130
obj-$(CONFIG_BLK_MQ_PCI) += blk-mq-pci.o
3231
obj-$(CONFIG_BLK_MQ_VIRTIO) += blk-mq-virtio.o
3332
obj-$(CONFIG_BLK_DEV_ZONED) += blk-zoned.o

block/bio-integrity.c

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -378,10 +378,9 @@ EXPORT_SYMBOL_GPL(bio_integrity_map_user);
378378
* bio_integrity_process - Process integrity metadata for a bio
379379
* @bio: bio to generate/verify integrity metadata for
380380
* @proc_iter: iterator to process
381-
* @proc_fn: Pointer to the relevant processing function
382381
*/
383382
static blk_status_t bio_integrity_process(struct bio *bio,
384-
struct bvec_iter *proc_iter, integrity_processing_fn *proc_fn)
383+
struct bvec_iter *proc_iter)
385384
{
386385
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
387386
struct blk_integrity_iter iter;
@@ -392,17 +391,18 @@ static blk_status_t bio_integrity_process(struct bio *bio,
392391

393392
iter.disk_name = bio->bi_bdev->bd_disk->disk_name;
394393
iter.interval = 1 << bi->interval_exp;
395-
iter.tuple_size = bi->tuple_size;
396394
iter.seed = proc_iter->bi_sector;
397395
iter.prot_buf = bvec_virt(bip->bip_vec);
398-
iter.pi_offset = bi->pi_offset;
399396

400397
__bio_for_each_segment(bv, bio, bviter, *proc_iter) {
401398
void *kaddr = bvec_kmap_local(&bv);
402399

403400
iter.data_buf = kaddr;
404401
iter.data_size = bv.bv_len;
405-
ret = proc_fn(&iter);
402+
if (bio_data_dir(bio) == WRITE)
403+
blk_integrity_generate(&iter, bi);
404+
else
405+
ret = blk_integrity_verify(&iter, bi);
406406
kunmap_local(kaddr);
407407

408408
if (ret)
@@ -448,12 +448,10 @@ bool bio_integrity_prep(struct bio *bio)
448448
return true;
449449

450450
if (bio_data_dir(bio) == READ) {
451-
if (!bi->profile->verify_fn ||
452-
!(bi->flags & BLK_INTEGRITY_VERIFY))
451+
if (!(bi->flags & BLK_INTEGRITY_VERIFY))
453452
return true;
454453
} else {
455-
if (!bi->profile->generate_fn ||
456-
!(bi->flags & BLK_INTEGRITY_GENERATE))
454+
if (!(bi->flags & BLK_INTEGRITY_GENERATE))
457455
return true;
458456

459457
/*
@@ -488,7 +486,7 @@ bool bio_integrity_prep(struct bio *bio)
488486
bip->bip_flags |= BIP_BLOCK_INTEGRITY;
489487
bip_set_seed(bip, bio->bi_iter.bi_sector);
490488

491-
if (bi->flags & BLK_INTEGRITY_IP_CHECKSUM)
489+
if (bi->csum_type == BLK_INTEGRITY_CSUM_IP)
492490
bip->bip_flags |= BIP_IP_CHECKSUM;
493491

494492
/* Map it */
@@ -511,12 +509,10 @@ bool bio_integrity_prep(struct bio *bio)
511509
}
512510

513511
/* Auto-generate integrity metadata if this is a write */
514-
if (bio_data_dir(bio) == WRITE) {
515-
bio_integrity_process(bio, &bio->bi_iter,
516-
bi->profile->generate_fn);
517-
} else {
512+
if (bio_data_dir(bio) == WRITE)
513+
bio_integrity_process(bio, &bio->bi_iter);
514+
else
518515
bip->bio_iter = bio->bi_iter;
519-
}
520516
return true;
521517

522518
err_end_io:
@@ -539,15 +535,13 @@ static void bio_integrity_verify_fn(struct work_struct *work)
539535
struct bio_integrity_payload *bip =
540536
container_of(work, struct bio_integrity_payload, bip_work);
541537
struct bio *bio = bip->bip_bio;
542-
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
543538

544539
/*
545540
* At the moment verify is called bio's iterator was advanced
546541
* during split and completion, we need to rewind iterator to
547542
* it's original position.
548543
*/
549-
bio->bi_status = bio_integrity_process(bio, &bip->bio_iter,
550-
bi->profile->verify_fn);
544+
bio->bi_status = bio_integrity_process(bio, &bip->bio_iter);
551545
bio_integrity_free(bio);
552546
bio_endio(bio);
553547
}
@@ -569,7 +563,7 @@ bool __bio_integrity_endio(struct bio *bio)
569563
struct bio_integrity_payload *bip = bio_integrity(bio);
570564

571565
if (bio_op(bio) == REQ_OP_READ && !bio->bi_status &&
572-
(bip->bip_flags & BIP_BLOCK_INTEGRITY) && bi->profile->verify_fn) {
566+
(bip->bip_flags & BIP_BLOCK_INTEGRITY) && bi->csum_type) {
573567
INIT_WORK(&bip->bip_work, bio_integrity_verify_fn);
574568
queue_work(kintegrityd_wq, &bip->bip_work);
575569
return false;

block/blk-integrity.c

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2)
123123
struct blk_integrity *b1 = &gd1->queue->integrity;
124124
struct blk_integrity *b2 = &gd2->queue->integrity;
125125

126-
if (!b1->profile && !b2->profile)
126+
if (!b1->tuple_size && !b2->tuple_size)
127127
return 0;
128128

129-
if (!b1->profile || !b2->profile)
129+
if (!b1->tuple_size || !b2->tuple_size)
130130
return -1;
131131

132132
if (b1->interval_exp != b2->interval_exp) {
@@ -150,10 +150,13 @@ int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2)
150150
return -1;
151151
}
152152

153-
if (b1->profile != b2->profile) {
153+
if (b1->csum_type != b2->csum_type ||
154+
(b1->flags & BLK_INTEGRITY_REF_TAG) !=
155+
(b2->flags & BLK_INTEGRITY_REF_TAG)) {
154156
pr_err("%s: %s/%s type %s != %s\n", __func__,
155157
gd1->disk_name, gd2->disk_name,
156-
b1->profile->name, b2->profile->name);
158+
blk_integrity_profile_name(b1),
159+
blk_integrity_profile_name(b2));
157160
return -1;
158161
}
159162

@@ -217,14 +220,37 @@ static inline struct blk_integrity *dev_to_bi(struct device *dev)
217220
return &dev_to_disk(dev)->queue->integrity;
218221
}
219222

223+
const char *blk_integrity_profile_name(struct blk_integrity *bi)
224+
{
225+
switch (bi->csum_type) {
226+
case BLK_INTEGRITY_CSUM_IP:
227+
if (bi->flags & BLK_INTEGRITY_REF_TAG)
228+
return "T10-DIF-TYPE1-IP";
229+
return "T10-DIF-TYPE3-IP";
230+
case BLK_INTEGRITY_CSUM_CRC:
231+
if (bi->flags & BLK_INTEGRITY_REF_TAG)
232+
return "T10-DIF-TYPE1-CRC";
233+
return "T10-DIF-TYPE3-CRC";
234+
case BLK_INTEGRITY_CSUM_CRC64:
235+
if (bi->flags & BLK_INTEGRITY_REF_TAG)
236+
return "EXT-DIF-TYPE1-CRC64";
237+
return "EXT-DIF-TYPE3-CRC64";
238+
case BLK_INTEGRITY_CSUM_NONE:
239+
break;
240+
}
241+
242+
return "nop";
243+
}
244+
EXPORT_SYMBOL_GPL(blk_integrity_profile_name);
245+
220246
static ssize_t format_show(struct device *dev, struct device_attribute *attr,
221247
char *page)
222248
{
223249
struct blk_integrity *bi = dev_to_bi(dev);
224250

225-
if (bi->profile && bi->profile->name)
226-
return sysfs_emit(page, "%s\n", bi->profile->name);
227-
return sysfs_emit(page, "none\n");
251+
if (!bi->tuple_size)
252+
return sysfs_emit(page, "none\n");
253+
return sysfs_emit(page, "%s\n", blk_integrity_profile_name(bi));
228254
}
229255

230256
static ssize_t tag_size_show(struct device *dev, struct device_attribute *attr,
@@ -326,28 +352,6 @@ const struct attribute_group blk_integrity_attr_group = {
326352
.attrs = integrity_attrs,
327353
};
328354

329-
static blk_status_t blk_integrity_nop_fn(struct blk_integrity_iter *iter)
330-
{
331-
return BLK_STS_OK;
332-
}
333-
334-
static void blk_integrity_nop_prepare(struct request *rq)
335-
{
336-
}
337-
338-
static void blk_integrity_nop_complete(struct request *rq,
339-
unsigned int nr_bytes)
340-
{
341-
}
342-
343-
static const struct blk_integrity_profile nop_profile = {
344-
.name = "nop",
345-
.generate_fn = blk_integrity_nop_fn,
346-
.verify_fn = blk_integrity_nop_fn,
347-
.prepare_fn = blk_integrity_nop_prepare,
348-
.complete_fn = blk_integrity_nop_complete,
349-
};
350-
351355
/**
352356
* blk_integrity_register - Register a gendisk as being integrity-capable
353357
* @disk: struct gendisk pointer to make integrity-aware
@@ -363,11 +367,11 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
363367
{
364368
struct blk_integrity *bi = &disk->queue->integrity;
365369

370+
bi->csum_type = template->csum_type;
366371
bi->flags = BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE |
367372
template->flags;
368373
bi->interval_exp = template->interval_exp ? :
369374
ilog2(queue_logical_block_size(disk->queue));
370-
bi->profile = template->profile ? template->profile : &nop_profile;
371375
bi->tuple_size = template->tuple_size;
372376
bi->tag_size = template->tag_size;
373377
bi->pi_offset = template->pi_offset;
@@ -394,7 +398,7 @@ void blk_integrity_unregister(struct gendisk *disk)
394398
{
395399
struct blk_integrity *bi = &disk->queue->integrity;
396400

397-
if (!bi->profile)
401+
if (!bi->tuple_size)
398402
return;
399403

400404
/* ensure all bios are off the integrity workqueue */

block/blk-mq.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -804,10 +804,8 @@ static void blk_complete_request(struct request *req)
804804
if (!bio)
805805
return;
806806

807-
#ifdef CONFIG_BLK_DEV_INTEGRITY
808807
if (blk_integrity_rq(req) && req_op(req) == REQ_OP_READ)
809-
req->q->integrity.profile->complete_fn(req, total_bytes);
810-
#endif
808+
blk_integrity_complete(req, total_bytes);
811809

812810
/*
813811
* Upper layers may call blk_crypto_evict_key() anytime after the last
@@ -875,11 +873,9 @@ bool blk_update_request(struct request *req, blk_status_t error,
875873
if (!req->bio)
876874
return false;
877875

878-
#ifdef CONFIG_BLK_DEV_INTEGRITY
879876
if (blk_integrity_rq(req) && req_op(req) == REQ_OP_READ &&
880877
error == BLK_STS_OK)
881-
req->q->integrity.profile->complete_fn(req, nr_bytes);
882-
#endif
878+
blk_integrity_complete(req, nr_bytes);
883879

884880
/*
885881
* Upper layers may call blk_crypto_evict_key() anytime after the last
@@ -1264,10 +1260,9 @@ void blk_mq_start_request(struct request *rq)
12641260
WRITE_ONCE(rq->state, MQ_RQ_IN_FLIGHT);
12651261
rq->mq_hctx->tags->rqs[rq->tag] = rq;
12661262

1267-
#ifdef CONFIG_BLK_DEV_INTEGRITY
12681263
if (blk_integrity_rq(rq) && req_op(rq) == REQ_OP_WRITE)
1269-
q->integrity.profile->prepare_fn(rq);
1270-
#endif
1264+
blk_integrity_prepare(rq);
1265+
12711266
if (rq->bio && rq->bio->bi_opf & REQ_POLLED)
12721267
WRITE_ONCE(rq->bio->bi_cookie, rq->mq_hctx->queue_num);
12731268
}

block/blk.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <xen/xen.h>
1010
#include "blk-crypto-internal.h"
1111

12+
struct blk_integrity_iter;
1213
struct elevator_type;
1314

1415
/* Max future timer expiry for timeouts */
@@ -673,4 +674,11 @@ int bdev_open(struct block_device *bdev, blk_mode_t mode, void *holder,
673674
const struct blk_holder_ops *hops, struct file *bdev_file);
674675
int bdev_permission(dev_t dev, blk_mode_t mode, void *holder);
675676

677+
void blk_integrity_generate(struct blk_integrity_iter *iter,
678+
struct blk_integrity *bi);
679+
blk_status_t blk_integrity_verify(struct blk_integrity_iter *iter,
680+
struct blk_integrity *bi);
681+
void blk_integrity_prepare(struct request *rq);
682+
void blk_integrity_complete(struct request *rq, unsigned int nr_bytes);
683+
676684
#endif /* BLK_INTERNAL_H */

0 commit comments

Comments
 (0)