diff options
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r-- | drivers/scsi/libiscsi.c | 60 |
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 | } |
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; |