[SCSI] iscsi: Some fixes in preparation for bidirectional support - exp_datasn
authorMike Christie <michaelc@cs.wisc.edu>
Wed, 30 May 2007 17:57:14 +0000 (12:57 -0500)
committerJames Bottomley <jejb@mulgrave.(none)>
Fri, 1 Jun 2007 16:57:17 +0000 (12:57 -0400)
This patch fixes handling of expected datasn/r2tsn as received from
target. It is done according to: T10 rfc3720 section 3.2.2.3. Data Sequencing.

. unify expected datasn/r2tsn into one counter
. calculate than check expected datasn/r2tsn. On error print a message
  and fail the request. (TODO use iscsi retransmits)
. remove the FIXME   ;)
. avoid zero length memset

Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/iscsi_tcp.c
drivers/scsi/iscsi_tcp.h
drivers/scsi/libiscsi.c
include/scsi/libiscsi.h

index 8201e6c4d8a961c0a755b61b02f49116a0ee8756..17fc79c408a2c1b37ffd8acfe3c8d966e596223d 100644 (file)
@@ -229,10 +229,13 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        if (tcp_conn->in.datalen == 0)
                return 0;
 
-       if (ctask->datasn != datasn)
+       if (tcp_ctask->exp_datasn != datasn) {
+               debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->datasn(%d)\n",
+                         __FUNCTION__, tcp_ctask->exp_datasn, datasn);
                return ISCSI_ERR_DATASN;
+       }
 
-       ctask->datasn++;
+       tcp_ctask->exp_datasn++;
 
        tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
        if (tcp_ctask->data_offset + tcp_conn->in.datalen > ctask->total_length)
@@ -365,15 +368,16 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
                return ISCSI_ERR_DATALEN;
        }
 
-       if (tcp_ctask->exp_r2tsn && tcp_ctask->exp_r2tsn != r2tsn)
+       if (tcp_ctask->exp_datasn != r2tsn){
+               debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->r2tsn(%d)\n",
+                         __FUNCTION__, tcp_ctask->exp_datasn, r2tsn);
                return ISCSI_ERR_R2TSN;
+       }
 
        rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
        if (rc)
                return rc;
 
-       /* FIXME: use R2TSN to detect missing R2T */
-
        /* fill-in new R2T associated with the task */
        spin_lock(&session->lock);
        if (!ctask->sc || ctask->mtask ||
@@ -414,7 +418,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
 
        iscsi_solicit_data_init(conn, ctask, r2t);
 
-       tcp_ctask->exp_r2tsn = r2tsn + 1;
+       tcp_ctask->exp_datasn = r2tsn + 1;
        __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
        tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
        list_move_tail(&ctask->running, &conn->xmitqueue);
@@ -1284,10 +1288,10 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
 
        tcp_ctask->sent = 0;
        tcp_ctask->sg_count = 0;
+       tcp_ctask->exp_datasn = 0;
 
        if (sc->sc_data_direction == DMA_TO_DEVICE) {
                tcp_ctask->xmstate = XMSTATE_W_HDR;
-               tcp_ctask->exp_r2tsn = 0;
                BUG_ON(ctask->total_length == 0);
 
                if (sc->use_sg) {
index 32736831790ec773ebc66a9931be2edf94912717..f909edbf61ee014115fa25b8dbfed29a02df59dd 100644 (file)
@@ -152,7 +152,7 @@ struct iscsi_tcp_cmd_task {
        struct scatterlist      *sg;                    /* per-cmd SG list  */
        struct scatterlist      *bad_sg;                /* assert statement */
        int                     sg_count;               /* SG's to process  */
-       uint32_t                exp_r2tsn;
+       uint32_t                exp_datasn;             /* expected target's R2TSN/DataSN */
        int                     data_offset;
        struct iscsi_r2t_info   *r2t;                   /* in progress R2T    */
        struct iscsi_queue      r2tpool;
index 5e6a42429c39ee9b1bde05717f46bb02cfd5b16b..eb51136079585880f318c002b11a087392779bd5 100644 (file)
@@ -120,7 +120,9 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
         session->cmdsn++;
         hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
         memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
-        memset(&hdr->cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len);
+       if (sc->cmd_len < MAX_COMMAND_SIZE)
+               memset(&hdr->cdb[sc->cmd_len], 0,
+                       MAX_COMMAND_SIZE - sc->cmd_len);
 
        ctask->data_count = 0;
        if (sc->sc_data_direction == DMA_TO_DEVICE) {
@@ -165,7 +167,6 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
                        /* No unsolicit Data-Out's */
                        ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL;
        } else {
-               ctask->datasn = 0;
                hdr->flags |= ISCSI_FLAG_CMD_FINAL;
                zero_data(hdr->dlength);
 
index deae90a56a0dee661b20315c20876952a7acde85..61e069206ac5dd4237683d0ddb5ace20163b4ae3 100644 (file)
@@ -99,7 +99,6 @@ struct iscsi_cmd_task {
         */
        struct iscsi_cmd        *hdr;
        int                     itt;            /* this ITT */
-       int                     datasn;         /* DataSN */
 
        uint32_t                unsol_datasn;
        int                     imm_count;      /* imm-data (bytes)   */