aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c60
1 files changed, 43 insertions, 17 deletions
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;