aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c8
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c23
-rw-r--r--drivers/scsi/iscsi_tcp.c13
-rw-r--r--drivers/scsi/libiscsi.c60
-rw-r--r--include/scsi/libiscsi.h4
5 files changed, 65 insertions, 43 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 8a1bfb7277c8..7b1468869066 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -98,7 +98,6 @@ iscsi_iser_recv(struct iscsi_conn *conn,
98 struct iscsi_hdr *hdr, char *rx_data, int rx_data_len) 98 struct iscsi_hdr *hdr, char *rx_data, int rx_data_len)
99{ 99{
100 int rc = 0; 100 int rc = 0;
101 uint32_t ret_itt;
102 int datalen; 101 int datalen;
103 int ahslen; 102 int ahslen;
104 103
@@ -114,12 +113,7 @@ iscsi_iser_recv(struct iscsi_conn *conn,
114 /* read AHS */ 113 /* read AHS */
115 ahslen = hdr->hlength * 4; 114 ahslen = hdr->hlength * 4;
116 115
117 /* verify itt (itt encoding: age+cid+itt) */ 116 rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
118 rc = iscsi_verify_itt(conn, hdr, &ret_itt);
119
120 if (!rc)
121 rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
122
123 if (rc && rc != ISCSI_ERR_NO_SCSI_CMD) 117 if (rc && rc != ISCSI_ERR_NO_SCSI_CMD)
124 goto error; 118 goto error;
125 119
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index 08dc81c46f41..b82a5f2d4d37 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -537,13 +537,11 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
537{ 537{
538 struct iser_dto *dto = &rx_desc->dto; 538 struct iser_dto *dto = &rx_desc->dto;
539 struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn; 539 struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
540 struct iscsi_session *session = conn->iscsi_conn->session;
541 struct iscsi_cmd_task *ctask; 540 struct iscsi_cmd_task *ctask;
542 struct iscsi_iser_cmd_task *iser_ctask; 541 struct iscsi_iser_cmd_task *iser_ctask;
543 struct iscsi_hdr *hdr; 542 struct iscsi_hdr *hdr;
544 char *rx_data = NULL; 543 char *rx_data = NULL;
545 int rx_data_len = 0; 544 int rx_data_len = 0;
546 unsigned int itt;
547 unsigned char opcode; 545 unsigned char opcode;
548 546
549 hdr = &rx_desc->iscsi_header; 547 hdr = &rx_desc->iscsi_header;
@@ -559,19 +557,18 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
559 opcode = hdr->opcode & ISCSI_OPCODE_MASK; 557 opcode = hdr->opcode & ISCSI_OPCODE_MASK;
560 558
561 if (opcode == ISCSI_OP_SCSI_CMD_RSP) { 559 if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
562 itt = get_itt(hdr->itt); /* mask out cid and age bits */ 560 ctask = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
563 if (!(itt < session->cmds_max)) 561 if (!ctask)
564 iser_err("itt can't be matched to task!!! " 562 iser_err("itt can't be matched to task!!! "
565 "conn %p opcode %d cmds_max %d itt %d\n", 563 "conn %p opcode %d itt %d\n",
566 conn->iscsi_conn,opcode,session->cmds_max,itt); 564 conn->iscsi_conn, opcode, hdr->itt);
567 /* use the mapping given with the cmds array indexed by itt */ 565 else {
568 ctask = (struct iscsi_cmd_task *)session->cmds[itt]; 566 iser_ctask = ctask->dd_data;
569 iser_ctask = ctask->dd_data; 567 iser_dbg("itt %d ctask %p\n",hdr->itt, ctask);
570 iser_dbg("itt %d ctask %p\n",itt,ctask); 568 iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
571 iser_ctask->status = ISER_TASK_STATUS_COMPLETED; 569 iser_ctask_rdma_finalize(iser_ctask);
572 iser_ctask_rdma_finalize(iser_ctask); 570 }
573 } 571 }
574
575 iser_dto_buffs_release(dto); 572 iser_dto_buffs_release(dto);
576 573
577 iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len); 574 iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index dfaf9fa57340..f2a08f7ed902 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -740,7 +740,6 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
740 struct iscsi_session *session = conn->session; 740 struct iscsi_session *session = conn->session;
741 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 741 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
742 struct iscsi_cmd_task *ctask; 742 struct iscsi_cmd_task *ctask;
743 uint32_t itt;
744 743
745 /* verify PDU length */ 744 /* verify PDU length */
746 tcp_conn->in.datalen = ntoh24(hdr->dlength); 745 tcp_conn->in.datalen = ntoh24(hdr->dlength);
@@ -758,7 +757,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
758 757
759 opcode = hdr->opcode & ISCSI_OPCODE_MASK; 758 opcode = hdr->opcode & ISCSI_OPCODE_MASK;
760 /* verify itt (itt encoding: age+cid+itt) */ 759 /* verify itt (itt encoding: age+cid+itt) */
761 rc = iscsi_verify_itt(conn, hdr, &itt); 760 rc = iscsi_verify_itt(conn, hdr->itt);
762 if (rc) 761 if (rc)
763 return rc; 762 return rc;
764 763
@@ -767,7 +766,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
767 766
768 switch(opcode) { 767 switch(opcode) {
769 case ISCSI_OP_SCSI_DATA_IN: 768 case ISCSI_OP_SCSI_DATA_IN:
770 ctask = session->cmds[itt]; 769 ctask = iscsi_itt_to_ctask(conn, hdr->itt);
770 if (!ctask)
771 return ISCSI_ERR_BAD_ITT;
772
771 spin_lock(&conn->session->lock); 773 spin_lock(&conn->session->lock);
772 rc = iscsi_data_rsp(conn, ctask); 774 rc = iscsi_data_rsp(conn, ctask);
773 spin_unlock(&conn->session->lock); 775 spin_unlock(&conn->session->lock);
@@ -810,7 +812,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
810 rc = iscsi_complete_pdu(conn, hdr, NULL, 0); 812 rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
811 break; 813 break;
812 case ISCSI_OP_R2T: 814 case ISCSI_OP_R2T:
813 ctask = session->cmds[itt]; 815 ctask = iscsi_itt_to_ctask(conn, hdr->itt);
816 if (!ctask)
817 return ISCSI_ERR_BAD_ITT;
818
814 if (ahslen) 819 if (ahslen)
815 rc = ISCSI_ERR_AHSLEN; 820 rc = ISCSI_ERR_AHSLEN;
816 else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) { 821 else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 79bc49fd7f12..4bc63c4b3c10 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -640,6 +640,10 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
640 uint32_t itt; 640 uint32_t itt;
641 641
642 conn->last_recv = jiffies; 642 conn->last_recv = jiffies;
643 rc = iscsi_verify_itt(conn, hdr->itt);
644 if (rc)
645 return rc;
646
643 if (hdr->itt != RESERVED_ITT) 647 if (hdr->itt != RESERVED_ITT)
644 itt = get_itt(hdr->itt); 648 itt = get_itt(hdr->itt);
645 else 649 else
@@ -776,27 +780,22 @@ int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
776} 780}
777EXPORT_SYMBOL_GPL(iscsi_complete_pdu); 781EXPORT_SYMBOL_GPL(iscsi_complete_pdu);
778 782
779/* verify itt (itt encoding: age+cid+itt) */ 783int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt)
780int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
781 uint32_t *ret_itt)
782{ 784{
783 struct iscsi_session *session = conn->session; 785 struct iscsi_session *session = conn->session;
784 struct iscsi_cmd_task *ctask; 786 struct iscsi_cmd_task *ctask;
785 uint32_t itt;
786 787
787 if (hdr->itt != RESERVED_ITT) { 788 if (itt == RESERVED_ITT)
788 if (((__force u32)hdr->itt & ISCSI_AGE_MASK) != 789 return 0;
789 (session->age << ISCSI_AGE_SHIFT)) {
790 iscsi_conn_printk(KERN_ERR, conn,
791 "received itt %x expected session "
792 "age (%x)\n", (__force u32)hdr->itt,
793 session->age & ISCSI_AGE_MASK);
794 return ISCSI_ERR_BAD_ITT;
795 }
796 790
797 itt = get_itt(hdr->itt); 791 if (((__force u32)itt & ISCSI_AGE_MASK) !=
798 } else 792 (session->age << ISCSI_AGE_SHIFT)) {
799 itt = ~0U; 793 iscsi_conn_printk(KERN_ERR, conn,
794 "received itt %x expected session age (%x)\n",
795 (__force u32)itt,
796 session->age & ISCSI_AGE_MASK);
797 return ISCSI_ERR_BAD_ITT;
798 }
800 799
801 if (itt < session->cmds_max) { 800 if (itt < session->cmds_max) {
802 ctask = session->cmds[itt]; 801 ctask = session->cmds[itt];
@@ -817,11 +816,38 @@ int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
817 } 816 }
818 } 817 }
819 818
820 *ret_itt = itt;
821 return 0; 819 return 0;
822} 820}
823EXPORT_SYMBOL_GPL(iscsi_verify_itt); 821EXPORT_SYMBOL_GPL(iscsi_verify_itt);
824 822
823struct iscsi_cmd_task *
824iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)
825{
826 struct iscsi_session *session = conn->session;
827 struct iscsi_cmd_task *ctask;
828 uint32_t i;
829
830 if (iscsi_verify_itt(conn, itt))
831 return NULL;
832
833 if (itt == RESERVED_ITT)
834 return NULL;
835
836 i = get_itt(itt);
837 if (i >= session->cmds_max)
838 return NULL;
839
840 ctask = session->cmds[i];
841 if (!ctask->sc)
842 return NULL;
843
844 if (ctask->sc->SCp.phase != session->age)
845 return NULL;
846
847 return ctask;
848}
849EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask);
850
825void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) 851void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
826{ 852{
827 struct iscsi_session *session = conn->session; 853 struct iscsi_session *session = conn->session;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index f54aeb1e8ae3..9be6a70faff5 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -385,8 +385,8 @@ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
385 char *, uint32_t); 385 char *, uint32_t);
386extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, 386extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
387 char *, int); 387 char *, int);
388extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *, 388extern int iscsi_verify_itt(struct iscsi_conn *, itt_t);
389 uint32_t *); 389extern struct iscsi_cmd_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
390extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); 390extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask);
391extern void iscsi_free_mgmt_task(struct iscsi_conn *conn, 391extern void iscsi_free_mgmt_task(struct iscsi_conn *conn,
392 struct iscsi_mgmt_task *mtask); 392 struct iscsi_mgmt_task *mtask);