[SCSI] libiscsi, iscsi_tcp, iser: add session cmds array accessor
authorMike Christie <michaelc@cs.wisc.edu>
Wed, 21 May 2008 20:54:04 +0000 (15:54 -0500)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Sat, 12 Jul 2008 13:22:18 +0000 (08:22 -0500)
Currently to get a ctask from the session cmd array, you have to
know to use the itt modifier. To make this easier on LLDs and
so in the future we can easilly kill the session array and use
the host shared map instead, this patch adds a nice wrapper
to strip the itt into a session->cmds index and return a ctask.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iser_initiator.c
drivers/scsi/iscsi_tcp.c
drivers/scsi/libiscsi.c
include/scsi/libiscsi.h

index 8a1bfb7277c8a8d5f4141d57c812c1bfa8621edf..7b1468869066e6bb7ce068a0b1d940b31b28c9c4 100644 (file)
@@ -98,7 +98,6 @@ iscsi_iser_recv(struct iscsi_conn *conn,
                struct iscsi_hdr *hdr, char *rx_data, int rx_data_len)
 {
        int rc = 0;
-       uint32_t ret_itt;
        int datalen;
        int ahslen;
 
@@ -114,12 +113,7 @@ iscsi_iser_recv(struct iscsi_conn *conn,
        /* read AHS */
        ahslen = hdr->hlength * 4;
 
-       /* verify itt (itt encoding: age+cid+itt) */
-       rc = iscsi_verify_itt(conn, hdr, &ret_itt);
-
-       if (!rc)
-               rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
-
+       rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
        if (rc && rc != ISCSI_ERR_NO_SCSI_CMD)
                goto error;
 
index 08dc81c46f41eac81f223177ca9f1e50ed64d285..b82a5f2d4d376715393bae7692994fa9b13130b7 100644 (file)
@@ -537,13 +537,11 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
 {
        struct iser_dto        *dto = &rx_desc->dto;
        struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
-       struct iscsi_session *session = conn->iscsi_conn->session;
        struct iscsi_cmd_task *ctask;
        struct iscsi_iser_cmd_task *iser_ctask;
        struct iscsi_hdr *hdr;
        char   *rx_data = NULL;
        int     rx_data_len = 0;
-       unsigned int itt;
        unsigned char opcode;
 
        hdr = &rx_desc->iscsi_header;
@@ -559,19 +557,18 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
        opcode = hdr->opcode & ISCSI_OPCODE_MASK;
 
        if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
-               itt = get_itt(hdr->itt); /* mask out cid and age bits */
-               if (!(itt < session->cmds_max))
+               ctask = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
+               if (!ctask)
                        iser_err("itt can't be matched to task!!! "
-                                "conn %p opcode %d cmds_max %d itt %d\n",
-                                conn->iscsi_conn,opcode,session->cmds_max,itt);
-               /* use the mapping given with the cmds array indexed by itt */
-               ctask = (struct iscsi_cmd_task *)session->cmds[itt];
-               iser_ctask = ctask->dd_data;
-               iser_dbg("itt %d ctask %p\n",itt,ctask);
-               iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
-               iser_ctask_rdma_finalize(iser_ctask);
+                                "conn %p opcode %d itt %d\n",
+                                conn->iscsi_conn, opcode, hdr->itt);
+               else {
+                       iser_ctask = ctask->dd_data;
+                       iser_dbg("itt %d ctask %p\n",hdr->itt, ctask);
+                       iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
+                       iser_ctask_rdma_finalize(iser_ctask);
+               }
        }
-
        iser_dto_buffs_release(dto);
 
        iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);
index dfaf9fa5734040e4ae07497a2fd101b711551c04..f2a08f7ed90205947a1f40fdf8d462589f81e9ff 100644 (file)
@@ -740,7 +740,6 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
        struct iscsi_session *session = conn->session;
        struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
        struct iscsi_cmd_task *ctask;
-       uint32_t itt;
 
        /* verify PDU length */
        tcp_conn->in.datalen = ntoh24(hdr->dlength);
@@ -758,7 +757,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
 
        opcode = hdr->opcode & ISCSI_OPCODE_MASK;
        /* verify itt (itt encoding: age+cid+itt) */
-       rc = iscsi_verify_itt(conn, hdr, &itt);
+       rc = iscsi_verify_itt(conn, hdr->itt);
        if (rc)
                return rc;
 
