diff options
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_initiator.c | 23 | ||||
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 13 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 60 | ||||
-rw-r--r-- | include/scsi/libiscsi.h | 4 |
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 | } |
777 | EXPORT_SYMBOL_GPL(iscsi_complete_pdu); | 781 | EXPORT_SYMBOL_GPL(iscsi_complete_pdu); |
778 | 782 | ||
779 | /* verify itt (itt encoding: age+cid+itt) */ | 783 | int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) |
780 | int 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 | } |
823 | EXPORT_SYMBOL_GPL(iscsi_verify_itt); | 821 | EXPORT_SYMBOL_GPL(iscsi_verify_itt); |
824 | 822 | ||
823 | struct iscsi_cmd_task * | ||
824 | iscsi_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 | } | ||
849 | EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask); | ||
850 | |||
825 | void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) | 851 | void 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); |
386 | extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, | 386 | extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, |
387 | char *, int); | 387 | char *, int); |
388 | extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *, | 388 | extern int iscsi_verify_itt(struct iscsi_conn *, itt_t); |
389 | uint32_t *); | 389 | extern struct iscsi_cmd_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); |
390 | extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); | 390 | extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); |
391 | extern void iscsi_free_mgmt_task(struct iscsi_conn *conn, | 391 | extern void iscsi_free_mgmt_task(struct iscsi_conn *conn, |
392 | struct iscsi_mgmt_task *mtask); | 392 | struct iscsi_mgmt_task *mtask); |