summaryrefslogtreecommitdiff
path: root/drivers/scsi/sd_dif.c
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2014-09-26 19:20:08 -0400
committerJens Axboe <axboe@fb.com>2014-09-30 15:17:35 -0600
commitc611529e7cd3465ec0eada0f44200e8420c38908 (patch)
treec1cbfbd9b3229906ec36c897761d06e1521823bd /drivers/scsi/sd_dif.c
parent582940508b5d589229d0232e0eeee8fef0d54809 (diff)
sd: Honor block layer integrity handling flags
A set of flags introduced in the block layer enable better control over how protection information is handled. These flags are useful for both error injection and data recovery purposes. Checking can be enabled and disabled for controller and disk, and the guard tag format is now a per-I/O property. Update sd_protect_op to communicate the relevant information to the low-level device driver via a set of flags in scsi_cmnd. Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Sagi Grimberg <sagig@mellanox.com> Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/scsi/sd_dif.c')
-rw-r--r--drivers/scsi/sd_dif.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index b7eaeadc18f9..14c7d42a11c2 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -106,8 +106,7 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
*
* Type 3 does not have a reference tag so no remapping is required.
*/
-void sd_dif_prepare(struct request *rq, sector_t hw_sector,
- unsigned int sector_sz)
+void sd_dif_prepare(struct scsi_cmnd *scmd)
{
const int tuple_sz = sizeof(struct t10_pi_tuple);
struct bio *bio;
@@ -115,14 +114,14 @@ void sd_dif_prepare(struct request *rq, sector_t hw_sector,
struct t10_pi_tuple *pi;
u32 phys, virt;
- sdkp = rq->bio->bi_bdev->bd_disk->private_data;
+ sdkp = scsi_disk(scmd->request->rq_disk);
if (sdkp->protection_type == SD_DIF_TYPE3_PROTECTION)
return;
- phys = hw_sector & 0xffffffff;
+ phys = scsi_prot_ref_tag(scmd);
- __rq_for_each_bio(bio, rq) {
+ __rq_for_each_bio(bio, scmd->request) {
struct bio_integrity_payload *bip = bio_integrity(bio);
struct bio_vec iv;
struct bvec_iter iter;
@@ -163,7 +162,7 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
struct scsi_disk *sdkp;
struct bio *bio;
struct t10_pi_tuple *pi;
- unsigned int j, sectors, sector_sz;
+ unsigned int j, intervals;
u32 phys, virt;
sdkp = scsi_disk(scmd->request->rq_disk);
@@ -171,12 +170,8 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
if (sdkp->protection_type == SD_DIF_TYPE3_PROTECTION || good_bytes == 0)
return;
- sector_sz = scmd->device->sector_size;
- sectors = good_bytes / sector_sz;
-
- phys = blk_rq_pos(scmd->request) & 0xffffffff;
- if (sector_sz == 4096)
- phys >>= 3;
+ intervals = good_bytes / scsi_prot_interval(scmd);
+ phys = scsi_prot_ref_tag(scmd);
__rq_for_each_bio(bio, scmd->request) {
struct bio_integrity_payload *bip = bio_integrity(bio);
@@ -190,7 +185,7 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
for (j = 0; j < iv.bv_len; j += tuple_sz, pi++) {
- if (sectors == 0) {
+ if (intervals == 0) {
kunmap_atomic(pi);
return;
}
@@ -200,7 +195,7 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
virt++;
phys++;
- sectors--;
+ intervals--;
}
kunmap_atomic(pi);