@@ -767,7 +766,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
 
        switch(opcode) {
        case ISCSI_OP_SCSI_DATA_IN:
-               ctask = session->cmds[itt];
+               ctask = iscsi_itt_to_ctask(conn, hdr->itt);
+               if (!ctask)
+                       return ISCSI_ERR_BAD_ITT;
+
                spin_lock(&conn->session->lock);
                rc = iscsi_data_rsp(conn, ctask);
                spin_unlock(&conn->session->lock);
@@ -810,7 +812,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
                rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
                break;
        case ISCSI_OP_R2T:
-               ctask = session->cmds[itt];
+               ctask = iscsi_itt_to_ctask(conn, hdr->itt);
+               if (!ctask)
+                       return ISCSI_ERR_BAD_ITT;
+
                if (ahslen)
                        rc = ISCSI_ERR_AHSLEN;
                else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
index 79bc49fd7f12c05e622b3ec3c17f804e0e3077c5..4bc63c4b3c105c276e67ff8fe9effd42b1066081 100644 (file)
@@ -640,6 +640,10 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
        uint32_t itt;
 
        conn->last_recv = jiffies;
+       rc = iscsi_verify_itt(conn, hdr->itt);
+       if (rc)
+               return rc;
+
        if (hdr->itt != RESERVED_ITT)
                itt = get_itt(hdr->itt);
        else
@@ -776,27 +780,22 @@ int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
 }
 EXPORT_SYMBOL_GPL(iscsi_complete_pdu);
 
-/* verify itt (itt encoding: age+cid+itt) */
-int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
-                    uint32_t *ret_itt)
+int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt)
 {
        struct iscsi_session *session = conn->session;
        struct iscsi_cmd_task *ctask;
-       uint32_t itt;
 
-       if (hdr->itt != RESERVED_ITT) {
-               if (((__force u32)hdr->itt & ISCSI_AGE_MASK) !=
-                   (session->age << ISCSI_AGE_SHIFT)) {
-                       iscsi_conn_printk(KERN_ERR, conn,
-                                         "received itt %x expected session "
-                                         "age (%x)\n", (__force u32)hdr->itt,
-                                         session->age & ISCSI_AGE_MASK);
-                       return ISCSI_ERR_BAD_ITT;
-               }
+       if (itt == RESERVED_ITT)
+               return 0;
 
-               itt = get_itt(hdr->itt);
-       } else
-               itt = ~0U;
+       if (((__force u32)itt & ISCSI_AGE_MASK) !=
+           (session->age << ISCSI_AGE_SHIFT)) {
+               iscsi_conn_printk(KERN_ERR, conn,
+                                 "received itt %x expected session age (%x)\n",
+                                 (__force u32)itt,
+                                 session->age & ISCSI_AGE_MASK);
+               return ISCSI_ERR_BAD_ITT;
+       }
 
        if (itt < session->cmds_max) {
                ctask = session->cmds[itt];
@@ -817,11 +816,38 @@ int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                }
        }
 
-       *ret_itt = itt;
        return 0;
 }
 EXPORT_SYMBOL_GPL(iscsi_verify_itt);
 
+struct iscsi_cmd_task *
+iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)
+{
+       struct iscsi_session *session = conn->session;
+       struct iscsi_cmd_task *ctask;
+       uint32_t i;
+
+       if (iscsi_verify_itt(conn, itt))
+               return NULL;
+
+       if (itt == RESERVED_ITT)
+               return NULL;
+
+       i = get_itt(itt);
+       if (i >= session->cmds_max)
+               return NULL;
+
+       ctask = session->cmds[i];
+       if (!ctask->sc)
+               return NULL;
+
+       if (ctask->sc->SCp.phase != session->age)
+               return NULL;
+
+       return ctask;
+}
+EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask);
+
 void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
 {
        struct iscsi_session *session = conn->session;
index f54aeb1e8ae359fba219c5c5c86f5ee81dc9ab24..9be6a70faff528da32d863be4b10f913b38eb6ed 100644 (file)
@@ -385,8 +385,8 @@ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
                                char *, uint32_t);
 extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
                              char *, int);
-extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *,
-                           uint32_t *);
+extern int iscsi_verify_itt(struct iscsi_conn *, itt_t);
+extern struct iscsi_cmd_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
 extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask);
 extern void iscsi_free_mgmt_task(struct iscsi_conn *conn,
                                 struct iscsi_mgmt_task *mtask);