target/sbc: Add sbc_dif_read_strip software emulation
authorNicholas Bellinger <nab@linux-iscsi.org>
Wed, 2 Apr 2014 21:34:11 +0000 (14:34 -0700)
committerNicholas Bellinger <nab@linux-iscsi.org>
Mon, 7 Apr 2014 08:48:57 +0000 (01:48 -0700)
Split up __sbc_dif_verify_read() so that VERIFY READ emulation can
perform target-core specific READ_STRIP, seperate from the existing
FILEIO/RAMDISK backend emulation code.

Also add sbc_dif_read_strip() in order to determine number of sectors
using cmd->prot_length, and skip the extra sbc_dif_copy_prot().

Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Quinn Tran <quinn.tran@qlogic.com>
Cc: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/target_core_sbc.c
include/target/target_core_backend.h

index cc8c0ba539304b904223f280ee9cac82c94cc776..e0229592ec5509656aed292970af719be1f9111d 100644 (file)
@@ -1271,9 +1271,9 @@ sbc_dif_verify_write(struct se_cmd *cmd, sector_t start, unsigned int sectors,
 }
 EXPORT_SYMBOL(sbc_dif_verify_write);
 
-sense_reason_t
-sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors,
-                   unsigned int ei_lba, struct scatterlist *sg, int sg_off)
+static sense_reason_t
+__sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors,
+                     unsigned int ei_lba, struct scatterlist *sg, int sg_off)
 {
        struct se_device *dev = cmd->se_dev;
        struct se_dif_v1_tuple *sdt;
@@ -1326,8 +1326,31 @@ sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors,
                kunmap_atomic(paddr);
                kunmap_atomic(daddr);
        }
-       sbc_dif_copy_prot(cmd, sectors, true, sg, sg_off);
 
        return 0;
 }
+
+sense_reason_t
+sbc_dif_read_strip(struct se_cmd *cmd)
+{
+       struct se_device *dev = cmd->se_dev;
+       u32 sectors = cmd->prot_length / dev->prot_length;
+
+       return __sbc_dif_verify_read(cmd, cmd->t_task_lba, sectors, 0,
+                                    cmd->t_prot_sg, 0);
+}
+
+sense_reason_t
+sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors,
+                   unsigned int ei_lba, struct scatterlist *sg, int sg_off)
+{
+       sense_reason_t rc;
+
+       rc = __sbc_dif_verify_read(cmd, start, sectors, ei_lba, sg, sg_off);
+       if (rc)
+               return rc;
+
+       sbc_dif_copy_prot(cmd, sectors, true, sg, sg_off);
+       return 0;
+}
 EXPORT_SYMBOL(sbc_dif_verify_read);
index 0a36c6cb93b2fd58db4495a10df50ed323677c08..3a1c1eea1fffcaee767d4bef1a8ea2700f1884e2 100644 (file)
@@ -78,6 +78,7 @@ sense_reason_t        sbc_dif_verify_write(struct se_cmd *, sector_t, unsigned int,
                                     unsigned int, struct scatterlist *, int);
 sense_reason_t sbc_dif_verify_read(struct se_cmd *, sector_t, unsigned int,
                                    unsigned int, struct scatterlist *, int);
+sense_reason_t sbc_dif_read_strip(struct se_cmd *);
 
 void   transport_set_vpd_proto_id(struct t10_vpd *, unsigned char *);
 int    transport_set_vpd_assoc(struct t10_vpd *, unsigned char *);