block: Integrity checksum flag
authorMartin K. Petersen <martin.petersen@oracle.com>
Fri, 26 Sep 2014 23:20:05 +0000 (19:20 -0400)
committerJens Axboe <axboe@fb.com>
Sat, 27 Sep 2014 15:14:55 +0000 (09:14 -0600)
Make the choice of checksum a per-I/O property by introducing a flag
that can be inspected by the SCSI layer. There are several reasons for
this:

 1. It allows us to switch choice of checksum without unloading and
    reloading the HBA driver.

 2. During error recovery we need to be able to tell the HBA that
    checksums read from disk should not be verified and converted to IP
    checksums.

 3. For error injection purposes we need to be able to write a bad guard
    tag to storage. Since the storage device only supports T10 CRC we
    need to be able to disable IP checksum conversion on the HBA.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
block/bio-integrity.c
drivers/scsi/sd_dif.c
include/linux/bio.h
include/linux/blkdev.h

index 26aa901b961f853fca946c2ffaa989a21371c26c..8e0548484dd386304dfa0e5714d3fba504eb2240 100644 (file)
@@ -297,6 +297,9 @@ int bio_integrity_prep(struct bio *bio)
        bip->bip_iter.bi_size = len;
        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 ; i++) {
index 4ce636fdc15f9c5305c4128fed53230c5a54e25d..2198abee619eeaebe939b920c01975220efff7ed 100644 (file)
@@ -255,12 +255,14 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
                return;
 
        /* Enable DMA of protection information */
-       if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP)
+       if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) {
                if (type == SD_DIF_TYPE3_PROTECTION)
                        blk_integrity_register(disk, &dif_type3_integrity_ip);
                else
                        blk_integrity_register(disk, &dif_type1_integrity_ip);
-       else
+
+               disk->integrity->flags |= BLK_INTEGRITY_IP_CHECKSUM;
+       } else
                if (type == SD_DIF_TYPE3_PROTECTION)
                        blk_integrity_register(disk, &dif_type3_integrity_crc);
                else
index b508cf69206d7aa073e190ccbf2b3f24da13e9d9..14bff3fe56d4352423c5f96331cdb2a8dd56de7a 100644 (file)
@@ -328,6 +328,7 @@ enum bip_flags {
        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 */
 };
 
 static inline sector_t bip_get_seed(struct bio_integrity_payload *bip)
index 4600fc63e3fc7c017cda89099d999edf6dc995fa..773df190a4eef9b2e82308b107c47b87a2e292f2 100644 (file)
@@ -1462,6 +1462,7 @@ 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,
 };
 
 struct blk_integrity_iter {