]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
target: Allow sbc_ops->execute_rw() to accept SGLs + data_direction
authorNicholas Bellinger <nab@daterainc.com>
Tue, 20 Aug 2013 06:57:30 +0000 (23:57 -0700)
committerNicholas Bellinger <nab@linux-iscsi.org>
Mon, 9 Sep 2013 21:29:28 +0000 (14:29 -0700)
COMPARE_AND_WRITE expects to be able to send down a DMA_FROM_DEVICE
to obtain the necessary READ payload for comparision against the
first half of the WRITE payload containing the verify user data.

Currently virtual backends expect to internally reference SGLs,
SGL nents, and data_direction, so change IBLOCK, FILEIO and RD
sbc_ops->execute_rw() to accept this values as function parameters.

Also add default sbc_execute_rw() handler for the typical case for
cmd->execute_rw() submission using cmd->t_data_sg, cmd->t_data_nents,
and cmd->data_direction).

v2 Changes:
  - Add SCF_COMPARE_AND_WRITE command flag
  - Use sbc_execute_rw() for normal cmd->execute_rw() submission
    with expected se_cmd members.

Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Chris Mason <chris.mason@fusionio.com>
Cc: James Bottomley <JBottomley@Parallels.com>
Cc: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Nicholas Bellinger <nab@daterainc.com>
drivers/target/target_core_file.c
drivers/target/target_core_iblock.c
drivers/target/target_core_rd.c
drivers/target/target_core_sbc.c
include/target/target_core_backend.h
include/target/target_core_base.h

index bc3245dfcdf767d8da3b7ccaf3c0a7b08115834d..c5448a5d8b73ceecc3d962bfc11d641106c79e05 100644 (file)
@@ -547,11 +547,9 @@ fd_execute_unmap(struct se_cmd *cmd)
 }
 
 static sense_reason_t
-fd_execute_rw(struct se_cmd *cmd)
+fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
+             enum dma_data_direction data_direction)
 {
-       struct scatterlist *sgl = cmd->t_data_sg;
-       u32 sgl_nents = cmd->t_data_nents;
-       enum dma_data_direction data_direction = cmd->data_direction;
        struct se_device *dev = cmd->se_dev;
        int ret = 0;
 
index 0a460f3350ebca5c217bbbe0e82bcdaf6b66fb4e..81464eb59f0c3fb7bae8bfbc4aeb44aac09a0a20 100644 (file)
@@ -587,11 +587,9 @@ static ssize_t iblock_show_configfs_dev_params(struct se_device *dev, char *b)
 }
 
 static sense_reason_t
-iblock_execute_rw(struct se_cmd *cmd)
+iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
+                 enum dma_data_direction data_direction)
 {
-       struct scatterlist *sgl = cmd->t_data_sg;
-       u32 sgl_nents = cmd->t_data_nents;
-       enum dma_data_direction data_direction = cmd->data_direction;
        struct se_device *dev = cmd->se_dev;
        struct iblock_req *ibr;
        struct bio *bio;
index 51127d15d5c5accd6e39a8c408ef35a0f521db2f..958d17ad1c9059049d31a830b2d2b5465843e4bd 100644 (file)
@@ -280,11 +280,9 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page)
 }
 
 static sense_reason_t
-rd_execute_rw(struct se_cmd *cmd)
+rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
+             enum dma_data_direction data_direction)
 {
-       struct scatterlist *sgl = cmd->t_data_sg;
-       u32 sgl_nents = cmd->t_data_nents;
-       enum dma_data_direction data_direction = cmd->data_direction;
        struct se_device *se_dev = cmd->se_dev;
        struct rd_dev *dev = RD_DEV(se_dev);
        struct rd_dev_sg_table *table;
index be5234abb76c4c4cfb2d274e40f2a887c7b44599..5569b3697103126defd65c8860a97118289cab94 100644 (file)
@@ -337,6 +337,13 @@ static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd)
        return ret;
 }
 
