libiscsi, iser: Adjust data_length to include protection information
authorSagi Grimberg <sagig@mellanox.com>
Wed, 11 Jun 2014 09:09:58 +0000 (12:09 +0300)
committerNicholas Bellinger <nab@linux-iscsi.org>
Wed, 11 Jun 2014 20:06:45 +0000 (13:06 -0700)
In case protection information exists over the wire
iscsi header data length is required to include it.
Use protection information aware scsi helpers to set
the correct transfer length.

In order to avoid breakage, remove iser transfer length
checks for each task as they are not always true and
somewhat redundant anyway.

Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Acked-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: stable@vger.kernel.org # 3.15+
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/infiniband/ulp/iser/iser_initiator.c
drivers/scsi/libiscsi.c

index 2e2d903db838f75e6105a88f875de8acf3667162..8d44a4060634c084971f6755aa246ff384c9a40a 100644 (file)
 #include "iscsi_iser.h"
 
 /* Register user buffer memory and initialize passive rdma
- *  dto descriptor. Total data size is stored in
- *  iser_task->data[ISER_DIR_IN].data_len
+ *  dto descriptor. Data size is stored in
+ *  task->data[ISER_DIR_IN].data_len, Protection size
+ *  os stored in task->prot[ISER_DIR_IN].data_len
  */
-static int iser_prepare_read_cmd(struct iscsi_task *task,
-                                unsigned int edtl)
+static int iser_prepare_read_cmd(struct iscsi_task *task)
 
 {
        struct iscsi_iser_task *iser_task = task->dd_data;
@@ -73,14 +73,6 @@ static int iser_prepare_read_cmd(struct iscsi_task *task,
                        return err;
        }
 
-       if (edtl > iser_task->data[ISER_DIR_IN].data_len) {
-               iser_err("Total data length: %ld, less than EDTL: "
-                        "%d, in READ cmd BHS itt: %d, conn: 0x%p\n",
-                        iser_task->data[ISER_DIR_IN].data_len, edtl,
-                        task->itt, iser_task->ib_conn);
-               return -EINVAL;
-       }
-
        err = device->iser_reg_rdma_mem(iser_task, ISER_DIR_IN);
        if (err) {
                iser_err("Failed to set up Data-IN RDMA\n");
@@ -100,8 +92,9 @@ static int iser_prepare_read_cmd(struct iscsi_task *task,
 }
 
 /* Register user buffer memory and initialize passive rdma
- *  dto descriptor. Total data size is stored in
- *  task->data[ISER_DIR_OUT].data_len
+ *  dto descriptor. Data size is stored in
+ *  task->data[ISER_DIR_OUT].data_len, Protection size
+ *  is stored at task->prot[ISER_DIR_OUT].data_len
  */
 static int
 iser_prepare_write_cmd(struct iscsi_task *task,
@@ -135,14 +128,6 @@ iser_prepare_write_cmd(struct iscsi_task *task,
                        return err;
        }
 
-       if (edtl > iser_task->data[ISER_DIR_OUT].data_len) {
-               iser_err("Total data length: %ld, less than EDTL: %d, "
-                        "in WRITE cmd BHS itt: %d, conn: 0x%p\n",
-                        iser_task->data[ISER_DIR_OUT].data_len,
-                        edtl, task->itt, task->conn);
-               return -EINVAL;
-       }
-
        err = device->iser_reg_rdma_mem(iser_task, ISER_DIR_OUT);
        if (err != 0) {
                iser_err("Failed to register write cmd RDMA mem\n");
@@ -417,11 +402,12 @@ int iser_send_command(struct iscsi_conn *conn,
        if (scsi_prot_sg_count(sc)) {
                prot_buf->buf  = scsi_prot_sglist(sc);
                prot_buf->size = scsi_prot_sg_count(sc);
-               prot_buf->data_len = sc->prot_sdb->length;
+               prot_buf->data_len = data_buf->data_len >>
+                                    ilog2(sc->device->sector_size) * 8;
        }
 
        if (hdr->flags & ISCSI_FLAG_CMD_READ) {
-               err = iser_prepare_read_cmd(task, edtl);
+               err = iser_prepare_read_cmd(task);
                if (err)
                        goto send_command_error;
        }
index 26dc005bb0f0f347eeecf2d4d0cb335912d55ee5..3f462349b16c8589185b1d1155fab8718f37d5dc 100644 (file)
@@ -338,7 +338,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
        struct iscsi_session *session = conn->session;
        struct scsi_cmnd *sc = task->sc;
        struct iscsi_scsi_req *hdr;
-       unsigned hdrlength, cmd_len;
+       unsigned hdrlength, cmd_len, transfer_length;
        itt_t itt;
        int rc;
 
@@ -391,11 +391,11 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
        if (scsi_get_prot_op(sc) != SCSI_PROT_NORMAL)
                task->protected = true;
 
+       transfer_length = scsi_transfer_length(sc);
+       hdr->data_length = cpu_to_be32(transfer_length);
        if (sc->sc_data_direction == DMA_TO_DEVICE) {
-               unsigned out_len = scsi_out(sc)->length;
                struct iscsi_r2t_info *r2t = &task->unsol_r2t;
 
-               hdr->data_length = cpu_to_be32(out_len);
                hdr->flags |= ISCSI_FLAG_CMD_WRITE;
                /*
                 * Write counters:
@@ -414,18 +414,19 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
                memset(r2t, 0, sizeof(*r2t));
 
                if (session->imm_data_en) {
-                       if (out_len >= session->first_burst)
+                       if (transfer_length >= session->first_burst)
                                task->imm_count = min(session->first_burst,
                                                        conn->max_xmit_dlength);
                        else
-                               task->imm_count = min(out_len,
-                                                       conn->max_xmit_dlength);
+                               task->imm_count = min(transfer_length,
+                                                     conn->max_xmit_dlength);
                        hton24(hdr->dlength, task->imm_count);
                } else
                        zero_data(hdr->dlength);
 
                if (!session->initial_r2t_en) {
-                       r2t->data_length = min(session->first_burst, out_len) -
+                       r2t->data_length = min(session->first_burst,
+                                              transfer_length) -
                                               task->imm_count;
                        r2t->data_offset = task->imm_count;
                        r2t->ttt = cpu_to_be32(ISCSI_RESERVED_TAG);
@@ -438,7 +439,6 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
        } else {
                hdr->flags |= ISCSI_FLAG_CMD_FINAL;
                zero_data(hdr->dlength);
-               hdr->data_length = cpu_to_be32(scsi_in(sc)->length);
 
                if (sc->sc_data_direction == DMA_FROM_DEVICE)
                        hdr->flags |= ISCSI_FLAG_CMD_READ;
@@ -466,7 +466,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
                          scsi_bidi_cmnd(sc) ? "bidirectional" :
                          sc->sc_data_direction == DMA_TO_DEVICE ?
                          "write" : "read", conn->id, sc, sc->cmnd[0],
-                         task->itt, scsi_bufflen(sc),
+                         task->itt, transfer_length,
                          scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0,
                          session->cmdsn,
                          session->max_cmdsn - session->exp_cmdsn + 1);