diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2005-09-12 22:02:04 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-09-20 13:36:02 -0400 |
commit | 9974487824570e7ac388390333ef5c4ca3ebc2da (patch) | |
tree | ba90b6074ce9db97384f8b9f465ebdca3e7df6a4 /drivers/scsi | |
parent | fa0a6957aa7d02addb08a231c8e7c77c2b8fcd20 (diff) |
[SCSI] iscsi: fix nop-in handling
From: zhenyu.z.wang@intel.com
This add check to NOOP_IN's ttt, when it's ~0UL we should not send
NOOP_OUT by spec (plus some cleanup).
Signed-off-by: Alex Aizman <itn780@yahoo.com>
Signed-off-by: Dmitry Yusupov <dmitry_yus@yahoo.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 82 |
1 files changed, 47 insertions, 35 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 13411ca3d648..1d27caf3abe8 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -672,34 +672,6 @@ iscsi_hdr_recv(struct iscsi_conn *conn) | |||
672 | else | 672 | else |
673 | rc = ISCSI_ERR_PROTO; | 673 | rc = ISCSI_ERR_PROTO; |
674 | break; | 674 | break; |
675 | case ISCSI_OP_NOOP_IN: | ||
676 | case ISCSI_OP_TEXT_RSP: | ||
677 | case ISCSI_OP_LOGOUT_RSP: | ||
678 | case ISCSI_OP_ASYNC_EVENT: | ||
679 | case ISCSI_OP_REJECT: | ||
680 | rc = iscsi_check_assign_cmdsn(session, | ||
681 | (struct iscsi_nopin*)hdr); | ||
682 | if (rc) | ||
683 | break; | ||
684 | |||
685 | /* update ExpStatSN */ | ||
686 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | ||
687 | if (!conn->in.datalen) { | ||
688 | struct iscsi_mgmt_task *mtask; | ||
689 | |||
690 | rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, | ||
691 | NULL, 0); | ||
692 | mtask = (struct iscsi_mgmt_task *) | ||
693 | session->mgmt_cmds[conn->in.itt - | ||
694 | ISCSI_MGMT_ITT_OFFSET]; | ||
695 | if (conn->login_mtask != mtask) { | ||
696 | spin_lock(&session->lock); | ||
697 | __kfifo_put(session->mgmtpool.queue, | ||
698 | (void*)&mtask, sizeof(void*)); | ||
699 | spin_unlock(&session->lock); | ||
700 | } | ||
701 | } | ||
702 | break; | ||
703 | default: | 675 | default: |
704 | rc = ISCSI_ERR_BAD_OPCODE; | 676 | rc = ISCSI_ERR_BAD_OPCODE; |
705 | break; | 677 | break; |
@@ -718,6 +690,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) | |||
718 | switch(conn->in.opcode) { | 690 | switch(conn->in.opcode) { |
719 | case ISCSI_OP_LOGIN_RSP: | 691 | case ISCSI_OP_LOGIN_RSP: |
720 | case ISCSI_OP_TEXT_RSP: | 692 | case ISCSI_OP_TEXT_RSP: |
693 | case ISCSI_OP_LOGOUT_RSP: | ||
721 | rc = iscsi_check_assign_cmdsn(session, | 694 | rc = iscsi_check_assign_cmdsn(session, |
722 | (struct iscsi_nopin*)hdr); | 695 | (struct iscsi_nopin*)hdr); |
723 | if (rc) | 696 | if (rc) |
@@ -758,20 +731,59 @@ iscsi_hdr_recv(struct iscsi_conn *conn) | |||
758 | } | 731 | } |
759 | spin_unlock(&session->lock); | 732 | spin_unlock(&session->lock); |
760 | break; | 733 | break; |
734 | case ISCSI_OP_NOOP_IN: | ||
735 | if (hdr->ttt != ISCSI_RESERVED_TAG) { | ||
736 | rc = ISCSI_ERR_PROTO; | ||
737 | break; | ||
738 | } | ||
739 | rc = iscsi_check_assign_cmdsn(session, | ||
740 | (struct iscsi_nopin*)hdr); | ||
741 | if (rc) | ||
742 | break; | ||
743 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | ||
744 | |||
745 | if (!conn->in.datalen) { | ||
746 | struct iscsi_mgmt_task *mtask; | ||
747 | |||
748 | rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, | ||
749 | NULL, 0); | ||
750 | mtask = (struct iscsi_mgmt_task *) | ||
751 | session->mgmt_cmds[conn->in.itt - | ||
752 | ISCSI_MGMT_ITT_OFFSET]; | ||
753 | if (conn->login_mtask != mtask) { | ||
754 | spin_lock(&session->lock); | ||
755 | __kfifo_put(session->mgmtpool.queue, | ||
756 | (void*)&mtask, sizeof(void*)); | ||
757 | spin_unlock(&session->lock); | ||
758 | } | ||
759 | } | ||
760 | break; | ||
761 | default: | 761 | default: |
762 | rc = ISCSI_ERR_BAD_OPCODE; | 762 | rc = ISCSI_ERR_BAD_OPCODE; |
763 | break; | 763 | break; |
764 | } | 764 | } |
765 | } else if (conn->in.itt == ISCSI_RESERVED_TAG) { | 765 | } else if (conn->in.itt == ISCSI_RESERVED_TAG) { |
766 | if (conn->in.opcode == ISCSI_OP_NOOP_IN && !conn->in.datalen) { | 766 | switch(conn->in.opcode) { |
767 | rc = iscsi_check_assign_cmdsn(session, | 767 | case ISCSI_OP_NOOP_IN: |
768 | if (!conn->in.datalen) { | ||
769 | rc = iscsi_check_assign_cmdsn(session, | ||
768 | (struct iscsi_nopin*)hdr); | 770 | (struct iscsi_nopin*)hdr); |
769 | if (!rc) | 771 | if (!rc && hdr->ttt != ISCSI_RESERVED_TAG) |
770 | rc = iscsi_recv_pdu(iscsi_handle(conn), | 772 | rc = iscsi_recv_pdu(iscsi_handle(conn), |
771 | hdr, NULL, 0); | 773 | hdr, NULL, 0); |
772 | } | 774 | } else |
773 | else | 775 | rc = ISCSI_ERR_PROTO; |
776 | break; | ||
777 | case ISCSI_OP_REJECT: | ||
778 | /* we need sth like iscsi_reject_rsp()*/ | ||
779 | case ISCSI_OP_ASYNC_EVENT: | ||
780 | /* we need sth like iscsi_async_event_rsp() */ | ||
774 | rc = ISCSI_ERR_BAD_OPCODE; | 781 | rc = ISCSI_ERR_BAD_OPCODE; |
782 | break; | ||
783 | default: | ||
784 | rc = ISCSI_ERR_BAD_OPCODE; | ||
785 | break; | ||
786 | } | ||
775 | } else | 787 | } else |
776 | rc = ISCSI_ERR_BAD_ITT; | 788 | rc = ISCSI_ERR_BAD_ITT; |
777 | 789 | ||