+static sense_reason_t
+sbc_execute_rw(struct se_cmd *cmd)
+{
+       return cmd->execute_rw(cmd, cmd->t_data_sg, cmd->t_data_nents,
+                              cmd->data_direction);
+}
+
 sense_reason_t
 sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
 {
@@ -351,31 +358,36 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
                sectors = transport_get_sectors_6(cdb);
                cmd->t_task_lba = transport_lba_21(cdb);
                cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
-               cmd->execute_cmd = ops->execute_rw;
+               cmd->execute_rw = ops->execute_rw;
+               cmd->execute_cmd = sbc_execute_rw;
                break;
        case READ_10:
                sectors = transport_get_sectors_10(cdb);
                cmd->t_task_lba = transport_lba_32(cdb);
                cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
-               cmd->execute_cmd = ops->execute_rw;
+               cmd->execute_rw = ops->execute_rw;
+               cmd->execute_cmd = sbc_execute_rw;
                break;
        case READ_12:
                sectors = transport_get_sectors_12(cdb);
                cmd->t_task_lba = transport_lba_32(cdb);
                cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
-               cmd->execute_cmd = ops->execute_rw;
+               cmd->execute_rw = ops->execute_rw;
+               cmd->execute_cmd = sbc_execute_rw;
                break;
        case READ_16:
                sectors = transport_get_sectors_16(cdb);
                cmd->t_task_lba = transport_lba_64(cdb);
                cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
-               cmd->execute_cmd = ops->execute_rw;
+               cmd->execute_rw = ops->execute_rw;
+               cmd->execute_cmd = sbc_execute_rw;
                break;
        case WRITE_6:
                sectors = transport_get_sectors_6(cdb);
                cmd->t_task_lba = transport_lba_21(cdb);
                cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
-               cmd->execute_cmd = ops->execute_rw;
+               cmd->execute_rw = ops->execute_rw;
+               cmd->execute_cmd = sbc_execute_rw;
                break;
        case WRITE_10:
        case WRITE_VERIFY:
@@ -384,7 +396,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
                if (cdb[1] & 0x8)
                        cmd->se_cmd_flags |= SCF_FUA;
                cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
-               cmd->execute_cmd = ops->execute_rw;
+               cmd->execute_rw = ops->execute_rw;
+               cmd->execute_cmd = sbc_execute_rw;
                break;
        case WRITE_12:
                sectors = transport_get_sectors_12(cdb);
@@ -392,7 +405,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
                if (cdb[1] & 0x8)
                        cmd->se_cmd_flags |= SCF_FUA;
                cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
-               cmd->execute_cmd = ops->execute_rw;
+               cmd->execute_rw = ops->execute_rw;
+               cmd->execute_cmd = sbc_execute_rw;
                break;
        case WRITE_16:
                sectors = transport_get_sectors_16(cdb);
@@ -400,7 +414,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
                if (cdb[1] & 0x8)
                        cmd->se_cmd_flags |= SCF_FUA;
                cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
-               cmd->execute_cmd = ops->execute_rw;
+               cmd->execute_rw = ops->execute_rw;
+               cmd->execute_cmd = sbc_execute_rw;
                break;
        case XDWRITEREAD_10:
                if (cmd->data_direction != DMA_TO_DEVICE ||
@@ -414,7 +429,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
                /*
                 * Setup BIDI XOR callback to be run after I/O completion.
                 */
-               cmd->execute_cmd = ops->execute_rw;
+               cmd->execute_rw = ops->execute_rw;
+               cmd->execute_cmd = sbc_execute_rw;
                cmd->transport_complete_callback = &xdreadwrite_callback;
                if (cdb[1] & 0x8)
                        cmd->se_cmd_flags |= SCF_FUA;
@@ -437,7 +453,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
                         * Setup BIDI XOR callback to be run during after I/O
                         * completion.
                         */
-                       cmd->execute_cmd = ops->execute_rw;
+                       cmd->execute_rw = ops->execute_rw;
+                       cmd->execute_cmd = sbc_execute_rw;
                        cmd->transport_complete_callback = &xdreadwrite_callback;
                        if (cdb[1] & 0x8)
                                cmd->se_cmd_flags |= SCF_FUA;
index ffa2696d64dcfe9794ec87a83be887b0e2aab453..77f25e0140773dfd92bbb78469bd73017e60e1a4 100644 (file)
@@ -39,7 +39,8 @@ struct se_subsystem_api {
 };
 
 struct sbc_ops {
-       sense_reason_t (*execute_rw)(struct se_cmd *cmd);
+       sense_reason_t (*execute_rw)(struct se_cmd *cmd, struct scatterlist *,
+                                    u32, enum dma_data_direction);
        sense_reason_t (*execute_sync_cache)(struct se_cmd *cmd);
        sense_reason_t (*execute_write_same)(struct se_cmd *cmd);
        sense_reason_t (*execute_write_same_unmap)(struct se_cmd *cmd);
index 3313b7d91ac8aa0e3c2a3168c0b880b97b3fa6f1..4a26a18a24d662c4720cc1dc9532668659c0fc61 100644 (file)
@@ -159,6 +159,8 @@ enum se_cmd_flags_table {
        SCF_ALUA_NON_OPTIMIZED          = 0x00008000,
        SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00020000,
        SCF_ACK_KREF                    = 0x00040000,
+       SCF_COMPARE_AND_WRITE           = 0x00080000,
+       SCF_COMPARE_AND_WRITE_POST      = 0x00100000,
 };
 
 /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */
@@ -448,11 +450,14 @@ struct se_cmd {
        struct kref             cmd_kref;
        struct target_core_fabric_ops *se_tfo;
        sense_reason_t          (*execute_cmd)(struct se_cmd *);
+       sense_reason_t          (*execute_rw)(struct se_cmd *, struct scatterlist *,
+                                             u32, enum dma_data_direction);
        sense_reason_t (*transport_complete_callback)(struct se_cmd *);
 
        unsigned char           *t_task_cdb;
        unsigned char           __t_task_cdb[TCM_MAX_COMMAND_SIZE];
        unsigned long long      t_task_lba;
+       unsigned int            t_task_nolb;
        unsigned int            transport_state;
 #define CMD_T_ABORTED          (1 << 0)
 #define CMD_T_ACTIVE           (1 << 1)