* move integrity settings to queue_limits
@ 2024-06-05 6:28 Christoph Hellwig
2024-06-05 6:28 ` [PATCH 01/12] dm-integrity: use the nop integrity profile Christoph Hellwig
` (11 more replies)
0 siblings, 12 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
Hi Jens, hi Martin,
this series converts the blk-integrity settings to sit in the queue
limits and be updated through the atomic queue limits API.
I've mostly tested this with nvme, scsi is only covered by simple
scsi_debug based tests.
For MD I found an pre-existing error handling bug when combining PI
capable devices with not PI capable devices. The fix was posted here
(and is included in the git branch below):
https://lore.kernel.org/linux-raid/20240604172607.3185916-1-hch@lst.de/
For dm-integrity my testing showed that even the baseline fails to create
the luks-based dm-crypto with dm-integrity backing for the authentication
data. As the failure is non-fatal I've not addressed it here.
Note that the support for native metadata in dm-crypt by Mikulas will
need a rebase on top of this, but as it already requires another
block layer patch and the changes in this series will simplify it a bit
I hope that is ok.
The series is based on top of my previously sent "convert the SCSI ULDs
to the atomic queue limits API v2" API.
A git tree is available here:
git://git.infradead.org/users/hch/block.git block-integrity-limits
Gitweb:
http://git.infradead.org/?p=users/hch/block.git;a=shortlog;h=refs/heads/block-integrity-limits
Diffstat:
Documentation/block/data-integrity.rst | 49 ------
block/Kconfig | 8 -
block/Makefile | 3
block/bio-integrity.c | 36 ++---
block/blk-integrity.c | 232 +++++++++-----------------------
block/blk-mq.c | 13 -
block/blk-settings.c | 118 +++++++++++++++-
block/blk.h | 8 +
block/t10-pi.c | 236 ++++++++++-----------------------
drivers/md/dm-core.h | 1
drivers/md/dm-crypt.c | 4
drivers/md/dm-integrity.c | 47 +-----
drivers/md/dm-table.c | 161 +++-------------------
drivers/md/md.c | 72 ++--------
drivers/md/md.h | 5
drivers/md/raid0.c | 7
drivers/md/raid1.c | 10 -
drivers/md/raid10.c | 10 -
drivers/md/raid5.c | 2
drivers/nvdimm/btt.c | 13 -
drivers/nvme/host/Kconfig | 1
drivers/nvme/host/core.c | 71 +++++----
drivers/nvme/host/multipath.c | 3
drivers/nvme/target/Kconfig | 1
drivers/nvme/target/io-cmd-bdev.c | 16 +-
drivers/scsi/Kconfig | 1
drivers/scsi/sd.c | 28 +--
drivers/scsi/sd.h | 12 -
drivers/scsi/sd_dif.c | 48 ++----
drivers/target/target_core_iblock.c | 49 +++---
include/linux/bio.h | 7
include/linux/blk-integrity.h | 74 ++++------
include/linux/blkdev.h | 19 +-
include/linux/t10-pi.h | 20 --
34 files changed, 524 insertions(+), 861 deletions(-)
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 01/12] dm-integrity: use the nop integrity profile
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-05 14:52 ` Milan Broz
2024-06-06 0:12 ` Chaitanya Kulkarni
2024-06-05 6:28 ` [PATCH 02/12] block: remove the unused BIP_{CTRL,DISK}_NOCHECK flags Christoph Hellwig
` (10 subsequent siblings)
11 siblings, 2 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
Use the block layer built-in nop profile instead of reinventing it.
Tested by:
$ dd if=/dev/urandom of=key.bin bs=512 count=1
$ cryptsetup luksFormat -q --type luks2 --integrity hmac-sha256 \
--integrity-no-wipe /dev/nvme0n1 key.bin
$ cryptsetup luksOpen /dev/nvme0n1 luks-integrity --key-file key.bin
and then doing mkfs.xfs and simple I/O on the mount file system.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/md/dm-crypt.c | 4 ++--
drivers/md/dm-integrity.c | 20 --------------------
2 files changed, 2 insertions(+), 22 deletions(-)
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 1b7a97cc377943..1dfc462f29cd6f 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1176,8 +1176,8 @@ static int crypt_integrity_ctr(struct crypt_config *cc, struct dm_target *ti)
struct blk_integrity *bi = blk_get_integrity(cc->dev->bdev->bd_disk);
struct mapped_device *md = dm_table_get_md(ti->table);
- /* From now we require underlying device with our integrity profile */
- if (!bi || strcasecmp(bi->profile->name, "DM-DIF-EXT-TAG")) {
+ /* We require an underlying device with non-PI metadata */
+ if (!bi || strcmp(bi->profile->name, "nop")) {
ti->error = "Integrity profile not supported.";
return -EINVAL;
}
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index 417fddebe367a2..c1cc27541673c7 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -350,25 +350,6 @@ static struct kmem_cache *journal_io_cache;
#define DEBUG_bytes(bytes, len, msg, ...) do { } while (0)
#endif
-static void dm_integrity_prepare(struct request *rq)
-{
-}
-
-static void dm_integrity_complete(struct request *rq, unsigned int nr_bytes)
-{
-}
-
-/*
- * DM Integrity profile, protection is performed layer above (dm-crypt)
- */
-static const struct blk_integrity_profile dm_integrity_profile = {
- .name = "DM-DIF-EXT-TAG",
- .generate_fn = NULL,
- .verify_fn = NULL,
- .prepare_fn = dm_integrity_prepare,
- .complete_fn = dm_integrity_complete,
-};
-
static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map);
static void integrity_bio_wait(struct work_struct *w);
static void dm_integrity_dtr(struct dm_target *ti);
@@ -3656,7 +3637,6 @@ static void dm_integrity_set(struct dm_target *ti, struct dm_integrity_c *ic)
struct blk_integrity bi;
memset(&bi, 0, sizeof(bi));
- bi.profile = &dm_integrity_profile;
bi.tuple_size = ic->tag_size;
bi.tag_size = bi.tuple_size;
bi.interval_exp = ic->sb->log2_sectors_per_block + SECTOR_SHIFT;
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 02/12] block: remove the unused BIP_{CTRL,DISK}_NOCHECK flags
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
2024-06-05 6:28 ` [PATCH 01/12] dm-integrity: use the nop integrity profile Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-05 16:16 ` Bart Van Assche
` (2 more replies)
2024-06-05 6:28 ` [PATCH 03/12] block: remove the BIP_IP_CHECKSUM flag Christoph Hellwig
` (9 subsequent siblings)
11 siblings, 3 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
Both flags are only checked, but never set.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/scsi/sd.c | 14 +++-----------
include/linux/bio.h | 2 --
2 files changed, 3 insertions(+), 13 deletions(-)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index d957e29b17a98a..b477383ccc3b2a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -806,25 +806,17 @@ static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
if (dix) { /* DIX Type 0, 1, 2, 3 */
if (bio_integrity_flagged(bio, BIP_IP_CHECKSUM))
scmd->prot_flags |= SCSI_PROT_IP_CHECKSUM;
-
- if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false)
- scmd->prot_flags |= SCSI_PROT_GUARD_CHECK;
+ scmd->prot_flags |= SCSI_PROT_GUARD_CHECK;
}
if (dif != T10_PI_TYPE3_PROTECTION) { /* DIX/DIF Type 0, 1, 2 */
scmd->prot_flags |= SCSI_PROT_REF_INCREMENT;
-
- if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false)
- scmd->prot_flags |= SCSI_PROT_REF_CHECK;
+ scmd->prot_flags |= SCSI_PROT_REF_CHECK;
}
if (dif) { /* DIX/DIF Type 1, 2, 3 */
scmd->prot_flags |= SCSI_PROT_TRANSFER_PI;
-
- if (bio_integrity_flagged(bio, BIP_DISK_NOCHECK))
- protect = 3 << 5; /* Disable target PI checking */
- else
- protect = 1 << 5; /* Enable target PI checking */
+ protect = 1 << 5; /* Enable target PI checking */
}
scsi_set_prot_op(scmd, prot_op);
diff --git a/include/linux/bio.h b/include/linux/bio.h
index d5379548d684e1..ec5dcf8635ac66 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -324,8 +324,6 @@ static inline void bio_next_folio(struct folio_iter *fi, struct bio *bio)
enum bip_flags {
BIP_BLOCK_INTEGRITY = 1 << 0, /* block layer owns integrity data */
BIP_MAPPED_INTEGRITY = 1 << 1, /* ref tag has been remapped */
- BIP_CTRL_NOCHECK = 1 << 2, /* disable HBA integrity checking */
- BIP_DISK_NOCHECK = 1 << 3, /* disable disk integrity checking */
BIP_IP_CHECKSUM = 1 << 4, /* IP checksum */
BIP_INTEGRITY_USER = 1 << 5, /* Integrity payload is user address */
BIP_COPY_USER = 1 << 6, /* Kernel bounce buffer in use */
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 03/12] block: remove the BIP_IP_CHECKSUM flag
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
2024-06-05 6:28 ` [PATCH 01/12] dm-integrity: use the nop integrity profile Christoph Hellwig
2024-06-05 6:28 ` [PATCH 02/12] block: remove the unused BIP_{CTRL,DISK}_NOCHECK flags Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-05 16:21 ` Bart Van Assche
` (2 more replies)
2024-06-05 6:28 ` [PATCH 04/12] block: remove the blk_integrity_profile structure Christoph Hellwig
` (8 subsequent siblings)
11 siblings, 3 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
Remove the BIP_IP_CHECKSUM as sd can just look at the per-disk
checksum type instead.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio-integrity.c | 3 ---
drivers/scsi/sd.c | 6 +++---
include/linux/bio.h | 5 ++---
3 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index 2e3e8e04961eae..43f112ec8b59fe 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -479,9 +479,6 @@ bool bio_integrity_prep(struct bio *bio)
bip->bip_flags |= BIP_BLOCK_INTEGRITY;
bip_set_seed(bip, bio->bi_iter.bi_sector);
- if (bi->flags & BLK_INTEGRITY_IP_CHECKSUM)
- bip->bip_flags |= BIP_IP_CHECKSUM;
-
/* Map it */
offset = offset_in_page(buf);
for (i = 0; i < nr_pages && len > 0; i++) {
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b477383ccc3b2a..e21b7df5c31b0d 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -43,7 +43,7 @@
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/init.h>
-#include <linux/blkdev.h>
+#include <linux/blk-integrity.h>
#include <linux/blkpg.h>
#include <linux/blk-pm.h>
#include <linux/delay.h>
@@ -799,12 +799,12 @@ static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
unsigned int dix, unsigned int dif)
{
struct request *rq = scsi_cmd_to_rq(scmd);
- struct bio *bio = rq->bio;
+ struct blk_integrity *bi = &rq->q->integrity;
unsigned int prot_op = sd_prot_op(rq_data_dir(rq), dix, dif);
unsigned int protect = 0;
if (dix) { /* DIX Type 0, 1, 2, 3 */
- if (bio_integrity_flagged(bio, BIP_IP_CHECKSUM))
+ if (bi->flags & BLK_INTEGRITY_IP_CHECKSUM)
scmd->prot_flags |= SCSI_PROT_IP_CHECKSUM;
scmd->prot_flags |= SCSI_PROT_GUARD_CHECK;
}
diff --git a/include/linux/bio.h b/include/linux/bio.h
index ec5dcf8635ac66..3295dd6021659b 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -324,9 +324,8 @@ static inline void bio_next_folio(struct folio_iter *fi, struct bio *bio)
enum bip_flags {
BIP_BLOCK_INTEGRITY = 1 << 0, /* block layer owns integrity data */
BIP_MAPPED_INTEGRITY = 1 << 1, /* ref tag has been remapped */
- BIP_IP_CHECKSUM = 1 << 4, /* IP checksum */
- BIP_INTEGRITY_USER = 1 << 5, /* Integrity payload is user address */
- BIP_COPY_USER = 1 << 6, /* Kernel bounce buffer in use */
+ BIP_INTEGRITY_USER = 1 << 2, /* Integrity payload is user address */
+ BIP_COPY_USER = 1 << 3, /* Kernel bounce buffer in use */
};
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 04/12] block: remove the blk_integrity_profile structure
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
` (2 preceding siblings ...)
2024-06-05 6:28 ` [PATCH 03/12] block: remove the BIP_IP_CHECKSUM flag Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-05 14:35 ` Kanchan Joshi
2024-06-05 16:31 ` Bart Van Assche
2024-06-05 6:28 ` [PATCH 05/12] block: remove the blk_flush_integrity call in blk_integrity_unregister Christoph Hellwig
` (7 subsequent siblings)
11 siblings, 2 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
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 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 <hch@lst.de>
---
block/Kconfig | 8 +-
block/Makefile | 3 +-
block/bio-integrity.c | 33 ++--
block/blk-integrity.c | 64 ++++----
block/blk-mq.c | 13 +-
block/blk.h | 8 +
block/t10-pi.c | 228 +++++++++-------------------
drivers/md/dm-crypt.c | 2 +-
drivers/nvme/host/Kconfig | 1 -
drivers/nvme/host/core.c | 17 +--
drivers/nvme/target/Kconfig | 1 -
drivers/nvme/target/io-cmd-bdev.c | 16 +-
drivers/scsi/Kconfig | 1 -
drivers/scsi/sd.c | 2 +-
drivers/scsi/sd_dif.c | 19 +--
drivers/target/target_core_iblock.c | 49 +++---
include/linux/blk-integrity.h | 42 +++--
include/linux/blkdev.h | 2 +-
include/linux/t10-pi.h | 8 -
19 files changed, 204 insertions(+), 313 deletions(-)
diff --git a/block/Kconfig b/block/Kconfig
index dc12af58dbaeca..5b623b876d3b4a 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -62,6 +62,8 @@ config BLK_DEV_BSGLIB
config BLK_DEV_INTEGRITY
bool "Block layer data integrity support"
+ select CRC_T10DIF
+ select CRC64_ROCKSOFT
help
Some storage devices allow extra information to be
stored/retrieved to help protect the data. The block layer
@@ -72,12 +74,6 @@ config BLK_DEV_INTEGRITY
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
- select CRC64_ROCKSOFT
-
config BLK_DEV_WRITE_MOUNTED
bool "Allow writing to mounted block devices"
default y
diff --git a/block/Makefile b/block/Makefile
index 168150b9c51025..ddfd21c1a9ffc9 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -26,8 +26,7 @@ obj-$(CONFIG_MQ_IOSCHED_KYBER) += kyber-iosched.o
bfq-y := bfq-iosched.o bfq-wf2q.o bfq-cgroup.o
obj-$(CONFIG_IOSCHED_BFQ) += bfq.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_DEV_ZONED) += blk-zoned.o
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index 43f112ec8b59fe..5966a65edcd10e 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -378,10 +378,9 @@ EXPORT_SYMBOL_GPL(bio_integrity_map_user);
* 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 bvec_iter *proc_iter)
{
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
struct blk_integrity_iter iter;
@@ -392,17 +391,18 @@ static blk_status_t bio_integrity_process(struct bio *bio,
iter.disk_name = bio->bi_bdev->bd_disk->disk_name;
iter.interval = 1 << bi->interval_exp;
- iter.tuple_size = bi->tuple_size;
iter.seed = proc_iter->bi_sector;
iter.prot_buf = bvec_virt(bip->bip_vec);
- iter.pi_offset = bi->pi_offset;
__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);
+ if (bio_data_dir(bio) == WRITE)
+ blk_integrity_generate(&iter, bi);
+ else
+ ret = blk_integrity_verify(&iter, bi);
kunmap_local(kaddr);
if (ret)
@@ -446,13 +446,14 @@ bool bio_integrity_prep(struct bio *bio)
if (bio_integrity(bio))
return true;
+ if (!bi->csum_type)
+ return true;
+
if (bio_data_dir(bio) == READ) {
- if (!bi->profile->verify_fn ||
- !(bi->flags & BLK_INTEGRITY_VERIFY))
+ if (!(bi->flags & BLK_INTEGRITY_VERIFY))
return true;
} else {
- if (!bi->profile->generate_fn ||
- !(bi->flags & BLK_INTEGRITY_GENERATE))
+ if (!(bi->flags & BLK_INTEGRITY_GENERATE))
return true;
}
@@ -499,12 +500,10 @@ 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);
- } else {
+ if (bio_data_dir(bio) == WRITE)
+ bio_integrity_process(bio, &bio->bi_iter);
+ else
bip->bio_iter = bio->bi_iter;
- }
return true;
err_end_io:
@@ -527,15 +526,13 @@ 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);
+ bio->bi_status = bio_integrity_process(bio, &bip->bio_iter);
bio_integrity_free(bio);
bio_endio(bio);
}
@@ -557,7 +554,7 @@ bool __bio_integrity_endio(struct bio *bio)
struct bio_integrity_payload *bip = bio_integrity(bio);
if (bio_op(bio) == REQ_OP_READ && !bio->bi_status &&
- (bip->bip_flags & BIP_BLOCK_INTEGRITY) && bi->profile->verify_fn) {
+ (bip->bip_flags & BIP_BLOCK_INTEGRITY) && bi->csum_type) {
INIT_WORK(&bip->bip_work, bio_integrity_verify_fn);
queue_work(kintegrityd_wq, &bip->bip_work);
return false;
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index ccbeb6dfa87a4d..4767603b443990 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -123,10 +123,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->tuple_size && !b2->tuple_size)
return 0;
- if (!b1->profile || !b2->profile)
+ if (!b1->tuple_size || !b2->tuple_size)
return -1;
if (b1->interval_exp != b2->interval_exp) {
@@ -150,10 +150,13 @@ int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2)
return -1;
}
- if (b1->profile != b2->profile) {
+ if (b1->csum_type != b2->csum_type ||
+ (b1->flags & BLK_INTEGRITY_REF_TAG) !=
+ (b2->flags & BLK_INTEGRITY_REF_TAG)) {
pr_err("%s: %s/%s type %s != %s\n", __func__,
gd1->disk_name, gd2->disk_name,
- b1->profile->name, b2->profile->name);
+ blk_integrity_profile_name(b1),
+ blk_integrity_profile_name(b2));
return -1;
}
@@ -217,14 +220,35 @@ static inline struct blk_integrity *dev_to_bi(struct device *dev)
return &dev_to_disk(dev)->queue->integrity;
}
+const char *blk_integrity_profile_name(struct blk_integrity *bi)
+{
+ switch (bi->csum_type) {
+ case BLK_INTEGRITY_CSUM_IP:
+ if (bi->flags & BLK_INTEGRITY_REF_TAG)
+ return "T10-DIF-TYPE1-IP";
+ return "T10-DIF-TYPE3-IP";
+ case BLK_INTEGRITY_CSUM_CRC:
+ if (bi->flags & BLK_INTEGRITY_REF_TAG)
+ return "T10-DIF-TYPE1-CRC";
+ return "T10-DIF-TYPE3-CRC";
+ case BLK_INTEGRITY_CSUM_CRC64:
+ if (bi->flags & BLK_INTEGRITY_REF_TAG)
+ return "EXT-DIF-TYPE1-CRC64";
+ return "EXT-DIF-TYPE3-CRC64";
+ default:
+ return "nop";
+ }
+}
+EXPORT_SYMBOL_GPL(blk_integrity_profile_name);
+
static ssize_t format_show(struct device *dev, struct device_attribute *attr,
char *page)
{
struct blk_integrity *bi = dev_to_bi(dev);
- if (bi->profile && bi->profile->name)
- return sysfs_emit(page, "%s\n", bi->profile->name);
- return sysfs_emit(page, "none\n");
+ if (!bi->tuple_size)
+ return sysfs_emit(page, "none\n");
+ return sysfs_emit(page, "%s\n", blk_integrity_profile_name(bi));
}
static ssize_t tag_size_show(struct device *dev, struct device_attribute *attr,
@@ -326,28 +350,6 @@ const struct attribute_group blk_integrity_attr_group = {
.attrs = integrity_attrs,
};
-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_integrity_register - Register a gendisk as being integrity-capable
* @disk: struct gendisk pointer to make integrity-aware
@@ -363,11 +365,11 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
{
struct blk_integrity *bi = &disk->queue->integrity;
+ bi->csum_type = template->csum_type;
bi->flags = BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE |
template->flags;
bi->interval_exp = template->interval_exp ? :
ilog2(queue_logical_block_size(disk->queue));
- bi->profile = template->profile ? template->profile : &nop_profile;
bi->tuple_size = template->tuple_size;
bi->tag_size = template->tag_size;
bi->pi_offset = template->pi_offset;
@@ -394,7 +396,7 @@ void blk_integrity_unregister(struct gendisk *disk)
{
struct blk_integrity *bi = &disk->queue->integrity;
- if (!bi->profile)
+ if (!bi->tuple_size)
return;
/* ensure all bios are off the integrity workqueue */
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 3b4df8e5ac9e5f..0d4cd39c3d25da 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -804,10 +804,8 @@ static void blk_complete_request(struct request *req)
if (!bio)
return;
-#ifdef CONFIG_BLK_DEV_INTEGRITY
if (blk_integrity_rq(req) && req_op(req) == REQ_OP_READ)
- req->q->integrity.profile->complete_fn(req, total_bytes);
-#endif
+ blk_integrity_complete(req, total_bytes);
/*
* 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,
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
+ blk_integrity_complete(req, nr_bytes);
/*
* Upper layers may call blk_crypto_evict_key() anytime after the last
@@ -1264,10 +1260,9 @@ void blk_mq_start_request(struct request *rq)
WRITE_ONCE(rq->state, MQ_RQ_IN_FLIGHT);
rq->mq_hctx->tags->rqs[rq->tag] = rq;
-#ifdef CONFIG_BLK_DEV_INTEGRITY
if (blk_integrity_rq(rq) && req_op(rq) == REQ_OP_WRITE)
- q->integrity.profile->prepare_fn(rq);
-#endif
+ blk_integrity_prepare(rq);
+
if (rq->bio && rq->bio->bi_opf & REQ_POLLED)
WRITE_ONCE(rq->bio->bi_cookie, rq->mq_hctx->queue_num);
}
diff --git a/block/blk.h b/block/blk.h
index 189bc25beb502a..79e8d5d4fe0caf 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -9,6 +9,7 @@
#include <xen/xen.h>
#include "blk-crypto-internal.h"
+struct blk_integrity_iter;
struct elevator_type;
/* Max future timer expiry for timeouts */
@@ -673,4 +674,11 @@ int bdev_open(struct block_device *bdev, blk_mode_t mode, void *holder,
const struct blk_holder_ops *hops, struct file *bdev_file);
int bdev_permission(dev_t dev, blk_mode_t mode, void *holder);
+void blk_integrity_generate(struct blk_integrity_iter *iter,
+ struct blk_integrity *bi);
+blk_status_t blk_integrity_verify(struct blk_integrity_iter *iter,
+ struct blk_integrity *bi);
+void blk_integrity_prepare(struct request *rq);
+void blk_integrity_complete(struct request *rq, unsigned int nr_bytes);
+
#endif /* BLK_INTERNAL_H */
diff --git a/block/t10-pi.c b/block/t10-pi.c
index f4cc91156da1f2..2d8298a4cd3307 100644
--- a/block/t10-pi.c
+++ b/block/t10-pi.c
@@ -11,17 +11,16 @@
#include <linux/module.h>
#include <net/checksum.h>
#include <asm/unaligned.h>
+#include "blk.h"
-typedef __be16 (csum_fn) (__be16, void *, unsigned int);
+#define T10_PI_F_IP_CSUM (1 << 1)
-static __be16 t10_pi_crc_fn(__be16 crc, void *data, unsigned int len)
+static __be16 t10_pi_csum(__be16 csum, void *data, unsigned int len,
+ unsigned char csum_type)
{
- return cpu_to_be16(crc_t10dif_update(be16_to_cpu(crc), data, len));
-}
-
-static __be16 t10_pi_ip_fn(__be16 csum, void *data, unsigned int len)
-{
- return (__force __be16)ip_compute_csum(data, len);
+ if (csum_type == BLK_INTEGRITY_CSUM_IP)
+ return (__force __be16)ip_compute_csum(data, len);
+ return cpu_to_be16(crc_t10dif_update(be16_to_cpu(csum), data, len));
}
/*
@@ -29,48 +28,44 @@ static __be16 t10_pi_ip_fn(__be16 csum, 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(struct blk_integrity_iter *iter,
+ struct blk_integrity *bi)
{
- u8 offset = iter->pi_offset;
+ u8 offset = bi->pi_offset;
unsigned int i;
for (i = 0 ; i < iter->data_size ; i += iter->interval) {
struct t10_pi_tuple *pi = iter->prot_buf + offset;
- pi->guard_tag = fn(0, iter->data_buf, iter->interval);
+ pi->guard_tag = t10_pi_csum(0, iter->data_buf, iter->interval,
+ bi->csum_type);
if (offset)
- pi->guard_tag = fn(pi->guard_tag, iter->prot_buf,
- offset);
+ pi->guard_tag = t10_pi_csum(pi->guard_tag,
+ iter->prot_buf, offset, bi->csum_type);
pi->app_tag = 0;
- if (type == T10_PI_TYPE1_PROTECTION)
+ if (bi->flags & BLK_INTEGRITY_REF_TAG)
pi->ref_tag = cpu_to_be32(lower_32_bits(iter->seed));
else
pi->ref_tag = 0;
iter->data_buf += iter->interval;
- iter->prot_buf += iter->tuple_size;
+ iter->prot_buf += bi->tuple_size;
iter->seed++;
}
-
- return BLK_STS_OK;
}
static blk_status_t t10_pi_verify(struct blk_integrity_iter *iter,
- csum_fn *fn, enum t10_dif_type type)
+ struct blk_integrity *bi)
{
- u8 offset = iter->pi_offset;
+ u8 offset = bi->pi_offset;
unsigned int i;
- BUG_ON(type == T10_PI_TYPE0_PROTECTION);
-
for (i = 0 ; i < iter->data_size ; i += iter->interval) {
struct t10_pi_tuple *pi = iter->prot_buf + offset;
__be16 csum;
- if (type == T10_PI_TYPE1_PROTECTION ||
- type == T10_PI_TYPE2_PROTECTION) {
+ if (bi->flags & BLK_INTEGRITY_REF_TAG) {
if (pi->app_tag == T10_PI_APP_ESCAPE)
goto next;
@@ -82,15 +77,17 @@ static blk_status_t t10_pi_verify(struct blk_integrity_iter *iter,
iter->seed, be32_to_cpu(pi->ref_tag));
return BLK_STS_PROTECTION;
}
- } else if (type == T10_PI_TYPE3_PROTECTION) {
+ } else {
if (pi->app_tag == T10_PI_APP_ESCAPE &&
pi->ref_tag == T10_PI_REF_ESCAPE)
goto next;
}
- csum = fn(0, iter->data_buf, iter->interval);
+ csum = t10_pi_csum(0, iter->data_buf, iter->interval,
+ bi->csum_type);
if (offset)
- csum = fn(csum, iter->prot_buf, offset);
+ csum = t10_pi_csum(csum, iter->prot_buf, offset,
+ bi->csum_type);
if (pi->guard_tag != csum) {
pr_err("%s: guard tag error at sector %llu " \
@@ -102,33 +99,13 @@ static blk_status_t t10_pi_verify(struct blk_integrity_iter *iter,
next:
iter->data_buf += iter->interval;
- iter->prot_buf += iter->tuple_size;
+ iter->prot_buf += bi->tuple_size;
iter->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);
-}
-
-static blk_status_t t10_pi_type1_generate_ip(struct blk_integrity_iter *iter)
-{
- 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);
-}
-
-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);
-}
-
/**
* t10_pi_type1_prepare - prepare PI prior submitting request to device
* @rq: request with PI that should be prepared
@@ -225,81 +202,15 @@ 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);
-
-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,
-};
-EXPORT_SYMBOL(t10_pi_type1_ip);
-
-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);
-
-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,
-};
-EXPORT_SYMBOL(t10_pi_type3_ip);
-
static __be64 ext_pi_crc64(u64 crc, void *data, unsigned int len)
{
return cpu_to_be64(crc64_rocksoft_update(crc, data, len));
}
-static blk_status_t ext_pi_crc64_generate(struct blk_integrity_iter *iter,
- enum t10_dif_type type)
+static void ext_pi_crc64_generate(struct blk_integrity_iter *iter,
+ struct blk_integrity *bi)
{
- u8 offset = iter->pi_offset;
+ u8 offset = bi->pi_offset;
unsigned int i;
for (i = 0 ; i < iter->data_size ; i += iter->interval) {
@@ -311,17 +222,15 @@ static blk_status_t ext_pi_crc64_generate(struct blk_integrity_iter *iter,
iter->prot_buf, offset);
pi->app_tag = 0;
- if (type == T10_PI_TYPE1_PROTECTION)
+ if (bi->flags & BLK_INTEGRITY_REF_TAG)
put_unaligned_be48(iter->seed, pi->ref_tag);
else
put_unaligned_be48(0ULL, pi->ref_tag);
iter->data_buf += iter->interval;
- iter->prot_buf += iter->tuple_size;
+ iter->prot_buf += bi->tuple_size;
iter->seed++;
}
-
- return BLK_STS_OK;
}
static bool ext_pi_ref_escape(u8 *ref_tag)
@@ -332,9 +241,9 @@ static bool ext_pi_ref_escape(u8 *ref_tag)
}
static blk_status_t ext_pi_crc64_verify(struct blk_integrity_iter *iter,
- enum t10_dif_type type)
+ struct blk_integrity *bi)
{
- u8 offset = iter->pi_offset;
+ u8 offset = bi->pi_offset;
unsigned int i;
for (i = 0; i < iter->data_size; i += iter->interval) {
@@ -342,7 +251,7 @@ static blk_status_t ext_pi_crc64_verify(struct blk_integrity_iter *iter,
u64 ref, seed;
__be64 csum;
- if (type == T10_PI_TYPE1_PROTECTION) {
+ if (bi->flags & BLK_INTEGRITY_REF_TAG) {
if (pi->app_tag == T10_PI_APP_ESCAPE)
goto next;
@@ -353,7 +262,7 @@ static blk_status_t ext_pi_crc64_verify(struct blk_integrity_iter *iter,
iter->disk_name, seed, ref);
return BLK_STS_PROTECTION;
}
- } else if (type == T10_PI_TYPE3_PROTECTION) {
+ } else {
if (pi->app_tag == T10_PI_APP_ESCAPE &&
ext_pi_ref_escape(pi->ref_tag))
goto next;
@@ -374,23 +283,13 @@ static blk_status_t ext_pi_crc64_verify(struct blk_integrity_iter *iter,
next:
iter->data_buf += iter->interval;
- iter->prot_buf += iter->tuple_size;
+ iter->prot_buf += bi->tuple_size;
iter->seed++;
}
return BLK_STS_OK;
}
-static blk_status_t ext_pi_type1_verify_crc64(struct blk_integrity_iter *iter)
-{
- return ext_pi_crc64_verify(iter, T10_PI_TYPE1_PROTECTION);
-}
-
-static blk_status_t ext_pi_type1_generate_crc64(struct blk_integrity_iter *iter)
-{
- return ext_pi_crc64_generate(iter, T10_PI_TYPE1_PROTECTION);
-}
-
static void ext_pi_type1_prepare(struct request *rq)
{
struct blk_integrity *bi = &rq->q->integrity;
@@ -467,33 +366,48 @@ static void ext_pi_type1_complete(struct request *rq, unsigned int nr_bytes)
}
}
-static blk_status_t ext_pi_type3_verify_crc64(struct blk_integrity_iter *iter)
+void blk_integrity_generate(struct blk_integrity_iter *iter,
+ struct blk_integrity *bi)
{
- return ext_pi_crc64_verify(iter, T10_PI_TYPE3_PROTECTION);
+ if (bi->csum_type == BLK_INTEGRITY_CSUM_CRC64)
+ ext_pi_crc64_generate(iter, bi);
+ else
+ t10_pi_generate(iter, bi);
}
-static blk_status_t ext_pi_type3_generate_crc64(struct blk_integrity_iter *iter)
+blk_status_t blk_integrity_verify(struct blk_integrity_iter *iter,
+ struct blk_integrity *bi)
{
- return ext_pi_crc64_generate(iter, T10_PI_TYPE3_PROTECTION);
+ if (bi->csum_type == BLK_INTEGRITY_CSUM_CRC64)
+ return ext_pi_crc64_verify(iter, bi);
+ return t10_pi_verify(iter, bi);
}
-const struct blk_integrity_profile ext_pi_type1_crc64 = {
- .name = "EXT-DIF-TYPE1-CRC64",
- .generate_fn = ext_pi_type1_generate_crc64,
- .verify_fn = ext_pi_type1_verify_crc64,
- .prepare_fn = ext_pi_type1_prepare,
- .complete_fn = ext_pi_type1_complete,
-};
-EXPORT_SYMBOL_GPL(ext_pi_type1_crc64);
-
-const struct blk_integrity_profile ext_pi_type3_crc64 = {
- .name = "EXT-DIF-TYPE3-CRC64",
- .generate_fn = ext_pi_type3_generate_crc64,
- .verify_fn = ext_pi_type3_verify_crc64,
- .prepare_fn = t10_pi_type3_prepare,
- .complete_fn = t10_pi_type3_complete,
-};
-EXPORT_SYMBOL_GPL(ext_pi_type3_crc64);
+void blk_integrity_prepare(struct request *rq)
+{
+ struct blk_integrity *bi = &rq->q->integrity;
+
+ if (!(bi->flags & BLK_INTEGRITY_REF_TAG))
+ return;
+
+ if (bi->csum_type == BLK_INTEGRITY_CSUM_CRC64)
+ ext_pi_type1_prepare(rq);
+ else
+ t10_pi_type1_prepare(rq);
+}
+
+void blk_integrity_complete(struct request *rq, unsigned int nr_bytes)
+{
+ struct blk_integrity *bi = &rq->q->integrity;
+
+ if (!(bi->flags & BLK_INTEGRITY_REF_TAG))
+ return;
+
+ if (bi->csum_type == BLK_INTEGRITY_CSUM_CRC64)
+ ext_pi_type1_complete(rq, nr_bytes);
+ else
+ t10_pi_type1_complete(rq, nr_bytes);
+}
MODULE_DESCRIPTION("T10 Protection Information module");
MODULE_LICENSE("GPL");
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 1dfc462f29cd6f..6c013ceb0e5f1d 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1177,7 +1177,7 @@ static int crypt_integrity_ctr(struct crypt_config *cc, struct dm_target *ti)
struct mapped_device *md = dm_table_get_md(ti->table);
/* We require an underlying device with non-PI metadata */
- if (!bi || strcmp(bi->profile->name, "nop")) {
+ if (!bi || bi->csum_type != BLK_INTEGRITY_CSUM_NONE) {
ti->error = "Integrity profile not supported.";
return -EINVAL;
}
diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig
index b309c8be720f47..a3caef75aa0a83 100644
--- a/drivers/nvme/host/Kconfig
+++ b/drivers/nvme/host/Kconfig
@@ -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"
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index f5d150c62955d8..14bac248cde4ca 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1744,17 +1744,16 @@ static bool nvme_init_integrity(struct gendisk *disk, struct nvme_ns_head *head)
case NVME_NS_DPS_PI_TYPE3:
switch (head->guard_type) {
case NVME_NVM_NS_16B_GUARD:
- integrity.profile = &t10_pi_type3_crc;
+ integrity.csum_type = BLK_INTEGRITY_CSUM_CRC;
integrity.tag_size = sizeof(u16) + sizeof(u32);
integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
break;
case NVME_NVM_NS_64B_GUARD:
- integrity.profile = &ext_pi_type3_crc64;
+ integrity.csum_type = BLK_INTEGRITY_CSUM_CRC64;
integrity.tag_size = sizeof(u16) + 6;
integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
break;
default:
- integrity.profile = NULL;
break;
}
break;
@@ -1762,22 +1761,22 @@ static bool nvme_init_integrity(struct gendisk *disk, struct nvme_ns_head *head)
case NVME_NS_DPS_PI_TYPE2:
switch (head->guard_type) {
case NVME_NVM_NS_16B_GUARD:
- integrity.profile = &t10_pi_type1_crc;
+ integrity.csum_type = BLK_INTEGRITY_CSUM_CRC;
integrity.tag_size = sizeof(u16);
- integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
+ integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE |
+ BLK_INTEGRITY_REF_TAG;
break;
case NVME_NVM_NS_64B_GUARD:
- integrity.profile = &ext_pi_type1_crc64;
+ integrity.csum_type = BLK_INTEGRITY_CSUM_CRC64;
integrity.tag_size = sizeof(u16);
- integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
+ integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE |
+ BLK_INTEGRITY_REF_TAG;
break;
default:
- integrity.profile = NULL;
break;
}
break;
default:
- integrity.profile = NULL;
break;
}
diff --git a/drivers/nvme/target/Kconfig b/drivers/nvme/target/Kconfig
index 872dd1a0acd804..c42aec41cc7b1f 100644
--- a/drivers/nvme/target/Kconfig
+++ b/drivers/nvme/target/Kconfig
@@ -6,7 +6,6 @@ config NVME_TARGET
depends on CONFIGFS_FS
select NVME_KEYRING if NVME_TARGET_TCP_TLS
select KEYS if NVME_TARGET_TCP_TLS
- select BLK_DEV_INTEGRITY_T10 if BLK_DEV_INTEGRITY
select SGL_ALLOC
help
This enabled target side support for the NVMe protocol, that is
diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
index 6426aac2634aeb..b628bc5ee99847 100644
--- a/drivers/nvme/target/io-cmd-bdev.c
+++ b/drivers/nvme/target/io-cmd-bdev.c
@@ -61,15 +61,17 @@ static void nvmet_bdev_ns_enable_integrity(struct nvmet_ns *ns)
{
struct blk_integrity *bi = bdev_get_integrity(ns->bdev);
- if (bi) {
+ if (!bi)
+ return;
+
+ if (bi->csum_type == BLK_INTEGRITY_CSUM_CRC) {
ns->metadata_size = bi->tuple_size;
- if (bi->profile == &t10_pi_type1_crc)
+ if (bi->flags & BLK_INTEGRITY_REF_TAG)
ns->pi_type = NVME_NS_DPS_PI_TYPE1;
- else if (bi->profile == &t10_pi_type3_crc)
- ns->pi_type = NVME_NS_DPS_PI_TYPE3;
else
- /* Unsupported metadata type */
- ns->metadata_size = 0;
+ ns->pi_type = NVME_NS_DPS_PI_TYPE3;
+ } else {
+ ns->metadata_size = 0;
}
}
@@ -102,7 +104,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);
if (bdev_is_zoned(ns->bdev)) {
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 065db86d602164..37c24ffea65cc0 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -82,7 +82,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,
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index e21b7df5c31b0d..67f24607b862a3 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -804,7 +804,7 @@ static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
unsigned int protect = 0;
if (dix) { /* DIX Type 0, 1, 2, 3 */
- if (bi->flags & BLK_INTEGRITY_IP_CHECKSUM)
+ if (bi->csum_type == BLK_INTEGRITY_CSUM_IP)
scmd->prot_flags |= SCSI_PROT_IP_CHECKSUM;
scmd->prot_flags |= SCSI_PROT_GUARD_CHECK;
}
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index 1df847b5f74764..6f0921c7db787b 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -47,18 +47,13 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
memset(&bi, 0, sizeof(bi));
/* Enable DMA of protection information */
- if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) {
- if (type == T10_PI_TYPE3_PROTECTION)
- bi.profile = &t10_pi_type3_ip;
- else
- bi.profile = &t10_pi_type1_ip;
+ if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP)
+ bi.csum_type = BLK_INTEGRITY_CSUM_IP;
+ else
+ bi.csum_type = BLK_INTEGRITY_CSUM_CRC;
- bi.flags |= BLK_INTEGRITY_IP_CHECKSUM;
- } else
- if (type == T10_PI_TYPE3_PROTECTION)
- bi.profile = &t10_pi_type3_crc;
- else
- bi.profile = &t10_pi_type1_crc;
+ if (type != T10_PI_TYPE3_PROTECTION)
+ bi.flags |= BLK_INTEGRITY_REF_TAG;
bi.tuple_size = sizeof(struct t10_pi_tuple);
@@ -76,7 +71,7 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
sd_first_printk(KERN_NOTICE, sdkp,
"Enabling DIX %s, application tag size %u bytes\n",
- bi.profile->name, bi.tag_size);
+ blk_integrity_profile_name(&bi), bi.tag_size);
out:
blk_integrity_register(disk, &bi);
}
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 7f6ca81778453b..a3e09adc4e767c 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -148,35 +148,38 @@ static int iblock_configure_device(struct se_device *dev)
dev->dev_attrib.is_nonrot = 1;
bi = bdev_get_integrity(bd);
- 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);
- ret = -ENOSYS;
- goto out_blkdev_put;
- }
+ if (!bi)
+ return 0;
- 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")) {
+ switch (bi->csum_type) {
+ case BLK_INTEGRITY_CSUM_IP:
+ pr_err("IBLOCK export of blk_integrity: %s not supported\n",
+ blk_integrity_profile_name(bi));
+ ret = -ENOSYS;
+ goto out_blkdev_put;
+ case BLK_INTEGRITY_CSUM_CRC:
+ if (bi->flags & BLK_INTEGRITY_REF_TAG)
dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE1_PROT;
- }
+ else
+ dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE3_PROT;
+ break;
+ default:
+ break;
+ }
- 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");
- ret = -ENOMEM;
- goto out_blkdev_put;
- }
- pr_debug("IBLOCK setup BIP bs->bio_integrity_pool: %p\n",
- &bs->bio_integrity_pool);
+ if (dev->dev_attrib.pi_prot_type) {
+ struct bio_set *bs = &ib_dev->ibd_bio_set;
+
+ if (bioset_integrity_create(bs, IBLOCK_BIO_POOL_SIZE) < 0) {
+ pr_err("Unable to allocate bioset for PI\n");
+ ret = -ENOMEM;
+ goto out_blkdev_put;
}
- dev->dev_attrib.hw_pi_prot_type = dev->dev_attrib.pi_prot_type;
+ pr_debug("IBLOCK setup BIP bs->bio_integrity_pool: %p\n",
+ &bs->bio_integrity_pool);
}
+ dev->dev_attrib.hw_pi_prot_type = dev->dev_attrib.pi_prot_type;
return 0;
out_blkdev_put:
diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h
index 7428cb43952da0..dea0fdebc3bdc7 100644
--- a/include/linux/blk-integrity.h
+++ b/include/linux/blk-integrity.h
@@ -10,7 +10,14 @@ enum blk_integrity_flags {
BLK_INTEGRITY_VERIFY = 1 << 0,
BLK_INTEGRITY_GENERATE = 1 << 1,
BLK_INTEGRITY_DEVICE_CAPABLE = 1 << 2,
- BLK_INTEGRITY_IP_CHECKSUM = 1 << 3,
+ BLK_INTEGRITY_REF_TAG = 1 << 3,
+};
+
+enum blk_integerity_checksum {
+ BLK_INTEGRITY_CSUM_NONE = 0,
+ BLK_INTEGRITY_CSUM_IP = 1,
+ BLK_INTEGRITY_CSUM_CRC = 2,
+ BLK_INTEGRITY_CSUM_CRC64 = 3,
};
struct blk_integrity_iter {
@@ -19,22 +26,10 @@ struct blk_integrity_iter {
sector_t seed;
unsigned int data_size;
unsigned short interval;
- unsigned char tuple_size;
- unsigned char pi_offset;
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;
-};
+const char *blk_integrity_profile_name(struct blk_integrity *bi);
#ifdef CONFIG_BLK_DEV_INTEGRITY
void blk_integrity_register(struct gendisk *, struct blk_integrity *);
@@ -44,14 +39,17 @@ int blk_rq_map_integrity_sg(struct request_queue *, struct bio *,
struct scatterlist *);
int blk_rq_count_integrity_sg(struct request_queue *, struct bio *);
-static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk)
+static inline bool
+blk_integrity_queue_supports_integrity(struct request_queue *q)
{
- struct blk_integrity *bi = &disk->queue->integrity;
+ return q->integrity.tuple_size;
+}
- if (!bi->profile)
+static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk)
+{
+ if (!blk_integrity_queue_supports_integrity(disk->queue))
return NULL;
-
- return bi;
+ return &disk->queue->integrity;
}
static inline struct blk_integrity *
@@ -60,12 +58,6 @@ bdev_get_integrity(struct block_device *bdev)
return blk_get_integrity(bdev->bd_disk);
}
-static inline bool
-blk_integrity_queue_supports_integrity(struct request_queue *q)
-{
- return q->integrity.profile;
-}
-
static inline unsigned short
queue_max_integrity_segments(const struct request_queue *q)
{
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ac8e0cb2353a0e..f5b0911eed55c6 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -106,8 +106,8 @@ struct disk_events;
struct badblocks;
struct blk_integrity {
- const struct blk_integrity_profile *profile;
unsigned char flags;
+ unsigned char csum_type;
unsigned char tuple_size;
unsigned char pi_offset;
unsigned char interval_exp;
diff --git a/include/linux/t10-pi.h b/include/linux/t10-pi.h
index 248f4ac9564258..d2bafb76badfb9 100644
--- a/include/linux/t10-pi.h
+++ b/include/linux/t10-pi.h
@@ -48,11 +48,6 @@ static inline u32 t10_pi_ref_tag(struct request *rq)
return blk_rq_pos(rq) >> (shift - SECTOR_SHIFT) & 0xffffffff;
}
-extern const struct blk_integrity_profile t10_pi_type1_crc;
-extern const struct blk_integrity_profile t10_pi_type1_ip;
-extern const struct blk_integrity_profile t10_pi_type3_crc;
-extern const struct blk_integrity_profile t10_pi_type3_ip;
-
struct crc64_pi_tuple {
__be64 guard_tag;
__be16 app_tag;
@@ -79,7 +74,4 @@ static inline u64 ext_pi_ref_tag(struct request *rq)
return lower_48_bits(blk_rq_pos(rq) >> (shift - SECTOR_SHIFT));
}
-extern const struct blk_integrity_profile ext_pi_type1_crc64;
-extern const struct blk_integrity_profile ext_pi_type3_crc64;
-
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 05/12] block: remove the blk_flush_integrity call in blk_integrity_unregister
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
` (3 preceding siblings ...)
2024-06-05 6:28 ` [PATCH 04/12] block: remove the blk_integrity_profile structure Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-05 6:28 ` [PATCH 06/12] block: factor out flag_{store,show} helper for integrity Christoph Hellwig
` (6 subsequent siblings)
11 siblings, 0 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
Now that there are no indirect calls for PI processing there is no
way to dereference a NULL pointer here. Additionally drivers now always
freeze the queue (or in case of stacking drivers use their internal
equivalent) around changing the integrity profile.
This is effectively a revert of commit 3df49967f6f1 ("block: flush the
integrity workqueue in blk_integrity_unregister").
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-integrity.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 4767603b443990..e11b815c03c981 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -399,8 +399,6 @@ void blk_integrity_unregister(struct gendisk *disk)
if (!bi->tuple_size)
return;
- /* ensure all bios are off the integrity workqueue */
- blk_flush_integrity();
blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue);
memset(bi, 0, sizeof(*bi));
}
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 06/12] block: factor out flag_{store,show} helper for integrity
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
` (4 preceding siblings ...)
2024-06-05 6:28 ` [PATCH 05/12] block: remove the blk_flush_integrity call in blk_integrity_unregister Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-05 16:00 ` Keith Busch
2024-06-06 0:16 ` Chaitanya Kulkarni
2024-06-05 6:28 ` [PATCH 07/12] block: use kstrtoul in flag_store Christoph Hellwig
` (5 subsequent siblings)
11 siblings, 2 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
Factor the duplicate code for the generate and verify attributes into
common helpers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-integrity.c | 53 +++++++++++++++++++++----------------------
1 file changed, 26 insertions(+), 27 deletions(-)
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index e11b815c03c981..686b6adf0ea5c7 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -241,6 +241,28 @@ const char *blk_integrity_profile_name(struct blk_integrity *bi)
}
EXPORT_SYMBOL_GPL(blk_integrity_profile_name);
+static ssize_t flag_store(struct device *dev, struct device_attribute *attr,
+ const char *page, size_t count, unsigned char flag)
+{
+ struct blk_integrity *bi = dev_to_bi(dev);
+ char *p = (char *) page;
+ unsigned long val = simple_strtoul(p, &p, 10);
+
+ if (val)
+ bi->flags |= flag;
+ else
+ bi->flags &= ~flag;
+ return count;
+}
+
+static ssize_t flag_show(struct device *dev, struct device_attribute *attr,
+ char *page, unsigned char flag)
+{
+ struct blk_integrity *bi = dev_to_bi(dev);
+
+ return sysfs_emit(page, "%d\n", !!(bi->flags & flag));
+}
+
static ssize_t format_show(struct device *dev, struct device_attribute *attr,
char *page)
{
@@ -273,49 +295,26 @@ static ssize_t read_verify_store(struct device *dev,
struct device_attribute *attr,
const char *page, size_t count)
{
- struct blk_integrity *bi = dev_to_bi(dev);
- char *p = (char *) page;
- unsigned long val = simple_strtoul(p, &p, 10);
-
- if (val)
- bi->flags |= BLK_INTEGRITY_VERIFY;
- else
- bi->flags &= ~BLK_INTEGRITY_VERIFY;
-
- return count;
+ return flag_store(dev, attr, page, count, BLK_INTEGRITY_VERIFY);
}
static ssize_t read_verify_show(struct device *dev,
struct device_attribute *attr, char *page)
{
- struct blk_integrity *bi = dev_to_bi(dev);
-
- return sysfs_emit(page, "%d\n", !!(bi->flags & BLK_INTEGRITY_VERIFY));
+ return flag_show(dev, attr, page, BLK_INTEGRITY_VERIFY);
}
static ssize_t write_generate_store(struct device *dev,
struct device_attribute *attr,
const char *page, size_t count)
{
- struct blk_integrity *bi = dev_to_bi(dev);
-
- char *p = (char *) page;
- unsigned long val = simple_strtoul(p, &p, 10);
-
- if (val)
- bi->flags |= BLK_INTEGRITY_GENERATE;
- else
- bi->flags &= ~BLK_INTEGRITY_GENERATE;
-
- return count;
+ return flag_store(dev, attr, page, count, BLK_INTEGRITY_GENERATE);
}
static ssize_t write_generate_show(struct device *dev,
struct device_attribute *attr, char *page)
{
- struct blk_integrity *bi = dev_to_bi(dev);
-
- return sysfs_emit(page, "%d\n", !!(bi->flags & BLK_INTEGRITY_GENERATE));
+ return flag_show(dev, attr, page, BLK_INTEGRITY_GENERATE);
}
static ssize_t device_is_integrity_capable_show(struct device *dev,
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 07/12] block: use kstrtoul in flag_store
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
` (5 preceding siblings ...)
2024-06-05 6:28 ` [PATCH 06/12] block: factor out flag_{store,show} helper for integrity Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-05 16:00 ` Keith Busch
2024-06-06 0:16 ` Chaitanya Kulkarni
2024-06-05 6:28 ` [PATCH 08/12] block: don't pretend to generate/verify for non-PI metadata Christoph Hellwig
` (4 subsequent siblings)
11 siblings, 2 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
Use the text to integer helper that has error handling and doesn't modify
the input pointer.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-integrity.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 686b6adf0ea5c7..bb3cd1e0eeb58e 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -245,8 +245,12 @@ static ssize_t flag_store(struct device *dev, struct device_attribute *attr,
const char *page, size_t count, unsigned char flag)
{
struct blk_integrity *bi = dev_to_bi(dev);
- char *p = (char *) page;
- unsigned long val = simple_strtoul(p, &p, 10);
+ unsigned long val;
+ int err;
+
+ err = kstrtoul(page, 10, &val);
+ if (err)
+ return err;
if (val)
bi->flags |= flag;
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 08/12] block: don't pretend to generate/verify for non-PI metadata
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
` (6 preceding siblings ...)
2024-06-05 6:28 ` [PATCH 07/12] block: use kstrtoul in flag_store Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-05 6:28 ` [PATCH 09/12] block: don't require stable pages " Christoph Hellwig
` (3 subsequent siblings)
11 siblings, 0 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
The kernel won't ever generate or verify non-PI metadata, so don't
set the flags and don't allow the user to modify them.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-integrity.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index bb3cd1e0eeb58e..c2fcb8e659ed56 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -248,6 +248,9 @@ static ssize_t flag_store(struct device *dev, struct device_attribute *attr,
unsigned long val;
int err;
+ if (bi->csum_type == BLK_INTEGRITY_CSUM_NONE)
+ return -EINVAL;
+
err = kstrtoul(page, 10, &val);
if (err)
return err;
@@ -369,8 +372,9 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
struct blk_integrity *bi = &disk->queue->integrity;
bi->csum_type = template->csum_type;
- bi->flags = BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE |
- template->flags;
+ bi->flags = template->flags;
+ if (bi->csum_type != BLK_INTEGRITY_CSUM_NONE)
+ bi->flags |= BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE;
bi->interval_exp = template->interval_exp ? :
ilog2(queue_logical_block_size(disk->queue));
bi->tuple_size = template->tuple_size;
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 09/12] block: don't require stable pages for non-PI metadata
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
` (7 preceding siblings ...)
2024-06-05 6:28 ` [PATCH 08/12] block: don't pretend to generate/verify for non-PI metadata Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-05 6:28 ` [PATCH 10/12] block: bypass the STABLE_WRITES flag for protection information Christoph Hellwig
` (2 subsequent siblings)
11 siblings, 0 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
Non-PI metadata doesn't contain checksums and thus doesn't require
stable pages.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-integrity.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index c2fcb8e659ed56..f07d44be6b2236 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -381,7 +381,8 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
bi->tag_size = template->tag_size;
bi->pi_offset = template->pi_offset;
- blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, disk->queue);
+ if (bi->csum_type != BLK_INTEGRITY_CSUM_NONE)
+ blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, disk->queue);
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
if (disk->queue->crypto_profile) {
@@ -406,7 +407,8 @@ void blk_integrity_unregister(struct gendisk *disk)
if (!bi->tuple_size)
return;
- blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue);
+ if (bi->csum_type != BLK_INTEGRITY_CSUM_NONE)
+ blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue);
memset(bi, 0, sizeof(*bi));
}
EXPORT_SYMBOL(blk_integrity_unregister);
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 10/12] block: bypass the STABLE_WRITES flag for protection information
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
` (8 preceding siblings ...)
2024-06-05 6:28 ` [PATCH 09/12] block: don't require stable pages " Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-05 6:28 ` [PATCH 11/12] block: invert the BLK_INTEGRITY_{GENERATE,VERIFY} flags Christoph Hellwig
2024-06-05 6:28 ` [PATCH 12/12] block: move integrity information into queue_limits Christoph Hellwig
11 siblings, 0 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
Currently registering a checksum-enabled (aka PI) integrity profile sets
the QUEUE_FLAG_STABLE_WRITE flag, and unregistering it clears the flag.
This can incorrectly clear the flag when the driver requires stable
writes even without PI, e.g. in case of iSCSI or NVMe/TCP with data
digest enabled.
Fix this by looking at the csum_type directly in bdev_stable_writes and
not setting the queue flag. Also remove the blk_queue_stable_writes
helper as the only user in nvme wants to only look at the actual
QUEUE_FLAG_STABLE_WRITE flag as it inherits the integrity configuration
by other means.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-integrity.c | 6 ------
drivers/nvme/host/multipath.c | 3 ++-
include/linux/blkdev.h | 12 ++++++++----
3 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index f07d44be6b2236..fbb0bd467eedbf 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -381,9 +381,6 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
bi->tag_size = template->tag_size;
bi->pi_offset = template->pi_offset;
- if (bi->csum_type != BLK_INTEGRITY_CSUM_NONE)
- blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, disk->queue);
-
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
if (disk->queue->crypto_profile) {
pr_warn("blk-integrity: Integrity and hardware inline encryption are not supported together. Disabling hardware inline encryption.\n");
@@ -406,9 +403,6 @@ void blk_integrity_unregister(struct gendisk *disk)
if (!bi->tuple_size)
return;
-
- if (bi->csum_type != BLK_INTEGRITY_CSUM_NONE)
- blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue);
memset(bi, 0, sizeof(*bi));
}
EXPORT_SYMBOL(blk_integrity_unregister);
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index d8b6b4648eaff9..12c59db02539e5 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -875,7 +875,8 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, __le32 anagrpid)
nvme_mpath_set_live(ns);
}
- if (blk_queue_stable_writes(ns->queue) && ns->head->disk)
+ if (test_bit(QUEUE_FLAG_STABLE_WRITES, &ns->queue->queue_flags) &&
+ ns->head->disk)
blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES,
ns->head->disk->queue);
#ifdef CONFIG_BLK_DEV_ZONED
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index f5b0911eed55c6..150910a4d4e6ae 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -564,8 +564,6 @@ bool blk_queue_flag_test_and_set(unsigned int flag, struct request_queue *q);
#define blk_queue_noxmerges(q) \
test_bit(QUEUE_FLAG_NOXMERGES, &(q)->queue_flags)
#define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags)
-#define blk_queue_stable_writes(q) \
- test_bit(QUEUE_FLAG_STABLE_WRITES, &(q)->queue_flags)
#define blk_queue_io_stat(q) test_bit(QUEUE_FLAG_IO_STAT, &(q)->queue_flags)
#define blk_queue_add_random(q) test_bit(QUEUE_FLAG_ADD_RANDOM, &(q)->queue_flags)
#define blk_queue_zone_resetall(q) \
@@ -1293,8 +1291,14 @@ static inline bool bdev_synchronous(struct block_device *bdev)
static inline bool bdev_stable_writes(struct block_device *bdev)
{
- return test_bit(QUEUE_FLAG_STABLE_WRITES,
- &bdev_get_queue(bdev)->queue_flags);
+ struct request_queue *q = bdev_get_queue(bdev);
+
+#ifdef CONFIG_BLK_DEV_INTEGRITY
+ /* BLK_INTEGRITY_CSUM_NONE is not available in blkdev.h */
+ if (q->integrity.csum_type != 0)
+ return true;
+#endif
+ return test_bit(QUEUE_FLAG_STABLE_WRITES, &q->queue_flags);
}
static inline bool bdev_write_cache(struct block_device *bdev)
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 11/12] block: invert the BLK_INTEGRITY_{GENERATE,VERIFY} flags
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
` (9 preceding siblings ...)
2024-06-05 6:28 ` [PATCH 10/12] block: bypass the STABLE_WRITES flag for protection information Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-06 0:20 ` Chaitanya Kulkarni
2024-06-05 6:28 ` [PATCH 12/12] block: move integrity information into queue_limits Christoph Hellwig
11 siblings, 1 reply; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
Invert the flags so that user set values will be able to persist
revalidating the integrity information once we switch the integrity
information to queue_limits.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio-integrity.c | 4 ++--
block/blk-integrity.c | 19 ++++++++++---------
include/linux/blk-integrity.h | 4 ++--
3 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index 5966a65edcd10e..3d6f6a63888f2e 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -450,10 +450,10 @@ bool bio_integrity_prep(struct bio *bio)
return true;
if (bio_data_dir(bio) == READ) {
- if (!(bi->flags & BLK_INTEGRITY_VERIFY))
+ if (bi->flags & BLK_INTEGRITY_NOVERIFY)
return true;
} else {
- if (!(bi->flags & BLK_INTEGRITY_GENERATE))
+ if (bi->flags & BLK_INTEGRITY_NOGENERATE)
return true;
}
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index fbb0bd467eedbf..9a126c8d08f1d8 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -255,10 +255,11 @@ static ssize_t flag_store(struct device *dev, struct device_attribute *attr,
if (err)
return err;
+ /* the flags are inverted vs the values in the sysfs files */
if (val)
- bi->flags |= flag;
- else
bi->flags &= ~flag;
+ else
+ bi->flags |= flag;
return count;
}
@@ -267,7 +268,9 @@ static ssize_t flag_show(struct device *dev, struct device_attribute *attr,
{
struct blk_integrity *bi = dev_to_bi(dev);
- return sysfs_emit(page, "%d\n", !!(bi->flags & flag));
+ return sysfs_emit(page, "%d\n",
+ (bi->csum_type != BLK_INTEGRITY_CSUM_NONE &&
+ !(bi->flags & flag)));
}
static ssize_t format_show(struct device *dev, struct device_attribute *attr,
@@ -302,26 +305,26 @@ static ssize_t read_verify_store(struct device *dev,
struct device_attribute *attr,
const char *page, size_t count)
{
- return flag_store(dev, attr, page, count, BLK_INTEGRITY_VERIFY);
+ return flag_store(dev, attr, page, count, BLK_INTEGRITY_NOVERIFY);
}
static ssize_t read_verify_show(struct device *dev,
struct device_attribute *attr, char *page)
{
- return flag_show(dev, attr, page, BLK_INTEGRITY_VERIFY);
+ return flag_show(dev, attr, page, BLK_INTEGRITY_NOVERIFY);
}
static ssize_t write_generate_store(struct device *dev,
struct device_attribute *attr,
const char *page, size_t count)
{
- return flag_store(dev, attr, page, count, BLK_INTEGRITY_GENERATE);
+ return flag_store(dev, attr, page, count, BLK_INTEGRITY_NOGENERATE);
}
static ssize_t write_generate_show(struct device *dev,
struct device_attribute *attr, char *page)
{
- return flag_show(dev, attr, page, BLK_INTEGRITY_GENERATE);
+ return flag_show(dev, attr, page, BLK_INTEGRITY_NOGENERATE);
}
static ssize_t device_is_integrity_capable_show(struct device *dev,
@@ -373,8 +376,6 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
bi->csum_type = template->csum_type;
bi->flags = template->flags;
- if (bi->csum_type != BLK_INTEGRITY_CSUM_NONE)
- bi->flags |= BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE;
bi->interval_exp = template->interval_exp ? :
ilog2(queue_logical_block_size(disk->queue));
bi->tuple_size = template->tuple_size;
diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h
index dea0fdebc3bdc7..a4bf2c78776c06 100644
--- a/include/linux/blk-integrity.h
+++ b/include/linux/blk-integrity.h
@@ -7,8 +7,8 @@
struct request;
enum blk_integrity_flags {
- BLK_INTEGRITY_VERIFY = 1 << 0,
- BLK_INTEGRITY_GENERATE = 1 << 1,
+ BLK_INTEGRITY_NOVERIFY = 1 << 0,
+ BLK_INTEGRITY_NOGENERATE = 1 << 1,
BLK_INTEGRITY_DEVICE_CAPABLE = 1 << 2,
BLK_INTEGRITY_REF_TAG = 1 << 3,
};
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 12/12] block: move integrity information into queue_limits
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
` (10 preceding siblings ...)
2024-06-05 6:28 ` [PATCH 11/12] block: invert the BLK_INTEGRITY_{GENERATE,VERIFY} flags Christoph Hellwig
@ 2024-06-05 6:28 ` Christoph Hellwig
2024-06-05 16:56 ` Bart Van Assche
11 siblings, 1 reply; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-05 6:28 UTC (permalink / raw)
To: Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
Move the integrity information into the queue limits so that it can be
set atomically with other queue limits, and that the sysfs changes to
the read_verify and write_generate flags are properly synchronized.
This also allows to provide a more useful helper to stack the integrity
fields, although it still is separate from the main stacking function
as not all stackable devices want to inherit the integrity settings.
Even with that it greatly simplifies the code in md and dm.
Note that the integrity field is moved as-is into the queue limits.
While there are good arguments for removing the separate blk_integrity
structure, this would cause a lot of churn and might better be done at a
later time if desired. However the integrity field in the queue_limits
structure is now unconditional so that various ifdefs can be avoided or
replaced with IS_ENABLED(). Given that tiny size of it that seems like
a worthwhile trade off.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
Documentation/block/data-integrity.rst | 49 +-------
block/blk-integrity.c | 126 +++----------------
block/blk-settings.c | 118 +++++++++++++++++-
block/t10-pi.c | 12 +-
drivers/md/dm-core.h | 1 -
drivers/md/dm-integrity.c | 27 ++---
drivers/md/dm-table.c | 161 +++++--------------------
drivers/md/md.c | 72 +++--------
drivers/md/md.h | 5 +-
drivers/md/raid0.c | 7 +-
drivers/md/raid1.c | 10 +-
drivers/md/raid10.c | 10 +-
drivers/md/raid5.c | 2 +-
drivers/nvdimm/btt.c | 13 +-
drivers/nvme/host/core.c | 70 +++++------
drivers/scsi/sd.c | 10 +-
drivers/scsi/sd.h | 12 +-
drivers/scsi/sd_dif.c | 37 +++---
include/linux/blk-integrity.h | 32 ++---
include/linux/blkdev.h | 11 +-
include/linux/t10-pi.h | 12 +-
21 files changed, 298 insertions(+), 499 deletions(-)
diff --git a/Documentation/block/data-integrity.rst b/Documentation/block/data-integrity.rst
index 6a760c0eb1924e..99905e880a0e56 100644
--- a/Documentation/block/data-integrity.rst
+++ b/Documentation/block/data-integrity.rst
@@ -153,18 +153,11 @@ bio_free() will automatically free the bip.
4.2 Block Device
----------------
-Because the format of the protection data is tied to the physical
-disk, each block device has been extended with a block integrity
-profile (struct blk_integrity). This optional profile is registered
-with the block layer using blk_integrity_register().
-
-The profile contains callback functions for generating and verifying
-the protection data, as well as getting and setting application tags.
-The profile also contains a few constants to aid in completing,
-merging and splitting the integrity metadata.
+Block devices can set up the integrity information in the integrity
+sub-struture of the queue_limits structure.
Layered block devices will need to pick a profile that's appropriate
-for all subdevices. blk_integrity_compare() can help with that. DM
+for all subdevices. queue_limits_stack_integrity() can help with that. DM
and MD linear, RAID0 and RAID1 are currently supported. RAID4/5/6
will require extra work due to the application tag.
@@ -250,42 +243,6 @@ will require extra work due to the application tag.
integrity upon completion.
-5.4 Registering A Block Device As Capable Of Exchanging Integrity Metadata
---------------------------------------------------------------------------
-
- To enable integrity exchange on a block device the gendisk must be
- registered as capable:
-
- `int blk_integrity_register(gendisk, blk_integrity);`
-
- The blk_integrity struct is a template and should contain the
- following::
-
- static struct blk_integrity my_profile = {
- .name = "STANDARDSBODY-TYPE-VARIANT-CSUM",
- .generate_fn = my_generate_fn,
- .verify_fn = my_verify_fn,
- .tuple_size = sizeof(struct my_tuple_size),
- .tag_size = <tag bytes per hw sector>,
- };
-
- 'name' is a text string which will be visible in sysfs. This is
- part of the userland API so chose it carefully and never change
- it. The format is standards body-type-variant.
- E.g. T10-DIF-TYPE1-IP or T13-EPP-0-CRC.
-
- 'generate_fn' generates appropriate integrity metadata (for WRITE).
-
- 'verify_fn' verifies that the data buffer matches the integrity
- metadata.
-
- 'tuple_size' must be set to match the size of the integrity
- metadata per sector. I.e. 8 for DIF and EPP.
-
- 'tag_size' must be set to identify how many bytes of tag space
- are available per hardware sector. For DIF this is either 2 or
- 0 depending on the value of the Control Mode Page ATO bit.
-
----------------------------------------------------------------------
2007-12-24 Martin K. Petersen <martin.petersen@oracle.com>
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 9a126c8d08f1d8..e55ef5c6859739 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -107,63 +107,6 @@ int blk_rq_map_integrity_sg(struct request_queue *q, struct bio *bio,
}
EXPORT_SYMBOL(blk_rq_map_integrity_sg);
-/**
- * blk_integrity_compare - Compare integrity profile of two disks
- * @gd1: Disk to compare
- * @gd2: Disk to compare
- *
- * Description: Meta-devices like DM and MD need to verify that all
- * sub-devices use the same integrity format before advertising to
- * upper layers that they can send/receive integrity metadata. This
- * function can be used to check whether two gendisk devices have
- * compatible integrity formats.
- */
-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->tuple_size && !b2->tuple_size)
- return 0;
-
- if (!b1->tuple_size || !b2->tuple_size)
- return -1;
-
- if (b1->interval_exp != b2->interval_exp) {
- pr_err("%s: %s/%s protection interval %u != %u\n",
- __func__, gd1->disk_name, gd2->disk_name,
- 1 << b1->interval_exp, 1 << b2->interval_exp);
- return -1;
- }
-
- if (b1->tuple_size != b2->tuple_size) {
- pr_err("%s: %s/%s tuple sz %u != %u\n", __func__,
- gd1->disk_name, gd2->disk_name,
- b1->tuple_size, b2->tuple_size);
- return -1;
- }
-
- 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);
- return -1;
- }
-
- if (b1->csum_type != b2->csum_type ||
- (b1->flags & BLK_INTEGRITY_REF_TAG) !=
- (b2->flags & BLK_INTEGRITY_REF_TAG)) {
- pr_err("%s: %s/%s type %s != %s\n", __func__,
- gd1->disk_name, gd2->disk_name,
- blk_integrity_profile_name(b1),
- blk_integrity_profile_name(b2));
- return -1;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(blk_integrity_compare);
-
bool blk_integrity_merge_rq(struct request_queue *q, struct request *req,
struct request *next)
{
@@ -217,7 +160,7 @@ bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,
static inline struct blk_integrity *dev_to_bi(struct device *dev)
{
- return &dev_to_disk(dev)->queue->integrity;
+ return &dev_to_disk(dev)->queue->limits.integrity;
}
const char *blk_integrity_profile_name(struct blk_integrity *bi)
@@ -244,22 +187,30 @@ EXPORT_SYMBOL_GPL(blk_integrity_profile_name);
static ssize_t flag_store(struct device *dev, struct device_attribute *attr,
const char *page, size_t count, unsigned char flag)
{
- struct blk_integrity *bi = dev_to_bi(dev);
+ struct request_queue *q = dev_to_disk(dev)->queue;
+ struct queue_limits lim;
unsigned long val;
int err;
- if (bi->csum_type == BLK_INTEGRITY_CSUM_NONE)
+ if (q->limits.integrity.csum_type == BLK_INTEGRITY_CSUM_NONE)
return -EINVAL;
err = kstrtoul(page, 10, &val);
if (err)
return err;
- /* the flags are inverted vs the values in the sysfs files */
+ /* note that the flags are inverted vs the values in the sysfs files */
+ lim = queue_limits_start_update(q);
if (val)
- bi->flags &= ~flag;
+ lim.integrity.flags &= ~flag;
else
- bi->flags |= flag;
+ lim.integrity.flags |= flag;
+
+ blk_mq_freeze_queue(q);
+ err = queue_limits_commit_update(q, &lim);
+ blk_mq_unfreeze_queue(q);
+ if (err)
+ return err;
return count;
}
@@ -358,52 +309,3 @@ const struct attribute_group blk_integrity_attr_group = {
.name = "integrity",
.attrs = integrity_attrs,
};
-
-/**
- * blk_integrity_register - Register a gendisk as being integrity-capable
- * @disk: struct gendisk pointer to make integrity-aware
- * @template: block integrity profile to register
- *
- * Description: When a device needs to advertise itself as being able to
- * send/receive integrity metadata it must use this function to register
- * the capability with the block layer. The template is a blk_integrity
- * struct with values appropriate for the underlying hardware. See
- * Documentation/block/data-integrity.rst.
- */
-void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template)
-{
- struct blk_integrity *bi = &disk->queue->integrity;
-
- bi->csum_type = template->csum_type;
- bi->flags = template->flags;
- bi->interval_exp = template->interval_exp ? :
- ilog2(queue_logical_block_size(disk->queue));
- bi->tuple_size = template->tuple_size;
- bi->tag_size = template->tag_size;
- bi->pi_offset = template->pi_offset;
-
-#ifdef CONFIG_BLK_INLINE_ENCRYPTION
- if (disk->queue->crypto_profile) {
- pr_warn("blk-integrity: Integrity and hardware inline encryption are not supported together. Disabling hardware inline encryption.\n");
- disk->queue->crypto_profile = NULL;
- }
-#endif
-}
-EXPORT_SYMBOL(blk_integrity_register);
-
-/**
- * blk_integrity_unregister - Unregister block integrity profile
- * @disk: disk whose integrity profile to unregister
- *
- * Description: This function unregisters the integrity capability from
- * a block device.
- */
-void blk_integrity_unregister(struct gendisk *disk)
-{
- struct blk_integrity *bi = &disk->queue->integrity;
-
- if (!bi->tuple_size)
- return;
- memset(bi, 0, sizeof(*bi));
-}
-EXPORT_SYMBOL(blk_integrity_unregister);
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 996f247fc98e80..f11c8676eb4c67 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -6,7 +6,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bio.h>
-#include <linux/blkdev.h>
+#include <linux/blk-integrity.h>
#include <linux/pagemap.h>
#include <linux/backing-dev-defs.h>
#include <linux/gcd.h>
@@ -97,6 +97,36 @@ static int blk_validate_zoned_limits(struct queue_limits *lim)
return 0;
}
+static int blk_validate_integrity_limits(struct queue_limits *lim)
+{
+ struct blk_integrity *bi = &lim->integrity;
+
+ if (!bi->tuple_size) {
+ if (bi->csum_type != BLK_INTEGRITY_CSUM_NONE ||
+ bi->tag_size || ((bi->flags & BLK_INTEGRITY_REF_TAG))) {
+ pr_warn("invalid PI settings.\n");
+ return -EINVAL;
+ }
+ return 0;
+ }
+
+ if (!IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY)) {
+ pr_warn("integrity support disabled.\n");
+ return -EINVAL;
+ }
+
+ if (bi->csum_type == BLK_INTEGRITY_CSUM_NONE &&
+ (bi->flags & BLK_INTEGRITY_REF_TAG)) {
+ pr_warn("ref tag not support without checksum.\n");
+ return -EINVAL;
+ }
+
+ if (!bi->interval_exp)
+ bi->interval_exp = ilog2(lim->logical_block_size);
+
+ return 0;
+}
+
/*
* Check that the limits in lim are valid, initialize defaults for unset
* values, and cap values based on others where needed.
@@ -105,6 +135,7 @@ static int blk_validate_limits(struct queue_limits *lim)
{
unsigned int max_hw_sectors;
unsigned int logical_block_sectors;
+ int err;
/*
* Unless otherwise specified, default to 512 byte logical blocks and a
@@ -230,6 +261,9 @@ static int blk_validate_limits(struct queue_limits *lim)
lim->misaligned = 0;
}
+ err = blk_validate_integrity_limits(lim);
+ if (err)
+ return err;
return blk_validate_zoned_limits(lim);
}
@@ -263,13 +297,24 @@ int queue_limits_commit_update(struct request_queue *q,
struct queue_limits *lim)
__releases(q->limits_lock)
{
- int error = blk_validate_limits(lim);
+ int error;
- if (!error) {
- q->limits = *lim;
- if (q->disk)
- blk_apply_bdi_limits(q->disk->bdi, lim);
+ error = blk_validate_limits(lim);
+ if (error)
+ goto out_unlock;
+
+#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ if (q->crypto_profile && lim->integrity.tag_size) {
+ pr_warn("blk-integrity: Integrity and hardware inline encryption are not supported together.\n");
+ error = -EINVAL;
+ goto out_unlock;
}
+#endif
+
+ q->limits = *lim;
+ if (q->disk)
+ blk_apply_bdi_limits(q->disk->bdi, lim);
+out_unlock:
mutex_unlock(&q->limits_lock);
return error;
}
@@ -575,6 +620,67 @@ void queue_limits_stack_bdev(struct queue_limits *t, struct block_device *bdev,
}
EXPORT_SYMBOL_GPL(queue_limits_stack_bdev);
+/**
+ * queue_limits_stack_integrity - stack integrity profile
+ * @t: target queue limits
+ * @b: base queue limits
+ *
+ * Check if the integrity profile in the @b can be stacked into the
+ * target @t. Stacking is possible if either:
+ *
+ * a) does not have any integrity information stacked into it yet
+ * b) the integrity profile in @b is identical to the one in @t
+ *
+ * If @b can be stacked into @t, return %true. Else return %false and clear the
+ * integrity information in @t.
+ */
+bool queue_limits_stack_integrity(struct queue_limits *t,
+ struct queue_limits *b)
+{
+ struct blk_integrity *ti = &t->integrity;
+ struct blk_integrity *bi = &b->integrity;
+
+ if (!IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY))
+ return true;
+
+ if (!ti->tuple_size) {
+ /* inherit the settings from the first underlying device */
+ if (!(ti->flags & BLK_INTEGRITY_STACKED)) {
+ ti->flags = BLK_INTEGRITY_DEVICE_CAPABLE |
+ (bi->flags & BLK_INTEGRITY_REF_TAG);
+ ti->csum_type = bi->csum_type;
+ ti->tuple_size = bi->tuple_size;
+ ti->pi_offset = bi->pi_offset;
+ ti->interval_exp = bi->interval_exp;
+ ti->tag_size = bi->tag_size;
+ goto done;
+ }
+ if (!bi->tuple_size)
+ goto done;
+ }
+
+ if (ti->tuple_size != bi->tuple_size)
+ goto incompatible;
+ if (ti->interval_exp != bi->interval_exp)
+ goto incompatible;
+ if (ti->tag_size != bi->tag_size)
+ goto incompatible;
+ if (ti->csum_type != bi->csum_type)
+ goto incompatible;
+ if ((ti->flags & BLK_INTEGRITY_REF_TAG) !=
+ (bi->flags & BLK_INTEGRITY_REF_TAG))
+ goto incompatible;
+
+done:
+ ti->flags |= BLK_INTEGRITY_STACKED;
+ return true;
+
+incompatible:
+ memset(ti, 0, sizeof(*ti));
+ return false;
+}
+EXPORT_SYMBOL_GPL(queue_limits_stack_integrity);
+
/**
* blk_queue_update_dma_pad - update pad mask
* @q: the request queue for the device
diff --git a/block/t10-pi.c b/block/t10-pi.c
index 2d8298a4cd3307..fb87ce3ad7efc5 100644
--- a/block/t10-pi.c
+++ b/block/t10-pi.c
@@ -118,7 +118,7 @@ static blk_status_t t10_pi_verify(struct blk_integrity_iter *iter,
*/
static void t10_pi_type1_prepare(struct request *rq)
{
- struct blk_integrity *bi = &rq->q->integrity;
+ struct blk_integrity *bi = &rq->q->limits.integrity;
const int tuple_sz = bi->tuple_size;
u32 ref_tag = t10_pi_ref_tag(rq);
u8 offset = bi->pi_offset;
@@ -169,7 +169,7 @@ static void t10_pi_type1_prepare(struct request *rq)
*/
static void t10_pi_type1_complete(struct request *rq, unsigned int nr_bytes)
{
- struct blk_integrity *bi = &rq->q->integrity;
+ struct blk_integrity *bi = &rq->q->limits.integrity;
unsigned intervals = nr_bytes >> bi->interval_exp;
const int tuple_sz = bi->tuple_size;
u32 ref_tag = t10_pi_ref_tag(rq);
@@ -292,7 +292,7 @@ static blk_status_t ext_pi_crc64_verify(struct blk_integrity_iter *iter,
static void ext_pi_type1_prepare(struct request *rq)
{
- struct blk_integrity *bi = &rq->q->integrity;
+ struct blk_integrity *bi = &rq->q->limits.integrity;
const int tuple_sz = bi->tuple_size;
u64 ref_tag = ext_pi_ref_tag(rq);
u8 offset = bi->pi_offset;
@@ -332,7 +332,7 @@ static void ext_pi_type1_prepare(struct request *rq)
static void ext_pi_type1_complete(struct request *rq, unsigned int nr_bytes)
{
- struct blk_integrity *bi = &rq->q->integrity;
+ struct blk_integrity *bi = &rq->q->limits.integrity;
unsigned intervals = nr_bytes >> bi->interval_exp;
const int tuple_sz = bi->tuple_size;
u64 ref_tag = ext_pi_ref_tag(rq);
@@ -385,7 +385,7 @@ blk_status_t blk_integrity_verify(struct blk_integrity_iter *iter,
void blk_integrity_prepare(struct request *rq)
{
- struct blk_integrity *bi = &rq->q->integrity;
+ struct blk_integrity *bi = &rq->q->limits.integrity;
if (!(bi->flags & BLK_INTEGRITY_REF_TAG))
return;
@@ -398,7 +398,7 @@ void blk_integrity_prepare(struct request *rq)
void blk_integrity_complete(struct request *rq, unsigned int nr_bytes)
{
- struct blk_integrity *bi = &rq->q->integrity;
+ struct blk_integrity *bi = &rq->q->limits.integrity;
if (!(bi->flags & BLK_INTEGRITY_REF_TAG))
return;
diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h
index 08700bfc3e2343..14a44c0f82868b 100644
--- a/drivers/md/dm-core.h
+++ b/drivers/md/dm-core.h
@@ -206,7 +206,6 @@ struct dm_table {
bool integrity_supported:1;
bool singleton:1;
- unsigned integrity_added:1;
/*
* Indicates the rw permissions for the new logical device. This
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index c1cc27541673c7..2a89f8eb4713c9 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -3475,6 +3475,17 @@ static void dm_integrity_io_hints(struct dm_target *ti, struct queue_limits *lim
limits->dma_alignment = limits->logical_block_size - 1;
limits->discard_granularity = ic->sectors_per_block << SECTOR_SHIFT;
}
+
+ if (!ic->internal_hash) {
+ struct blk_integrity *bi = &limits->integrity;
+
+ memset(bi, 0, sizeof(*bi));
+ bi->tuple_size = ic->tag_size;
+ bi->tag_size = bi->tuple_size;
+ bi->interval_exp =
+ ic->sb->log2_sectors_per_block + SECTOR_SHIFT;
+ }
+
limits->max_integrity_segments = USHRT_MAX;
}
@@ -3631,19 +3642,6 @@ static int initialize_superblock(struct dm_integrity_c *ic,
return 0;
}
-static void dm_integrity_set(struct dm_target *ti, struct dm_integrity_c *ic)
-{
- struct gendisk *disk = dm_disk(dm_table_get_md(ti->table));
- struct blk_integrity bi;
-
- memset(&bi, 0, sizeof(bi));
- bi.tuple_size = ic->tag_size;
- bi.tag_size = bi.tuple_size;
- bi.interval_exp = ic->sb->log2_sectors_per_block + SECTOR_SHIFT;
-
- blk_integrity_register(disk, &bi);
-}
-
static void dm_integrity_free_page_list(struct page_list *pl)
{
unsigned int i;
@@ -4629,9 +4627,6 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned int argc, char **argv
}
}
- if (!ic->internal_hash)
- dm_integrity_set(ti, ic);
-
ti->num_flush_bios = 1;
ti->flush_supported = true;
if (ic->discard)
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index b2d5246cff2102..fd789eeb62d943 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -425,6 +425,13 @@ static int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
q->limits.logical_block_size,
q->limits.alignment_offset,
(unsigned long long) start << SECTOR_SHIFT);
+
+ /*
+ * Only stack the integrity profile if the target doesn't have native
+ * integrity support.
+ */
+ if (!dm_target_has_integrity(ti->type))
+ queue_limits_stack_integrity_bdev(limits, bdev);
return 0;
}
@@ -702,9 +709,6 @@ int dm_table_add_target(struct dm_table *t, const char *type,
t->immutable_target_type = ti->type;
}
- if (dm_target_has_integrity(ti->type))
- t->integrity_added = 1;
-
ti->table = t;
ti->begin = start;
ti->len = len;
@@ -1119,99 +1123,6 @@ static int dm_table_build_index(struct dm_table *t)
return r;
}
-static bool integrity_profile_exists(struct gendisk *disk)
-{
- return !!blk_get_integrity(disk);
-}
-
-/*
- * Get a disk whose integrity profile reflects the table's profile.
- * Returns NULL if integrity support was inconsistent or unavailable.
- */
-static struct gendisk *dm_table_get_integrity_disk(struct dm_table *t)
-{
- struct list_head *devices = dm_table_get_devices(t);
- struct dm_dev_internal *dd = NULL;
- struct gendisk *prev_disk = NULL, *template_disk = NULL;
-
- for (unsigned int i = 0; i < t->num_targets; i++) {
- struct dm_target *ti = dm_table_get_target(t, i);
-
- if (!dm_target_passes_integrity(ti->type))
- goto no_integrity;
- }
-
- list_for_each_entry(dd, devices, list) {
- template_disk = dd->dm_dev->bdev->bd_disk;
- if (!integrity_profile_exists(template_disk))
- goto no_integrity;
- else if (prev_disk &&
- blk_integrity_compare(prev_disk, template_disk) < 0)
- goto no_integrity;
- prev_disk = template_disk;
- }
-
- return template_disk;
-
-no_integrity:
- if (prev_disk)
- DMWARN("%s: integrity not set: %s and %s profile mismatch",
- dm_device_name(t->md),
- prev_disk->disk_name,
- template_disk->disk_name);
- return NULL;
-}
-
-/*
- * Register the mapped device for blk_integrity support if the
- * underlying devices have an integrity profile. But all devices may
- * not have matching profiles (checking all devices isn't reliable
- * during table load because this table may use other DM device(s) which
- * must be resumed before they will have an initialized integity
- * profile). Consequently, stacked DM devices force a 2 stage integrity
- * profile validation: First pass during table load, final pass during
- * resume.
- */
-static int dm_table_register_integrity(struct dm_table *t)
-{
- struct mapped_device *md = t->md;
- struct gendisk *template_disk = NULL;
-
- /* If target handles integrity itself do not register it here. */
- if (t->integrity_added)
- return 0;
-
- template_disk = dm_table_get_integrity_disk(t);
- if (!template_disk)
- return 0;
-
- if (!integrity_profile_exists(dm_disk(md))) {
- t->integrity_supported = true;
- /*
- * Register integrity profile during table load; we can do
- * this because the final profile must match during resume.
- */
- blk_integrity_register(dm_disk(md),
- blk_get_integrity(template_disk));
- return 0;
- }
-
- /*
- * If DM device already has an initialized integrity
- * profile the new profile should not conflict.
- */
- if (blk_integrity_compare(dm_disk(md), template_disk) < 0) {
- DMERR("%s: conflict with existing integrity profile: %s profile mismatch",
- dm_device_name(t->md),
- template_disk->disk_name);
- return 1;
- }
-
- /* Preserve existing integrity profile */
- t->integrity_supported = true;
- return 0;
-}
-
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
struct dm_crypto_profile {
@@ -1423,12 +1334,6 @@ int dm_table_complete(struct dm_table *t)
return r;
}
- r = dm_table_register_integrity(t);
- if (r) {
- DMERR("could not register integrity profile.");
- return r;
- }
-
r = dm_table_construct_crypto_profile(t);
if (r) {
DMERR("could not construct crypto profile.");
@@ -1688,6 +1593,14 @@ int dm_calculate_queue_limits(struct dm_table *t,
blk_set_stacking_limits(limits);
+ t->integrity_supported = true;
+ for (unsigned int i = 0; i < t->num_targets; i++) {
+ struct dm_target *ti = dm_table_get_target(t, i);
+
+ if (!dm_target_passes_integrity(ti->type))
+ t->integrity_supported = false;
+ }
+
for (unsigned int i = 0; i < t->num_targets; i++) {
struct dm_target *ti = dm_table_get_target(t, i);
@@ -1738,6 +1651,18 @@ int dm_calculate_queue_limits(struct dm_table *t,
dm_device_name(t->md),
(unsigned long long) ti->begin,
(unsigned long long) ti->len);
+
+ if (t->integrity_supported ||
+ dm_target_has_integrity(ti->type)) {
+ if (!queue_limits_stack_integrity(limits, &ti_limits)) {
+ DMWARN("%s: adding target device (start sect %llu len %llu) "
+ "disabled integrity support due to incompatibility",
+ dm_device_name(t->md),
+ (unsigned long long) ti->begin,
+ (unsigned long long) ti->len);
+ t->integrity_supported = false;
+ }
+ }
}
/*
@@ -1761,36 +1686,6 @@ int dm_calculate_queue_limits(struct dm_table *t,
return validate_hardware_logical_block_alignment(t, limits);
}
-/*
- * Verify that all devices have an integrity profile that matches the
- * DM device's registered integrity profile. If the profiles don't
- * match then unregister the DM device's integrity profile.
- */
-static void dm_table_verify_integrity(struct dm_table *t)
-{
- struct gendisk *template_disk = NULL;
-
- if (t->integrity_added)
- return;
-
- if (t->integrity_supported) {
- /*
- * Verify that the original integrity profile
- * matches all the devices in this table.
- */
- template_disk = dm_table_get_integrity_disk(t);
- if (template_disk &&
- blk_integrity_compare(dm_disk(t->md), template_disk) >= 0)
- return;
- }
-
- if (integrity_profile_exists(dm_disk(t->md))) {
- DMWARN("%s: unable to establish an integrity profile",
- dm_device_name(t->md));
- blk_integrity_unregister(dm_disk(t->md));
- }
-}
-
static int device_flush_capable(struct dm_target *ti, struct dm_dev *dev,
sector_t start, sector_t len, void *data)
{
@@ -2004,8 +1899,6 @@ int dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
else
blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
- dm_table_verify_integrity(t);
-
/*
* Some devices don't use blk_integrity but still want stable pages
* because they do their own checksumming.
diff --git a/drivers/md/md.c b/drivers/md/md.c
index aff9118ff69750..67ece2cd725f50 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2410,36 +2410,10 @@ static LIST_HEAD(pending_raid_disks);
*/
int md_integrity_register(struct mddev *mddev)
{
- struct md_rdev *rdev, *reference = NULL;
-
if (list_empty(&mddev->disks))
return 0; /* nothing to do */
- if (mddev_is_dm(mddev) || blk_get_integrity(mddev->gendisk))
- return 0; /* shouldn't register, or already is */
- rdev_for_each(rdev, mddev) {
- /* skip spares and non-functional disks */
- if (test_bit(Faulty, &rdev->flags))
- continue;
- if (rdev->raid_disk < 0)
- continue;
- if (!reference) {
- /* Use the first rdev as the reference */
- reference = rdev;
- continue;
- }
- /* does this rdev's profile match the reference profile? */
- if (blk_integrity_compare(reference->bdev->bd_disk,
- rdev->bdev->bd_disk) < 0)
- return -EINVAL;
- }
- if (!reference || !bdev_get_integrity(reference->bdev))
- return 0;
- /*
- * All component devices are integrity capable and have matching
- * profiles, register the common profile for the md device.
- */
- blk_integrity_register(mddev->gendisk,
- bdev_get_integrity(reference->bdev));
+ if (mddev_is_dm(mddev) || !blk_get_integrity(mddev->gendisk))
+ return 0; /* shouldn't register */
pr_debug("md: data integrity enabled on %s\n", mdname(mddev));
if (bioset_integrity_create(&mddev->bio_set, BIO_POOL_SIZE) ||
@@ -2459,32 +2433,6 @@ int md_integrity_register(struct mddev *mddev)
}
EXPORT_SYMBOL(md_integrity_register);
-/*
- * Attempt to add an rdev, but only if it is consistent with the current
- * integrity profile
- */
-int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev)
-{
- struct blk_integrity *bi_mddev;
-
- if (mddev_is_dm(mddev))
- return 0;
-
- bi_mddev = blk_get_integrity(mddev->gendisk);
-
- if (!bi_mddev) /* nothing to do */
- return 0;
-
- if (blk_integrity_compare(mddev->gendisk, rdev->bdev->bd_disk) != 0) {
- pr_err("%s: incompatible integrity profile for %pg\n",
- mdname(mddev), rdev->bdev);
- return -ENXIO;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(md_integrity_add_rdev);
-
static bool rdev_read_only(struct md_rdev *rdev)
{
return bdev_read_only(rdev->bdev) ||
@@ -5755,14 +5703,20 @@ static const struct kobj_type md_ktype = {
int mdp_major = 0;
/* stack the limit for all rdevs into lim */
-void mddev_stack_rdev_limits(struct mddev *mddev, struct queue_limits *lim)
+int mddev_stack_rdev_limits(struct mddev *mddev, struct queue_limits *lim,
+ unsigned int flags)
{
struct md_rdev *rdev;
rdev_for_each(rdev, mddev) {
queue_limits_stack_bdev(lim, rdev->bdev, rdev->data_offset,
mddev->gendisk->disk_name);
+ if ((flags & MDDEV_STACK_INTEGRITY) &&
+ !queue_limits_stack_integrity_bdev(lim, rdev->bdev))
+ return -EINVAL;
}
+
+ return 0;
}
EXPORT_SYMBOL_GPL(mddev_stack_rdev_limits);
@@ -5777,6 +5731,14 @@ int mddev_stack_new_rdev(struct mddev *mddev, struct md_rdev *rdev)
lim = queue_limits_start_update(mddev->gendisk->queue);
queue_limits_stack_bdev(&lim, rdev->bdev, rdev->data_offset,
mddev->gendisk->disk_name);
+
+ if (!queue_limits_stack_integrity_bdev(&lim, rdev->bdev)) {
+ pr_err("%s: incompatible integrity profile for %pg\n",
+ mdname(mddev), rdev->bdev);
+ queue_limits_cancel_update(mddev->gendisk->queue);
+ return -ENXIO;
+ }
+
return queue_limits_commit_update(mddev->gendisk->queue, &lim);
}
EXPORT_SYMBOL_GPL(mddev_stack_new_rdev);
diff --git a/drivers/md/md.h b/drivers/md/md.h
index ca085ecad50449..6733b0b0abf999 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -809,7 +809,6 @@ extern void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev);
extern void md_set_array_sectors(struct mddev *mddev, sector_t array_sectors);
extern int md_check_no_bitmap(struct mddev *mddev);
extern int md_integrity_register(struct mddev *mddev);
-extern int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev);
extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale);
extern int mddev_init(struct mddev *mddev);
@@ -908,7 +907,9 @@ void md_autostart_arrays(int part);
int md_set_array_info(struct mddev *mddev, struct mdu_array_info_s *info);
int md_add_new_disk(struct mddev *mddev, struct mdu_disk_info_s *info);
int do_md_run(struct mddev *mddev);
-void mddev_stack_rdev_limits(struct mddev *mddev, struct queue_limits *lim);
+#define MDDEV_STACK_INTEGRITY (1u << 0)
+int mddev_stack_rdev_limits(struct mddev *mddev, struct queue_limits *lim,
+ unsigned int flags);
int mddev_stack_new_rdev(struct mddev *mddev, struct md_rdev *rdev);
void mddev_update_io_opt(struct mddev *mddev, unsigned int nr_stripes);
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 81c01347cd24e6..62634e2a33bd0f 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -377,13 +377,18 @@ static void raid0_free(struct mddev *mddev, void *priv)
static int raid0_set_limits(struct mddev *mddev)
{
struct queue_limits lim;
+ int err;
blk_set_stacking_limits(&lim);
lim.max_hw_sectors = mddev->chunk_sectors;
lim.max_write_zeroes_sectors = mddev->chunk_sectors;
lim.io_min = mddev->chunk_sectors << 9;
lim.io_opt = lim.io_min * mddev->raid_disks;
- mddev_stack_rdev_limits(mddev, &lim);
+ err = mddev_stack_rdev_limits(mddev, &lim, MDDEV_STACK_INTEGRITY);
+ if (err) {
+ queue_limits_cancel_update(mddev->gendisk->queue);
+ return err;
+ }
return queue_limits_set(mddev->gendisk->queue, &lim);
}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 1f321826ef02ba..779cad62f6f8c0 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1907,9 +1907,6 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
if (mddev->recovery_disabled == conf->recovery_disabled)
return -EBUSY;
- if (md_integrity_add_rdev(rdev, mddev))
- return -ENXIO;
-
if (rdev->raid_disk >= 0)
first = last = rdev->raid_disk;
@@ -3197,10 +3194,15 @@ static struct r1conf *setup_conf(struct mddev *mddev)
static int raid1_set_limits(struct mddev *mddev)
{
struct queue_limits lim;
+ int err;
blk_set_stacking_limits(&lim);
lim.max_write_zeroes_sectors = 0;
- mddev_stack_rdev_limits(mddev, &lim);
+ err = mddev_stack_rdev_limits(mddev, &lim, MDDEV_STACK_INTEGRITY);
+ if (err) {
+ queue_limits_cancel_update(mddev->gendisk->queue);
+ return err;
+ }
return queue_limits_set(mddev->gendisk->queue, &lim);
}
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index a4556d2e46bf95..5f6885b53b691a 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2083,9 +2083,6 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)
if (rdev->saved_raid_disk < 0 && !_enough(conf, 1, -1))
return -EINVAL;
- if (md_integrity_add_rdev(rdev, mddev))
- return -ENXIO;
-
if (rdev->raid_disk >= 0)
first = last = rdev->raid_disk;
@@ -3980,12 +3977,17 @@ static int raid10_set_queue_limits(struct mddev *mddev)
{
struct r10conf *conf = mddev->private;
struct queue_limits lim;
+ int err;
blk_set_stacking_limits(&lim);
lim.max_write_zeroes_sectors = 0;
lim.io_min = mddev->chunk_sectors << 9;
lim.io_opt = lim.io_min * raid10_nr_stripes(conf);
- mddev_stack_rdev_limits(mddev, &lim);
+ err = mddev_stack_rdev_limits(mddev, &lim, MDDEV_STACK_INTEGRITY);
+ if (err) {
+ queue_limits_cancel_update(mddev->gendisk->queue);
+ return err;
+ }
return queue_limits_set(mddev->gendisk->queue, &lim);
}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 2bd1ce9b39226a..675c68fa6c6403 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -7708,7 +7708,7 @@ static int raid5_set_limits(struct mddev *mddev)
lim.raid_partial_stripes_expensive = 1;
lim.discard_granularity = stripe;
lim.max_write_zeroes_sectors = 0;
- mddev_stack_rdev_limits(mddev, &lim);
+ mddev_stack_rdev_limits(mddev, &lim, 0);
rdev_for_each(rdev, mddev)
queue_limits_stack_bdev(&lim, rdev->bdev, rdev->new_data_offset,
mddev->gendisk->disk_name);
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index 1e5aedaf8c7bd9..c5f8451b494d6c 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -1504,6 +1504,11 @@ static int btt_blk_init(struct btt *btt)
};
int rc;
+ if (btt_meta_size(btt) && IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY)) {
+ lim.integrity.tuple_size = btt_meta_size(btt);
+ lim.integrity.tag_size = btt_meta_size(btt);
+ }
+
btt->btt_disk = blk_alloc_disk(&lim, NUMA_NO_NODE);
if (IS_ERR(btt->btt_disk))
return PTR_ERR(btt->btt_disk);
@@ -1516,14 +1521,6 @@ static int btt_blk_init(struct btt *btt)
blk_queue_flag_set(QUEUE_FLAG_NONROT, btt->btt_disk->queue);
blk_queue_flag_set(QUEUE_FLAG_SYNCHRONOUS, btt->btt_disk->queue);
- if (btt_meta_size(btt) && IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY)) {
- struct blk_integrity bi = {
- .tuple_size = btt_meta_size(btt),
- .tag_size = btt_meta_size(btt),
- };
- blk_integrity_register(btt->btt_disk, &bi);
- }
-
set_capacity(btt->btt_disk, btt->nlba * btt->sector_size >> 9);
rc = device_add_disk(&btt->nd_btt->dev, btt->btt_disk, NULL);
if (rc)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 14bac248cde4ca..5a673fa5cb2612 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1723,11 +1723,12 @@ int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo)
return 0;
}
-static bool nvme_init_integrity(struct gendisk *disk, struct nvme_ns_head *head)
+static bool nvme_init_integrity(struct gendisk *disk, struct nvme_ns_head *head,
+ struct queue_limits *lim)
{
- struct blk_integrity integrity = { };
+ struct blk_integrity *bi = &lim->integrity;
- blk_integrity_unregister(disk);
+ memset(bi, 0, sizeof(*bi));
if (!head->ms)
return true;
@@ -1744,14 +1745,14 @@ static bool nvme_init_integrity(struct gendisk *disk, struct nvme_ns_head *head)
case NVME_NS_DPS_PI_TYPE3:
switch (head->guard_type) {
case NVME_NVM_NS_16B_GUARD:
- integrity.csum_type = BLK_INTEGRITY_CSUM_CRC;
- integrity.tag_size = sizeof(u16) + sizeof(u32);
- integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
+ bi->csum_type = BLK_INTEGRITY_CSUM_CRC;
+ bi->tag_size = sizeof(u16) + sizeof(u32);
+ bi->flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
break;
case NVME_NVM_NS_64B_GUARD:
- integrity.csum_type = BLK_INTEGRITY_CSUM_CRC64;
- integrity.tag_size = sizeof(u16) + 6;
- integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
+ bi->csum_type = BLK_INTEGRITY_CSUM_CRC64;
+ bi->tag_size = sizeof(u16) + 6;
+ bi->flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
break;
default:
break;
@@ -1761,16 +1762,16 @@ static bool nvme_init_integrity(struct gendisk *disk, struct nvme_ns_head *head)
case NVME_NS_DPS_PI_TYPE2:
switch (head->guard_type) {
case NVME_NVM_NS_16B_GUARD:
- integrity.csum_type = BLK_INTEGRITY_CSUM_CRC;
- integrity.tag_size = sizeof(u16);
- integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE |
- BLK_INTEGRITY_REF_TAG;
+ bi->csum_type = BLK_INTEGRITY_CSUM_CRC;
+ bi->tag_size = sizeof(u16);
+ bi->flags |= BLK_INTEGRITY_DEVICE_CAPABLE |
+ BLK_INTEGRITY_REF_TAG;
break;
case NVME_NVM_NS_64B_GUARD:
- integrity.csum_type = BLK_INTEGRITY_CSUM_CRC64;
- integrity.tag_size = sizeof(u16);
- integrity.flags |= BLK_INTEGRITY_DEVICE_CAPABLE |
- BLK_INTEGRITY_REF_TAG;
+ bi->csum_type = BLK_INTEGRITY_CSUM_CRC64;
+ bi->tag_size = sizeof(u16);
+ bi->flags |= BLK_INTEGRITY_DEVICE_CAPABLE |
+ BLK_INTEGRITY_REF_TAG;
break;
default:
break;
@@ -1780,9 +1781,8 @@ static bool nvme_init_integrity(struct gendisk *disk, struct nvme_ns_head *head)
break;
}
- integrity.tuple_size = head->ms;
- integrity.pi_offset = head->pi_offset;
- blk_integrity_register(disk, &integrity);
+ bi->tuple_size = head->ms;
+ bi->pi_offset = head->pi_offset;
return true;
}
@@ -2105,11 +2105,6 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
ns->head->ids.csi == NVME_CSI_ZNS)
nvme_update_zone_info(ns, &lim, &zi);
- ret = queue_limits_commit_update(ns->disk->queue, &lim);
- if (ret) {
- blk_mq_unfreeze_queue(ns->disk->queue);
- goto out;
- }
/*
* Register a metadata profile for PI, or the plain non-integrity NVMe
@@ -2117,9 +2112,15 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
* I/O to namespaces with metadata except when the namespace supports
* PI, as it can strip/insert in that case.
*/
- if (!nvme_init_integrity(ns->disk, ns->head))
+ if (!nvme_init_integrity(ns->disk, ns->head, &lim))
capacity = 0;
+ ret = queue_limits_commit_update(ns->disk->queue, &lim);
+ if (ret) {
+ blk_mq_unfreeze_queue(ns->disk->queue);
+ goto out;
+ }
+
set_capacity_and_notify(ns->disk, capacity);
/*
@@ -2191,14 +2192,6 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
struct queue_limits lim;
blk_mq_freeze_queue(ns->head->disk->queue);
- if (unsupported)
- ns->head->disk->flags |= GENHD_FL_HIDDEN;
- else
- nvme_init_integrity(ns->head->disk, ns->head);
- set_capacity_and_notify(ns->head->disk, get_capacity(ns->disk));
- set_disk_ro(ns->head->disk, nvme_ns_is_readonly(ns, info));
- nvme_mpath_revalidate_paths(ns);
-
/*
* queue_limits mixes values that are the hardware limitations
* for bio splitting with what is the device configuration.
@@ -2221,7 +2214,16 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
lim.io_opt = ns_lim->io_opt;
queue_limits_stack_bdev(&lim, ns->disk->part0, 0,
ns->head->disk->disk_name);
+ if (unsupported)
+ ns->head->disk->flags |= GENHD_FL_HIDDEN;
+ else
+ nvme_init_integrity(ns->head->disk, ns->head, &lim);
ret = queue_limits_commit_update(ns->head->disk->queue, &lim);
+
+ set_capacity_and_notify(ns->head->disk, get_capacity(ns->disk));
+ set_disk_ro(ns->head->disk, nvme_ns_is_readonly(ns, info));
+ nvme_mpath_revalidate_paths(ns);
+
blk_mq_unfreeze_queue(ns->head->disk->queue);
}
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 67f24607b862a3..85b45345a27739 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -799,7 +799,7 @@ static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
unsigned int dix, unsigned int dif)
{
struct request *rq = scsi_cmd_to_rq(scmd);
- struct blk_integrity *bi = &rq->q->integrity;
+ struct blk_integrity *bi = &rq->q->limits.integrity;
unsigned int prot_op = sd_prot_op(rq_data_dir(rq), dix, dif);
unsigned int protect = 0;
@@ -2474,11 +2474,13 @@ static int sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer
return 0;
}
-static void sd_config_protection(struct scsi_disk *sdkp)
+static void sd_config_protection(struct scsi_disk *sdkp,
+ struct queue_limits *lim)
{
struct scsi_device *sdp = sdkp->device;
- sd_dif_config_host(sdkp);
+ if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY))
+ sd_dif_config_host(sdkp, lim);
if (!sdkp->protection_type)
return;
@@ -3669,7 +3671,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
sd_read_app_tag_own(sdkp, buffer);
sd_read_write_same(sdkp, buffer);
sd_read_security(sdkp, buffer);
- sd_config_protection(sdkp);
+ sd_config_protection(sdkp, &lim);
}
/*
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index b4170b17bad47a..726f1613f6cb56 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -220,17 +220,7 @@ static inline sector_t sectors_to_logical(struct scsi_device *sdev, sector_t sec
return sector >> (ilog2(sdev->sector_size) - 9);
}
-#ifdef CONFIG_BLK_DEV_INTEGRITY
-
-extern void sd_dif_config_host(struct scsi_disk *);
-
-#else /* CONFIG_BLK_DEV_INTEGRITY */
-
-static inline void sd_dif_config_host(struct scsi_disk *disk)
-{
-}
-
-#endif /* CONFIG_BLK_DEV_INTEGRITY */
+void sd_dif_config_host(struct scsi_disk *sdkp, struct queue_limits *lim);
static inline int sd_is_zoned(struct scsi_disk *sdkp)
{
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index 6f0921c7db787b..4c1c0595f2d1fc 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -24,55 +24,50 @@
/*
* Configure exchange of protection information between OS and HBA.
*/
-void sd_dif_config_host(struct scsi_disk *sdkp)
+void sd_dif_config_host(struct scsi_disk *sdkp, struct queue_limits *lim)
{
struct scsi_device *sdp = sdkp->device;
- struct gendisk *disk = sdkp->disk;
u8 type = sdkp->protection_type;
- struct blk_integrity bi;
+ struct blk_integrity *bi = &lim->integrity;
int dif, dix;
+ memset(bi, 0, sizeof(*bi));
+
dif = scsi_host_dif_capable(sdp->host, type);
dix = scsi_host_dix_capable(sdp->host, type);
if (!dix && scsi_host_dix_capable(sdp->host, 0)) {
- dif = 0; dix = 1;
+ dif = 0;
+ dix = 1;
}
- if (!dix) {
- blk_integrity_unregister(disk);
+ 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)
- bi.csum_type = BLK_INTEGRITY_CSUM_IP;
+ bi->csum_type = BLK_INTEGRITY_CSUM_IP;
else
- bi.csum_type = BLK_INTEGRITY_CSUM_CRC;
+ bi->csum_type = BLK_INTEGRITY_CSUM_CRC;
if (type != T10_PI_TYPE3_PROTECTION)
- bi.flags |= BLK_INTEGRITY_REF_TAG;
+ bi->flags |= BLK_INTEGRITY_REF_TAG;
- bi.tuple_size = sizeof(struct t10_pi_tuple);
+ bi->tuple_size = sizeof(struct t10_pi_tuple);
if (dif && type) {
- bi.flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
+ bi->flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
if (!sdkp->ATO)
- goto out;
+ return;
if (type == T10_PI_TYPE3_PROTECTION)
- bi.tag_size = sizeof(u16) + sizeof(u32);
+ bi->tag_size = sizeof(u16) + sizeof(u32);
else
- bi.tag_size = sizeof(u16);
+ bi->tag_size = sizeof(u16);
}
sd_first_printk(KERN_NOTICE, sdkp,
"Enabling DIX %s, application tag size %u bytes\n",
- blk_integrity_profile_name(&bi), bi.tag_size);
-out:
- blk_integrity_register(disk, &bi);
+ blk_integrity_profile_name(bi), bi->tag_size);
}
-
diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h
index a4bf2c78776c06..4aa679cace1739 100644
--- a/include/linux/blk-integrity.h
+++ b/include/linux/blk-integrity.h
@@ -11,6 +11,7 @@ enum blk_integrity_flags {
BLK_INTEGRITY_NOGENERATE = 1 << 1,
BLK_INTEGRITY_DEVICE_CAPABLE = 1 << 2,
BLK_INTEGRITY_REF_TAG = 1 << 3,
+ BLK_INTEGRITY_STACKED = 1 << 4,
};
enum blk_integerity_checksum {
@@ -32,9 +33,7 @@ struct blk_integrity_iter {
const char *blk_integrity_profile_name(struct blk_integrity *bi);
#ifdef CONFIG_BLK_DEV_INTEGRITY
-void blk_integrity_register(struct gendisk *, struct blk_integrity *);
-void blk_integrity_unregister(struct gendisk *);
-int blk_integrity_compare(struct gendisk *, struct gendisk *);
+bool queue_limits_stack_integrity(struct queue_limits *t, struct queue_limits *b);
int blk_rq_map_integrity_sg(struct request_queue *, struct bio *,
struct scatterlist *);
int blk_rq_count_integrity_sg(struct request_queue *, struct bio *);
@@ -42,14 +41,14 @@ int blk_rq_count_integrity_sg(struct request_queue *, struct bio *);
static inline bool
blk_integrity_queue_supports_integrity(struct request_queue *q)
{
- return q->integrity.tuple_size;
+ return q->limits.integrity.tuple_size;
}
static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk)
{
if (!blk_integrity_queue_supports_integrity(disk->queue))
return NULL;
- return &disk->queue->integrity;
+ return &disk->queue->limits.integrity;
}
static inline struct blk_integrity *
@@ -102,6 +101,11 @@ static inline struct bio_vec *rq_integrity_vec(struct request *rq)
return rq->bio->bi_integrity->bip_vec;
}
#else /* CONFIG_BLK_DEV_INTEGRITY */
+static inline bool queue_limits_stack_integrity(struct queue_limits *t,
+ struct queue_limits *b)
+{
+ return true;
+}
static inline int blk_rq_count_integrity_sg(struct request_queue *q,
struct bio *b)
{
@@ -126,17 +130,6 @@ blk_integrity_queue_supports_integrity(struct request_queue *q)
{
return false;
}
-static inline int blk_integrity_compare(struct gendisk *a, struct gendisk *b)
-{
- return 0;
-}
-static inline void blk_integrity_register(struct gendisk *d,
- struct blk_integrity *b)
-{
-}
-static inline void blk_integrity_unregister(struct gendisk *d)
-{
-}
static inline unsigned short
queue_max_integrity_segments(const struct request_queue *q)
{
@@ -164,4 +157,11 @@ static inline struct bio_vec *rq_integrity_vec(struct request *rq)
return NULL;
}
#endif /* CONFIG_BLK_DEV_INTEGRITY */
+
+static inline bool queue_limits_stack_integrity_bdev(struct queue_limits *t,
+ struct block_device *bdev)
+{
+ return queue_limits_stack_integrity(t, &bdev->bd_disk->queue->limits);
+}
+
#endif /* _LINUX_BLK_INTEGRITY_H */
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 150910a4d4e6ae..1102d822021928 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -327,6 +327,8 @@ struct queue_limits {
* due to possible offsets.
*/
unsigned int dma_alignment;
+
+ struct blk_integrity integrity;
};
typedef int (*report_zones_cb)(struct blk_zone *zone, unsigned int idx,
@@ -412,10 +414,6 @@ struct request_queue {
struct queue_limits limits;
-#ifdef CONFIG_BLK_DEV_INTEGRITY
- struct blk_integrity integrity;
-#endif /* CONFIG_BLK_DEV_INTEGRITY */
-
#ifdef CONFIG_PM
struct device *dev;
enum rpm_status rpm_status;
@@ -1293,11 +1291,10 @@ static inline bool bdev_stable_writes(struct block_device *bdev)
{
struct request_queue *q = bdev_get_queue(bdev);
-#ifdef CONFIG_BLK_DEV_INTEGRITY
/* BLK_INTEGRITY_CSUM_NONE is not available in blkdev.h */
- if (q->integrity.csum_type != 0)
+ if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) &&
+ q->limits.integrity.csum_type != 0)
return true;
-#endif
return test_bit(QUEUE_FLAG_STABLE_WRITES, &q->queue_flags);
}
diff --git a/include/linux/t10-pi.h b/include/linux/t10-pi.h
index d2bafb76badfb9..1773610010ebaf 100644
--- a/include/linux/t10-pi.h
+++ b/include/linux/t10-pi.h
@@ -39,12 +39,8 @@ struct t10_pi_tuple {
static inline u32 t10_pi_ref_tag(struct request *rq)
{
- unsigned int shift = ilog2(queue_logical_block_size(rq->q));
+ unsigned int shift = rq->q->limits.integrity.interval_exp;
-#ifdef CONFIG_BLK_DEV_INTEGRITY
- if (rq->q->integrity.interval_exp)
- shift = rq->q->integrity.interval_exp;
-#endif
return blk_rq_pos(rq) >> (shift - SECTOR_SHIFT) & 0xffffffff;
}
@@ -65,12 +61,8 @@ static inline u64 lower_48_bits(u64 n)
static inline u64 ext_pi_ref_tag(struct request *rq)
{
- unsigned int shift = ilog2(queue_logical_block_size(rq->q));
+ unsigned int shift = rq->q->limits.integrity.interval_exp;
-#ifdef CONFIG_BLK_DEV_INTEGRITY
- if (rq->q->integrity.interval_exp)
- shift = rq->q->integrity.interval_exp;
-#endif
return lower_48_bits(blk_rq_pos(rq) >> (shift - SECTOR_SHIFT));
}
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [PATCH 04/12] block: remove the blk_integrity_profile structure
2024-06-05 6:28 ` [PATCH 04/12] block: remove the blk_integrity_profile structure Christoph Hellwig
@ 2024-06-05 14:35 ` Kanchan Joshi
2024-06-06 4:49 ` Christoph Hellwig
2024-06-05 16:31 ` Bart Van Assche
1 sibling, 1 reply; 34+ messages in thread
From: Kanchan Joshi @ 2024-06-05 14:35 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jens Axboe, Martin K. Petersen, Mike Snitzer, Mikulas Patocka,
Song Liu, Yu Kuai, Dan Williams, Vishal Verma, Dave Jiang,
Ira Weiny, Keith Busch, Sagi Grimberg, Chaitanya Kulkarni,
linux-block, dm-devel, linux-raid, nvdimm, linux-nvme, linux-scsi
On Wed, Jun 5, 2024 at 12:01 PM Christoph Hellwig <hch@lst.de> wrote:
> @@ -446,13 +446,14 @@ bool bio_integrity_prep(struct bio *bio)
> if (bio_integrity(bio))
> return true;
>
> + if (!bi->csum_type)
> + return true;
Changes look mostly good, but trigger a behavior change for non-PI
metadata format.
Earlier nop profile was registered for that case. And the block-layer
continued to attach an appropriately sized meta buffer to incoming IO, even
though it did not generate/verify. Hence, IOs don't fail.
Now also we show that the nop profile is set, but the above
"csum_type" check ensures that
meta buffer is not attached and REQ_INTEGRITY is not set in the bio.
NVMe will start failing IOs with BLK_STS_NOTSUPP now [*].
[*]
if (!blk_integrity_rq(req)) {
if (WARN_ON_ONCE(!nvme_ns_has_pi(ns->head)))
return BLK_STS_NOTSUPP;
control |= NVME_RW_PRINFO_PRACT;
}
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 01/12] dm-integrity: use the nop integrity profile
2024-06-05 6:28 ` [PATCH 01/12] dm-integrity: use the nop integrity profile Christoph Hellwig
@ 2024-06-05 14:52 ` Milan Broz
2024-06-06 4:45 ` Christoph Hellwig
2024-06-06 0:12 ` Chaitanya Kulkarni
1 sibling, 1 reply; 34+ messages in thread
From: Milan Broz @ 2024-06-05 14:52 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
On 6/5/24 8:28 AM, Christoph Hellwig wrote:
> Use the block layer built-in nop profile instead of reinventing it.
As this is my "invention", I am pretty sure that "nop" profile was
not available at the time I was prototyping AEAD dmcrypt extension.
(It was months before we submitted it upstream - and then nobody
apparently fixed it.)
So, I am quite happy this hack can go away!
I run full cryptsetup testuite with this patch and everything
works, nice cleanup.
Reviewed-by: Milan Broz <gmazyland@gmail.com>
Thanks,
Milan
>
> Tested by:
>
> $ dd if=/dev/urandom of=key.bin bs=512 count=1
>
> $ cryptsetup luksFormat -q --type luks2 --integrity hmac-sha256 \
> --integrity-no-wipe /dev/nvme0n1 key.bin
> $ cryptsetup luksOpen /dev/nvme0n1 luks-integrity --key-file key.bin
>
> and then doing mkfs.xfs and simple I/O on the mount file system.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> drivers/md/dm-crypt.c | 4 ++--
> drivers/md/dm-integrity.c | 20 --------------------
> 2 files changed, 2 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
> index 1b7a97cc377943..1dfc462f29cd6f 100644
> --- a/drivers/md/dm-crypt.c
> +++ b/drivers/md/dm-crypt.c
> @@ -1176,8 +1176,8 @@ static int crypt_integrity_ctr(struct crypt_config *cc, struct dm_target *ti)
> struct blk_integrity *bi = blk_get_integrity(cc->dev->bdev->bd_disk);
> struct mapped_device *md = dm_table_get_md(ti->table);
>
> - /* From now we require underlying device with our integrity profile */
> - if (!bi || strcasecmp(bi->profile->name, "DM-DIF-EXT-TAG")) {
> + /* We require an underlying device with non-PI metadata */
> + if (!bi || strcmp(bi->profile->name, "nop")) {
> ti->error = "Integrity profile not supported.";
> return -EINVAL;
> }
> diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
> index 417fddebe367a2..c1cc27541673c7 100644
> --- a/drivers/md/dm-integrity.c
> +++ b/drivers/md/dm-integrity.c
> @@ -350,25 +350,6 @@ static struct kmem_cache *journal_io_cache;
> #define DEBUG_bytes(bytes, len, msg, ...) do { } while (0)
> #endif
>
> -static void dm_integrity_prepare(struct request *rq)
> -{
> -}
> -
> -static void dm_integrity_complete(struct request *rq, unsigned int nr_bytes)
> -{
> -}
> -
> -/*
> - * DM Integrity profile, protection is performed layer above (dm-crypt)
> - */
> -static const struct blk_integrity_profile dm_integrity_profile = {
> - .name = "DM-DIF-EXT-TAG",
> - .generate_fn = NULL,
> - .verify_fn = NULL,
> - .prepare_fn = dm_integrity_prepare,
> - .complete_fn = dm_integrity_complete,
> -};
> -
> static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map);
> static void integrity_bio_wait(struct work_struct *w);
> static void dm_integrity_dtr(struct dm_target *ti);
> @@ -3656,7 +3637,6 @@ static void dm_integrity_set(struct dm_target *ti, struct dm_integrity_c *ic)
> struct blk_integrity bi;
>
> memset(&bi, 0, sizeof(bi));
> - bi.profile = &dm_integrity_profile;
> bi.tuple_size = ic->tag_size;
> bi.tag_size = bi.tuple_size;
> bi.interval_exp = ic->sb->log2_sectors_per_block + SECTOR_SHIFT;
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 06/12] block: factor out flag_{store,show} helper for integrity
2024-06-05 6:28 ` [PATCH 06/12] block: factor out flag_{store,show} helper for integrity Christoph Hellwig
@ 2024-06-05 16:00 ` Keith Busch
2024-06-06 0:16 ` Chaitanya Kulkarni
1 sibling, 0 replies; 34+ messages in thread
From: Keith Busch @ 2024-06-05 16:00 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jens Axboe, Martin K. Petersen, Mike Snitzer, Mikulas Patocka,
Song Liu, Yu Kuai, Dan Williams, Vishal Verma, Dave Jiang,
Ira Weiny, Sagi Grimberg, Chaitanya Kulkarni, linux-block,
dm-devel, linux-raid, nvdimm, linux-nvme, linux-scsi
On Wed, Jun 05, 2024 at 08:28:35AM +0200, Christoph Hellwig wrote:
> Factor the duplicate code for the generate and verify attributes into
> common helpers.
Looks good.
Reviewed-by: Keith Busch <kbusch@kernel.org>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 07/12] block: use kstrtoul in flag_store
2024-06-05 6:28 ` [PATCH 07/12] block: use kstrtoul in flag_store Christoph Hellwig
@ 2024-06-05 16:00 ` Keith Busch
2024-06-06 0:16 ` Chaitanya Kulkarni
1 sibling, 0 replies; 34+ messages in thread
From: Keith Busch @ 2024-06-05 16:00 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jens Axboe, Martin K. Petersen, Mike Snitzer, Mikulas Patocka,
Song Liu, Yu Kuai, Dan Williams, Vishal Verma, Dave Jiang,
Ira Weiny, Sagi Grimberg, Chaitanya Kulkarni, linux-block,
dm-devel, linux-raid, nvdimm, linux-nvme, linux-scsi
On Wed, Jun 05, 2024 at 08:28:36AM +0200, Christoph Hellwig wrote:
> Use the text to integer helper that has error handling and doesn't modify
> the input pointer.
Looks good.
Reviewed-by: Keith Busch <kbusch@kernel.org>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 02/12] block: remove the unused BIP_{CTRL,DISK}_NOCHECK flags
2024-06-05 6:28 ` [PATCH 02/12] block: remove the unused BIP_{CTRL,DISK}_NOCHECK flags Christoph Hellwig
@ 2024-06-05 16:16 ` Bart Van Assche
2024-06-05 23:31 ` Kanchan Joshi
2024-06-06 0:13 ` Chaitanya Kulkarni
2 siblings, 0 replies; 34+ messages in thread
From: Bart Van Assche @ 2024-06-05 16:16 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
On 6/5/24 00:28, Christoph Hellwig wrote:
> Both flags are only checked, but never set.
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 03/12] block: remove the BIP_IP_CHECKSUM flag
2024-06-05 6:28 ` [PATCH 03/12] block: remove the BIP_IP_CHECKSUM flag Christoph Hellwig
@ 2024-06-05 16:21 ` Bart Van Assche
2024-06-05 23:31 ` Kanchan Joshi
2024-06-06 0:14 ` Chaitanya Kulkarni
2 siblings, 0 replies; 34+ messages in thread
From: Bart Van Assche @ 2024-06-05 16:21 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
On 6/5/24 00:28, Christoph Hellwig wrote:
> Remove the BIP_IP_CHECKSUM as sd can just look at the per-disk
> checksum type instead.
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 04/12] block: remove the blk_integrity_profile structure
2024-06-05 6:28 ` [PATCH 04/12] block: remove the blk_integrity_profile structure Christoph Hellwig
2024-06-05 14:35 ` Kanchan Joshi
@ 2024-06-05 16:31 ` Bart Van Assche
2024-06-06 4:50 ` Christoph Hellwig
1 sibling, 1 reply; 34+ messages in thread
From: Bart Van Assche @ 2024-06-05 16:31 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
On 6/5/24 00:28, Christoph Hellwig wrote:
> +const char *blk_integrity_profile_name(struct blk_integrity *bi)
> +{
> + switch (bi->csum_type) {
> + case BLK_INTEGRITY_CSUM_IP:
> + if (bi->flags & BLK_INTEGRITY_REF_TAG)
> + return "T10-DIF-TYPE1-IP";
> + return "T10-DIF-TYPE3-IP";
> + case BLK_INTEGRITY_CSUM_CRC:
> + if (bi->flags & BLK_INTEGRITY_REF_TAG)
> + return "T10-DIF-TYPE1-CRC";
> + return "T10-DIF-TYPE3-CRC";
> + case BLK_INTEGRITY_CSUM_CRC64:
> + if (bi->flags & BLK_INTEGRITY_REF_TAG)
> + return "EXT-DIF-TYPE1-CRC64";
> + return "EXT-DIF-TYPE3-CRC64";
> + default:
> + return "nop";
> + }
> +}
Since bi->csum_type has an enumeration type, please leave out the "default:"
and move return "nop" outside the switch statement. This will make the
compiler issue a warning if a new enumeration label would be added without
updating the above switch statement. Otherwise this patch looks good to me.
Thanks,
Bart.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 12/12] block: move integrity information into queue_limits
2024-06-05 6:28 ` [PATCH 12/12] block: move integrity information into queue_limits Christoph Hellwig
@ 2024-06-05 16:56 ` Bart Van Assche
2024-06-06 4:51 ` Christoph Hellwig
0 siblings, 1 reply; 34+ messages in thread
From: Bart Van Assche @ 2024-06-05 16:56 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
On 6/5/24 00:28, Christoph Hellwig wrote:
> if (!dix && scsi_host_dix_capable(sdp->host, 0)) {
> - dif = 0; dix = 1;
> + dif = 0;
> + dix = 1;
> }
Although the above change looks fine to me, it is unrelated to the
other changes in this patch?
Thanks,
Bart.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 02/12] block: remove the unused BIP_{CTRL,DISK}_NOCHECK flags
2024-06-05 6:28 ` [PATCH 02/12] block: remove the unused BIP_{CTRL,DISK}_NOCHECK flags Christoph Hellwig
2024-06-05 16:16 ` Bart Van Assche
@ 2024-06-05 23:31 ` Kanchan Joshi
2024-06-06 0:13 ` Chaitanya Kulkarni
2 siblings, 0 replies; 34+ messages in thread
From: Kanchan Joshi @ 2024-06-05 23:31 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jens Axboe, Martin K. Petersen, Mike Snitzer, Mikulas Patocka,
Song Liu, Yu Kuai, Dan Williams, Vishal Verma, Dave Jiang,
Ira Weiny, Keith Busch, Sagi Grimberg, Chaitanya Kulkarni,
linux-block, dm-devel, linux-raid, nvdimm, linux-nvme, linux-scsi
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 03/12] block: remove the BIP_IP_CHECKSUM flag
2024-06-05 6:28 ` [PATCH 03/12] block: remove the BIP_IP_CHECKSUM flag Christoph Hellwig
2024-06-05 16:21 ` Bart Van Assche
@ 2024-06-05 23:31 ` Kanchan Joshi
2024-06-06 0:14 ` Chaitanya Kulkarni
2 siblings, 0 replies; 34+ messages in thread
From: Kanchan Joshi @ 2024-06-05 23:31 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jens Axboe, Martin K. Petersen, Mike Snitzer, Mikulas Patocka,
Song Liu, Yu Kuai, Dan Williams, Vishal Verma, Dave Jiang,
Ira Weiny, Keith Busch, Sagi Grimberg, Chaitanya Kulkarni,
linux-block, dm-devel, linux-raid, nvdimm, linux-nvme, linux-scsi
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 01/12] dm-integrity: use the nop integrity profile
2024-06-05 6:28 ` [PATCH 01/12] dm-integrity: use the nop integrity profile Christoph Hellwig
2024-06-05 14:52 ` Milan Broz
@ 2024-06-06 0:12 ` Chaitanya Kulkarni
1 sibling, 0 replies; 34+ messages in thread
From: Chaitanya Kulkarni @ 2024-06-06 0:12 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block@vger.kernel.org,
dm-devel@lists.linux.dev, linux-raid@vger.kernel.org,
nvdimm@lists.linux.dev, linux-nvme@lists.infradead.org,
linux-scsi@vger.kernel.org
On 6/4/2024 11:28 PM, Christoph Hellwig wrote:
> Use the block layer built-in nop profile instead of reinventing it.
>
> Tested by:
>
> $ dd if=/dev/urandom of=key.bin bs=512 count=1
>
> $ cryptsetup luksFormat -q --type luks2 --integrity hmac-sha256 \
> --integrity-no-wipe /dev/nvme0n1 key.bin
> $ cryptsetup luksOpen /dev/nvme0n1 luks-integrity --key-file key.bin
>
> and then doing mkfs.xfs and simple I/O on the mount file system.
>
> Signed-off-by: Christoph Hellwig<hch@lst.de>
Looks good.
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
-ck
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 02/12] block: remove the unused BIP_{CTRL,DISK}_NOCHECK flags
2024-06-05 6:28 ` [PATCH 02/12] block: remove the unused BIP_{CTRL,DISK}_NOCHECK flags Christoph Hellwig
2024-06-05 16:16 ` Bart Van Assche
2024-06-05 23:31 ` Kanchan Joshi
@ 2024-06-06 0:13 ` Chaitanya Kulkarni
2 siblings, 0 replies; 34+ messages in thread
From: Chaitanya Kulkarni @ 2024-06-06 0:13 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block@vger.kernel.org,
dm-devel@lists.linux.dev, linux-raid@vger.kernel.org,
nvdimm@lists.linux.dev, linux-nvme@lists.infradead.org,
linux-scsi@vger.kernel.org
On 6/4/2024 11:28 PM, Christoph Hellwig wrote:
> Both flags are only checked, but never set.
>
> Signed-off-by: Christoph Hellwig<hch@lst.de>
Looks good.
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
-ck
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 03/12] block: remove the BIP_IP_CHECKSUM flag
2024-06-05 6:28 ` [PATCH 03/12] block: remove the BIP_IP_CHECKSUM flag Christoph Hellwig
2024-06-05 16:21 ` Bart Van Assche
2024-06-05 23:31 ` Kanchan Joshi
@ 2024-06-06 0:14 ` Chaitanya Kulkarni
2 siblings, 0 replies; 34+ messages in thread
From: Chaitanya Kulkarni @ 2024-06-06 0:14 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block@vger.kernel.org,
dm-devel@lists.linux.dev, linux-raid@vger.kernel.org,
nvdimm@lists.linux.dev, linux-nvme@lists.infradead.org,
linux-scsi@vger.kernel.org
On 6/4/2024 11:28 PM, Christoph Hellwig wrote:
> Remove the BIP_IP_CHECKSUM as sd can just look at the per-disk
> checksum type instead.
>
> Signed-off-by: Christoph Hellwig<hch@lst.de>
Looks good.
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
-ck
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 06/12] block: factor out flag_{store,show} helper for integrity
2024-06-05 6:28 ` [PATCH 06/12] block: factor out flag_{store,show} helper for integrity Christoph Hellwig
2024-06-05 16:00 ` Keith Busch
@ 2024-06-06 0:16 ` Chaitanya Kulkarni
1 sibling, 0 replies; 34+ messages in thread
From: Chaitanya Kulkarni @ 2024-06-06 0:16 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block@vger.kernel.org,
dm-devel@lists.linux.dev, linux-raid@vger.kernel.org,
nvdimm@lists.linux.dev, linux-nvme@lists.infradead.org,
linux-scsi@vger.kernel.org
On 6/4/2024 11:28 PM, Christoph Hellwig wrote:
> Factor the duplicate code for the generate and verify attributes into
> common helpers.
>
> Signed-off-by: Christoph Hellwig<hch@lst.de>
Looks good.
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
-ck
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 07/12] block: use kstrtoul in flag_store
2024-06-05 6:28 ` [PATCH 07/12] block: use kstrtoul in flag_store Christoph Hellwig
2024-06-05 16:00 ` Keith Busch
@ 2024-06-06 0:16 ` Chaitanya Kulkarni
1 sibling, 0 replies; 34+ messages in thread
From: Chaitanya Kulkarni @ 2024-06-06 0:16 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block@vger.kernel.org,
dm-devel@lists.linux.dev, linux-raid@vger.kernel.org,
nvdimm@lists.linux.dev, linux-nvme@lists.infradead.org,
linux-scsi@vger.kernel.org
On 6/4/2024 11:28 PM, Christoph Hellwig wrote:
> Use the text to integer helper that has error handling and doesn't modify
> the input pointer.
>
> Signed-off-by: Christoph Hellwig<hch@lst.de>
Looks good.
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
-ck
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 11/12] block: invert the BLK_INTEGRITY_{GENERATE,VERIFY} flags
2024-06-05 6:28 ` [PATCH 11/12] block: invert the BLK_INTEGRITY_{GENERATE,VERIFY} flags Christoph Hellwig
@ 2024-06-06 0:20 ` Chaitanya Kulkarni
0 siblings, 0 replies; 34+ messages in thread
From: Chaitanya Kulkarni @ 2024-06-06 0:20 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Martin K. Petersen
Cc: Mike Snitzer, Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block@vger.kernel.org,
dm-devel@lists.linux.dev, linux-raid@vger.kernel.org,
nvdimm@lists.linux.dev, linux-nvme@lists.infradead.org,
linux-scsi@vger.kernel.org
On 6/4/2024 11:28 PM, Christoph Hellwig wrote:
> Invert the flags so that user set values will be able to persist
> revalidating the integrity information once we switch the integrity
> information to queue_limits.
>
> Signed-off-by: Christoph Hellwig<hch@lst.de>
Looks good.
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
-ck
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 01/12] dm-integrity: use the nop integrity profile
2024-06-05 14:52 ` Milan Broz
@ 2024-06-06 4:45 ` Christoph Hellwig
0 siblings, 0 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-06 4:45 UTC (permalink / raw)
To: Milan Broz
Cc: Christoph Hellwig, Jens Axboe, Martin K. Petersen, Mike Snitzer,
Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams, Vishal Verma,
Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
On Wed, Jun 05, 2024 at 04:52:27PM +0200, Milan Broz wrote:
> On 6/5/24 8:28 AM, Christoph Hellwig wrote:
>> Use the block layer built-in nop profile instead of reinventing it.
>
> As this is my "invention", I am pretty sure that "nop" profile was
> not available at the time I was prototyping AEAD dmcrypt extension.
> (It was months before we submitted it upstream - and then nobody
> apparently fixed it.)
Looking at the history the nop profile was moved from nvme to common
code to also support btt in 2015, dm-integrity was added in 2017.
So maybe you just missed it. Anyway, I'm also happy to tone this
down a bit, it sounds a bit too aggressive..
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 04/12] block: remove the blk_integrity_profile structure
2024-06-05 14:35 ` Kanchan Joshi
@ 2024-06-06 4:49 ` Christoph Hellwig
0 siblings, 0 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-06 4:49 UTC (permalink / raw)
To: Kanchan Joshi
Cc: Christoph Hellwig, Jens Axboe, Martin K. Petersen, Mike Snitzer,
Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams, Vishal Verma,
Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
On Wed, Jun 05, 2024 at 08:05:20PM +0530, Kanchan Joshi wrote:
> On Wed, Jun 5, 2024 at 12:01???PM Christoph Hellwig <hch@lst.de> wrote:
> > @@ -446,13 +446,14 @@ bool bio_integrity_prep(struct bio *bio)
> > if (bio_integrity(bio))
> > return true;
> >
> > + if (!bi->csum_type)
> > + return true;
>
> Changes look mostly good, but trigger a behavior change for non-PI
> metadata format.
>
> Earlier nop profile was registered for that case. And the block-layer
> continued to attach an appropriately sized meta buffer to incoming IO, even
> though it did not generate/verify. Hence, IOs don't fail.
>
> Now also we show that the nop profile is set, but the above
> "csum_type" check ensures that
> meta buffer is not attached and REQ_INTEGRITY is not set in the bio.
> NVMe will start failing IOs with BLK_STS_NOTSUPP now [*].
Yes. I didn't remember that odd case and failed to test it, but I can
trivially reproduce it now.
Which brings up another issue: bio_integrity_prep allocates the metadata
buffer using kmalloc, so we'll leak write random kernel memory to the
devices for this case which is ... not good. I guess for stable fixes
and backports I'll add a real generate_fn that just zeroes all the
memory for now.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 04/12] block: remove the blk_integrity_profile structure
2024-06-05 16:31 ` Bart Van Assche
@ 2024-06-06 4:50 ` Christoph Hellwig
2024-06-06 15:38 ` Bart Van Assche
0 siblings, 1 reply; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-06 4:50 UTC (permalink / raw)
To: Bart Van Assche
Cc: Christoph Hellwig, Jens Axboe, Martin K. Petersen, Mike Snitzer,
Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams, Vishal Verma,
Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
On Wed, Jun 05, 2024 at 10:31:27AM -0600, Bart Van Assche wrote:
>> + case BLK_INTEGRITY_CSUM_CRC64:
>> + if (bi->flags & BLK_INTEGRITY_REF_TAG)
>> + return "EXT-DIF-TYPE1-CRC64";
>> + return "EXT-DIF-TYPE3-CRC64";
>> + default:
>> + return "nop";
>> + }
>> +}
>
> Since bi->csum_type has an enumeration type, please leave out the "default:"
> and move return "nop" outside the switch statement. This will make the
> compiler issue a warning if a new enumeration label would be added without
> updating the above switch statement. Otherwise this patch looks good to me.
For that to work you'd need to make csum_type the enum type and not an
unsigned char, which would bloat the block limits. You'd also need to
keep the return "nop" where it is, but use the explicit case instead of
the default.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 12/12] block: move integrity information into queue_limits
2024-06-05 16:56 ` Bart Van Assche
@ 2024-06-06 4:51 ` Christoph Hellwig
0 siblings, 0 replies; 34+ messages in thread
From: Christoph Hellwig @ 2024-06-06 4:51 UTC (permalink / raw)
To: Bart Van Assche
Cc: Christoph Hellwig, Jens Axboe, Martin K. Petersen, Mike Snitzer,
Mikulas Patocka, Song Liu, Yu Kuai, Dan Williams, Vishal Verma,
Dave Jiang, Ira Weiny, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, linux-block, dm-devel, linux-raid, nvdimm,
linux-nvme, linux-scsi
On Wed, Jun 05, 2024 at 10:56:20AM -0600, Bart Van Assche wrote:
> On 6/5/24 00:28, Christoph Hellwig wrote:
>> if (!dix && scsi_host_dix_capable(sdp->host, 0)) {
>> - dif = 0; dix = 1;
>> + dif = 0;
>> + dix = 1;
>> }
>
> Although the above change looks fine to me, it is unrelated to the
> other changes in this patch?
Yes. And earlier version touched this more extensible and this is what
is left of that.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 04/12] block: remove the blk_integrity_profile structure
2024-06-06 4:50 ` Christoph Hellwig
@ 2024-06-06 15:38 ` Bart Van Assche
0 siblings, 0 replies; 34+ messages in thread
From: Bart Van Assche @ 2024-06-06 15:38 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jens Axboe, Martin K. Petersen, Mike Snitzer, Mikulas Patocka,
Song Liu, Yu Kuai, Dan Williams, Vishal Verma, Dave Jiang,
Ira Weiny, Keith Busch, Sagi Grimberg, Chaitanya Kulkarni,
linux-block, dm-devel, linux-raid, nvdimm, linux-nvme, linux-scsi
On 6/5/24 22:50, Christoph Hellwig wrote:
> On Wed, Jun 05, 2024 at 10:31:27AM -0600, Bart Van Assche wrote:
>>> + case BLK_INTEGRITY_CSUM_CRC64:
>>> + if (bi->flags & BLK_INTEGRITY_REF_TAG)
>>> + return "EXT-DIF-TYPE1-CRC64";
>>> + return "EXT-DIF-TYPE3-CRC64";
>>> + default:
>>> + return "nop";
>>> + }
>>> +}
>>
>> Since bi->csum_type has an enumeration type, please leave out the "default:"
>> and move return "nop" outside the switch statement. This will make the
>> compiler issue a warning if a new enumeration label would be added without
>> updating the above switch statement. Otherwise this patch looks good to me.
>
> For that to work you'd need to make csum_type the enum type and not an
> unsigned char, which would bloat the block limits. You'd also need to
> keep the return "nop" where it is, but use the explicit case instead of
> the default.
Has it been considered to add __packed to the definition of enum
blk_integerity_checksum such that its size changes from 4 to 1 bytes and to
change "unsigned char csum_type" into "enum blk_integerity csum_type"?
Thanks,
Bart.
^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2024-06-06 15:38 UTC | newest]
Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-05 6:28 move integrity settings to queue_limits Christoph Hellwig
2024-06-05 6:28 ` [PATCH 01/12] dm-integrity: use the nop integrity profile Christoph Hellwig
2024-06-05 14:52 ` Milan Broz
2024-06-06 4:45 ` Christoph Hellwig
2024-06-06 0:12 ` Chaitanya Kulkarni
2024-06-05 6:28 ` [PATCH 02/12] block: remove the unused BIP_{CTRL,DISK}_NOCHECK flags Christoph Hellwig
2024-06-05 16:16 ` Bart Van Assche
2024-06-05 23:31 ` Kanchan Joshi
2024-06-06 0:13 ` Chaitanya Kulkarni
2024-06-05 6:28 ` [PATCH 03/12] block: remove the BIP_IP_CHECKSUM flag Christoph Hellwig
2024-06-05 16:21 ` Bart Van Assche
2024-06-05 23:31 ` Kanchan Joshi
2024-06-06 0:14 ` Chaitanya Kulkarni
2024-06-05 6:28 ` [PATCH 04/12] block: remove the blk_integrity_profile structure Christoph Hellwig
2024-06-05 14:35 ` Kanchan Joshi
2024-06-06 4:49 ` Christoph Hellwig
2024-06-05 16:31 ` Bart Van Assche
2024-06-06 4:50 ` Christoph Hellwig
2024-06-06 15:38 ` Bart Van Assche
2024-06-05 6:28 ` [PATCH 05/12] block: remove the blk_flush_integrity call in blk_integrity_unregister Christoph Hellwig
2024-06-05 6:28 ` [PATCH 06/12] block: factor out flag_{store,show} helper for integrity Christoph Hellwig
2024-06-05 16:00 ` Keith Busch
2024-06-06 0:16 ` Chaitanya Kulkarni
2024-06-05 6:28 ` [PATCH 07/12] block: use kstrtoul in flag_store Christoph Hellwig
2024-06-05 16:00 ` Keith Busch
2024-06-06 0:16 ` Chaitanya Kulkarni
2024-06-05 6:28 ` [PATCH 08/12] block: don't pretend to generate/verify for non-PI metadata Christoph Hellwig
2024-06-05 6:28 ` [PATCH 09/12] block: don't require stable pages " Christoph Hellwig
2024-06-05 6:28 ` [PATCH 10/12] block: bypass the STABLE_WRITES flag for protection information Christoph Hellwig
2024-06-05 6:28 ` [PATCH 11/12] block: invert the BLK_INTEGRITY_{GENERATE,VERIFY} flags Christoph Hellwig
2024-06-06 0:20 ` Chaitanya Kulkarni
2024-06-05 6:28 ` [PATCH 12/12] block: move integrity information into queue_limits Christoph Hellwig
2024-06-05 16:56 ` Bart Van Assche
2024-06-06 4:51 ` Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).