diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-07-03 06:48:24 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-07-07 00:59:53 -0400 |
commit | ba159914086f06532079fc15141f46ffe7e04a41 (patch) | |
tree | 9618efce9323083a5812cf831997e0cf560a6b0a /drivers/target | |
parent | 3df8f68aaf7ebe3d136a22262b41b350b0a1858b (diff) |
iscsi-target: Fix iscsit_add_reject* usage for iser
This patch changes iscsit_add_reject() + iscsit_add_reject_from_cmd()
usage to not sleep on iscsi_cmd->reject_comp to address a free-after-use
usage bug in v3.10 with iser-target code.
It saves ->reject_reason for use within iscsit_build_reject() so the
correct value for both transport cases. It also drops the legacy
fail_conn parameter usage throughput iscsi-target code and adds
two iscsit_add_reject_cmd() and iscsit_reject_cmd helper functions,
along with various small cleanups.
(v2: Re-enable target_put_sess_cmd() to be called from
iscsit_add_reject_from_cmd() for rejects invoked after
target_get_sess_cmd() has been called)
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Mike Christie <michaelc@cs.wisc.edu>
Cc: stable@vger.kernel.org # 3.10+
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 255 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target.h | 2 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_core.h | 8 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_erl0.c | 7 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_erl1.c | 20 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 1 |
6 files changed, 120 insertions, 173 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 19a31f9bb7d5..2a25bd3b065c 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -628,25 +628,18 @@ static void __exit iscsi_target_cleanup_module(void) | |||
628 | } | 628 | } |
629 | 629 | ||
630 | static int iscsit_add_reject( | 630 | static int iscsit_add_reject( |
631 | struct iscsi_conn *conn, | ||
631 | u8 reason, | 632 | u8 reason, |
632 | int fail_conn, | 633 | unsigned char *buf) |
633 | unsigned char *buf, | ||
634 | struct iscsi_conn *conn) | ||
635 | { | 634 | { |
636 | struct iscsi_cmd *cmd; | 635 | struct iscsi_cmd *cmd; |
637 | struct iscsi_reject *hdr; | ||
638 | int ret; | ||
639 | 636 | ||
640 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 637 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
641 | if (!cmd) | 638 | if (!cmd) |
642 | return -1; | 639 | return -1; |
643 | 640 | ||
644 | cmd->iscsi_opcode = ISCSI_OP_REJECT; | 641 | cmd->iscsi_opcode = ISCSI_OP_REJECT; |
645 | if (fail_conn) | 642 | cmd->reject_reason = reason; |
646 | cmd->cmd_flags |= ICF_REJECT_FAIL_CONN; | ||
647 | |||
648 | hdr = (struct iscsi_reject *) cmd->pdu; | ||
649 | hdr->reason = reason; | ||
650 | 643 | ||
651 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); | 644 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
652 | if (!cmd->buf_ptr) { | 645 | if (!cmd->buf_ptr) { |
@@ -662,23 +655,16 @@ static int iscsit_add_reject( | |||
662 | cmd->i_state = ISTATE_SEND_REJECT; | 655 | cmd->i_state = ISTATE_SEND_REJECT; |
663 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); | 656 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); |
664 | 657 | ||
665 | ret = wait_for_completion_interruptible(&cmd->reject_comp); | 658 | return -1; |
666 | if (ret != 0) | ||
667 | return -1; | ||
668 | |||
669 | return (!fail_conn) ? 0 : -1; | ||
670 | } | 659 | } |
671 | 660 | ||
672 | int iscsit_add_reject_from_cmd( | 661 | static int iscsit_add_reject_from_cmd( |
662 | struct iscsi_cmd *cmd, | ||
673 | u8 reason, | 663 | u8 reason, |
674 | int fail_conn, | 664 | bool add_to_conn, |
675 | int add_to_conn, | 665 | unsigned char *buf) |
676 | unsigned char *buf, | ||
677 | struct iscsi_cmd *cmd) | ||
678 | { | 666 | { |
679 | struct iscsi_conn *conn; | 667 | struct iscsi_conn *conn; |
680 | struct iscsi_reject *hdr; | ||
681 | int ret; | ||
682 | 668 | ||
683 | if (!cmd->conn) { | 669 | if (!cmd->conn) { |
684 | pr_err("cmd->conn is NULL for ITT: 0x%08x\n", | 670 | pr_err("cmd->conn is NULL for ITT: 0x%08x\n", |
@@ -688,11 +674,7 @@ int iscsit_add_reject_from_cmd( | |||
688 | conn = cmd->conn; | 674 | conn = cmd->conn; |
689 | 675 | ||
690 | cmd->iscsi_opcode = ISCSI_OP_REJECT; | 676 | cmd->iscsi_opcode = ISCSI_OP_REJECT; |
691 | if (fail_conn) | 677 | cmd->reject_reason = reason; |
692 | cmd->cmd_flags |= ICF_REJECT_FAIL_CONN; | ||
693 | |||
694 | hdr = (struct iscsi_reject *) cmd->pdu; | ||
695 | hdr->reason = reason; | ||
696 | 678 | ||
697 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); | 679 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
698 | if (!cmd->buf_ptr) { | 680 | if (!cmd->buf_ptr) { |
@@ -709,8 +691,6 @@ int iscsit_add_reject_from_cmd( | |||
709 | 691 | ||
710 | cmd->i_state = ISTATE_SEND_REJECT; | 692 | cmd->i_state = ISTATE_SEND_REJECT; |
711 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); | 693 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); |
712 | |||
713 | ret = wait_for_completion_interruptible(&cmd->reject_comp); | ||
714 | /* | 694 | /* |
715 | * Perform the kref_put now if se_cmd has already been setup by | 695 | * Perform the kref_put now if se_cmd has already been setup by |
716 | * scsit_setup_scsi_cmd() | 696 | * scsit_setup_scsi_cmd() |
@@ -719,12 +699,19 @@ int iscsit_add_reject_from_cmd( | |||
719 | pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n"); | 699 | pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n"); |
720 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | 700 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); |
721 | } | 701 | } |
722 | if (ret != 0) | 702 | return -1; |
723 | return -1; | 703 | } |
724 | 704 | ||
725 | return (!fail_conn) ? 0 : -1; | 705 | static int iscsit_add_reject_cmd(struct iscsi_cmd *cmd, u8 reason, |
706 | unsigned char *buf) | ||
707 | { | ||
708 | return iscsit_add_reject_from_cmd(cmd, reason, true, buf); | ||
709 | } | ||
710 | |||
711 | int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8 reason, unsigned char *buf) | ||
712 | { | ||
713 | return iscsit_add_reject_from_cmd(cmd, reason, false, buf); | ||
726 | } | 714 | } |
727 | EXPORT_SYMBOL(iscsit_add_reject_from_cmd); | ||
728 | 715 | ||
729 | /* | 716 | /* |
730 | * Map some portion of the allocated scatterlist to an iovec, suitable for | 717 | * Map some portion of the allocated scatterlist to an iovec, suitable for |
@@ -844,8 +831,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
844 | !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) { | 831 | !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) { |
845 | pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL" | 832 | pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL" |
846 | " not set. Bad iSCSI Initiator.\n"); | 833 | " not set. Bad iSCSI Initiator.\n"); |
847 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 834 | return iscsit_add_reject_cmd(cmd, |
848 | 1, 1, buf, cmd); | 835 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
849 | } | 836 | } |
850 | 837 | ||
851 | if (((hdr->flags & ISCSI_FLAG_CMD_READ) || | 838 | if (((hdr->flags & ISCSI_FLAG_CMD_READ) || |
@@ -865,8 +852,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
865 | pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE" | 852 | pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE" |
866 | " set when Expected Data Transfer Length is 0 for" | 853 | " set when Expected Data Transfer Length is 0 for" |
867 | " CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]); | 854 | " CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]); |
868 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 855 | return iscsit_add_reject_cmd(cmd, |
869 | 1, 1, buf, cmd); | 856 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
870 | } | 857 | } |
871 | done: | 858 | done: |
872 | 859 | ||
@@ -875,62 +862,62 @@ done: | |||
875 | pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE" | 862 | pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE" |
876 | " MUST be set if Expected Data Transfer Length is not 0." | 863 | " MUST be set if Expected Data Transfer Length is not 0." |
877 | " Bad iSCSI Initiator\n"); | 864 | " Bad iSCSI Initiator\n"); |
878 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 865 | return iscsit_add_reject_cmd(cmd, |
879 | 1, 1, buf, cmd); | 866 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
880 | } | 867 | } |
881 | 868 | ||
882 | if ((hdr->flags & ISCSI_FLAG_CMD_READ) && | 869 | if ((hdr->flags & ISCSI_FLAG_CMD_READ) && |
883 | (hdr->flags & ISCSI_FLAG_CMD_WRITE)) { | 870 | (hdr->flags & ISCSI_FLAG_CMD_WRITE)) { |
884 | pr_err("Bidirectional operations not supported!\n"); | 871 | pr_err("Bidirectional operations not supported!\n"); |
885 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 872 | return iscsit_add_reject_cmd(cmd, |
886 | 1, 1, buf, cmd); | 873 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
887 | } | 874 | } |
888 | 875 | ||
889 | if (hdr->opcode & ISCSI_OP_IMMEDIATE) { | 876 | if (hdr->opcode & ISCSI_OP_IMMEDIATE) { |
890 | pr_err("Illegally set Immediate Bit in iSCSI Initiator" | 877 | pr_err("Illegally set Immediate Bit in iSCSI Initiator" |
891 | " Scsi Command PDU.\n"); | 878 | " Scsi Command PDU.\n"); |
892 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 879 | return iscsit_add_reject_cmd(cmd, |
893 | 1, 1, buf, cmd); | 880 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
894 | } | 881 | } |
895 | 882 | ||
896 | if (payload_length && !conn->sess->sess_ops->ImmediateData) { | 883 | if (payload_length && !conn->sess->sess_ops->ImmediateData) { |
897 | pr_err("ImmediateData=No but DataSegmentLength=%u," | 884 | pr_err("ImmediateData=No but DataSegmentLength=%u," |
898 | " protocol error.\n", payload_length); | 885 | " protocol error.\n", payload_length); |
899 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 886 | return iscsit_add_reject_cmd(cmd, |
900 | 1, 1, buf, cmd); | 887 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
901 | } | 888 | } |
902 | 889 | ||
903 | if ((be32_to_cpu(hdr->data_length )== payload_length) && | 890 | if ((be32_to_cpu(hdr->data_length) == payload_length) && |
904 | (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) { | 891 | (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) { |
905 | pr_err("Expected Data Transfer Length and Length of" | 892 | pr_err("Expected Data Transfer Length and Length of" |
906 | " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL" | 893 | " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL" |
907 | " bit is not set protocol error\n"); | 894 | " bit is not set protocol error\n"); |
908 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 895 | return iscsit_add_reject_cmd(cmd, |
909 | 1, 1, buf, cmd); | 896 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
910 | } | 897 | } |
911 | 898 | ||
912 | if (payload_length > be32_to_cpu(hdr->data_length)) { | 899 | if (payload_length > be32_to_cpu(hdr->data_length)) { |
913 | pr_err("DataSegmentLength: %u is greater than" | 900 | pr_err("DataSegmentLength: %u is greater than" |
914 | " EDTL: %u, protocol error.\n", payload_length, | 901 | " EDTL: %u, protocol error.\n", payload_length, |
915 | hdr->data_length); | 902 | hdr->data_length); |
916 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 903 | return iscsit_add_reject_cmd(cmd, |
917 | 1, 1, buf, cmd); | 904 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
918 | } | 905 | } |
919 | 906 | ||
920 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { | 907 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { |
921 | pr_err("DataSegmentLength: %u is greater than" | 908 | pr_err("DataSegmentLength: %u is greater than" |
922 | " MaxXmitDataSegmentLength: %u, protocol error.\n", | 909 | " MaxXmitDataSegmentLength: %u, protocol error.\n", |
923 | payload_length, conn->conn_ops->MaxXmitDataSegmentLength); | 910 | payload_length, conn->conn_ops->MaxXmitDataSegmentLength); |
924 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 911 | return iscsit_add_reject_cmd(cmd, |
925 | 1, 1, buf, cmd); | 912 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
926 | } | 913 | } |
927 | 914 | ||
928 | if (payload_length > conn->sess->sess_ops->FirstBurstLength) { | 915 | if (payload_length > conn->sess->sess_ops->FirstBurstLength) { |
929 | pr_err("DataSegmentLength: %u is greater than" | 916 | pr_err("DataSegmentLength: %u is greater than" |
930 | " FirstBurstLength: %u, protocol error.\n", | 917 | " FirstBurstLength: %u, protocol error.\n", |
931 | payload_length, conn->sess->sess_ops->FirstBurstLength); | 918 | payload_length, conn->sess->sess_ops->FirstBurstLength); |
932 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 919 | return iscsit_add_reject_cmd(cmd, |
933 | 1, 1, buf, cmd); | 920 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
934 | } | 921 | } |
935 | 922 | ||
936 | data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : | 923 | data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : |
@@ -985,9 +972,8 @@ done: | |||
985 | 972 | ||
986 | dr = iscsit_allocate_datain_req(); | 973 | dr = iscsit_allocate_datain_req(); |
987 | if (!dr) | 974 | if (!dr) |
988 | return iscsit_add_reject_from_cmd( | 975 | return iscsit_add_reject_cmd(cmd, |
989 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 976 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
990 | 1, 1, buf, cmd); | ||
991 | 977 | ||
992 | iscsit_attach_datain_req(cmd, dr); | 978 | iscsit_attach_datain_req(cmd, dr); |
993 | } | 979 | } |
@@ -1015,18 +1001,16 @@ done: | |||
1015 | cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); | 1001 | cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); |
1016 | if (cmd->sense_reason) { | 1002 | if (cmd->sense_reason) { |
1017 | if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) { | 1003 | if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) { |
1018 | return iscsit_add_reject_from_cmd( | 1004 | return iscsit_add_reject_cmd(cmd, |
1019 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1005 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
1020 | 1, 1, buf, cmd); | ||
1021 | } | 1006 | } |
1022 | 1007 | ||
1023 | goto attach_cmd; | 1008 | goto attach_cmd; |
1024 | } | 1009 | } |
1025 | 1010 | ||
1026 | if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) { | 1011 | if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) { |
1027 | return iscsit_add_reject_from_cmd( | 1012 | return iscsit_add_reject_cmd(cmd, |
1028 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1013 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
1029 | 1, 1, buf, cmd); | ||
1030 | } | 1014 | } |
1031 | 1015 | ||
1032 | attach_cmd: | 1016 | attach_cmd: |
@@ -1075,10 +1059,6 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1075 | 1059 | ||
1076 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | 1060 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); |
1077 | return 0; | 1061 | return 0; |
1078 | } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) { | ||
1079 | return iscsit_add_reject_from_cmd( | ||
1080 | ISCSI_REASON_PROTOCOL_ERROR, | ||
1081 | 1, 0, (unsigned char *)hdr, cmd); | ||
1082 | } | 1062 | } |
1083 | } | 1063 | } |
1084 | 1064 | ||
@@ -1149,11 +1129,6 @@ after_immediate_data: | |||
1149 | } else if (cmd->unsolicited_data) | 1129 | } else if (cmd->unsolicited_data) |
1150 | iscsit_set_unsoliticed_dataout(cmd); | 1130 | iscsit_set_unsoliticed_dataout(cmd); |
1151 | 1131 | ||
1152 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | ||
1153 | return iscsit_add_reject_from_cmd( | ||
1154 | ISCSI_REASON_PROTOCOL_ERROR, | ||
1155 | 1, 0, (unsigned char *)hdr, cmd); | ||
1156 | |||
1157 | } else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) { | 1132 | } else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) { |
1158 | /* | 1133 | /* |
1159 | * Immediate Data failed DataCRC and ERL>=1, | 1134 | * Immediate Data failed DataCRC and ERL>=1, |
@@ -1190,9 +1165,8 @@ iscsit_handle_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1190 | * traditional iSCSI block I/O. | 1165 | * traditional iSCSI block I/O. |
1191 | */ | 1166 | */ |
1192 | if (iscsit_allocate_iovecs(cmd) < 0) { | 1167 | if (iscsit_allocate_iovecs(cmd) < 0) { |
1193 | return iscsit_add_reject_from_cmd( | 1168 | return iscsit_add_reject_cmd(cmd, |
1194 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1169 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
1195 | 1, 0, buf, cmd); | ||
1196 | } | 1170 | } |
1197 | immed_data = cmd->immediate_data; | 1171 | immed_data = cmd->immediate_data; |
1198 | 1172 | ||
@@ -1282,8 +1256,8 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, | |||
1282 | 1256 | ||
1283 | if (!payload_length) { | 1257 | if (!payload_length) { |
1284 | pr_err("DataOUT payload is ZERO, protocol error.\n"); | 1258 | pr_err("DataOUT payload is ZERO, protocol error.\n"); |
1285 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 1259 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
1286 | buf, conn); | 1260 | buf); |
1287 | } | 1261 | } |
1288 | 1262 | ||
1289 | /* iSCSI write */ | 1263 | /* iSCSI write */ |
@@ -1300,8 +1274,8 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, | |||
1300 | pr_err("DataSegmentLength: %u is greater than" | 1274 | pr_err("DataSegmentLength: %u is greater than" |
1301 | " MaxXmitDataSegmentLength: %u\n", payload_length, | 1275 | " MaxXmitDataSegmentLength: %u\n", payload_length, |
1302 | conn->conn_ops->MaxXmitDataSegmentLength); | 1276 | conn->conn_ops->MaxXmitDataSegmentLength); |
1303 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 1277 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
1304 | buf, conn); | 1278 | buf); |
1305 | } | 1279 | } |
1306 | 1280 | ||
1307 | cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt, | 1281 | cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt, |
@@ -1324,8 +1298,7 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, | |||
1324 | if (cmd->data_direction != DMA_TO_DEVICE) { | 1298 | if (cmd->data_direction != DMA_TO_DEVICE) { |
1325 | pr_err("Command ITT: 0x%08x received DataOUT for a" | 1299 | pr_err("Command ITT: 0x%08x received DataOUT for a" |
1326 | " NON-WRITE command.\n", cmd->init_task_tag); | 1300 | " NON-WRITE command.\n", cmd->init_task_tag); |
1327 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 1301 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf); |
1328 | 1, 0, buf, cmd); | ||
1329 | } | 1302 | } |
1330 | se_cmd = &cmd->se_cmd; | 1303 | se_cmd = &cmd->se_cmd; |
1331 | iscsit_mod_dataout_timer(cmd); | 1304 | iscsit_mod_dataout_timer(cmd); |
@@ -1334,8 +1307,7 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, | |||
1334 | pr_err("DataOut Offset: %u, Length %u greater than" | 1307 | pr_err("DataOut Offset: %u, Length %u greater than" |
1335 | " iSCSI Command EDTL %u, protocol error.\n", | 1308 | " iSCSI Command EDTL %u, protocol error.\n", |
1336 | hdr->offset, payload_length, cmd->se_cmd.data_length); | 1309 | hdr->offset, payload_length, cmd->se_cmd.data_length); |
1337 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 1310 | return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID, buf); |
1338 | 1, 0, buf, cmd); | ||
1339 | } | 1311 | } |
1340 | 1312 | ||
1341 | if (cmd->unsolicited_data) { | 1313 | if (cmd->unsolicited_data) { |
@@ -1543,8 +1515,8 @@ int iscsit_setup_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1543 | if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { | 1515 | if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { |
1544 | pr_err("NOPOUT ITT is reserved, but Immediate Bit is" | 1516 | pr_err("NOPOUT ITT is reserved, but Immediate Bit is" |
1545 | " not set, protocol error.\n"); | 1517 | " not set, protocol error.\n"); |
1546 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 1518 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, |
1547 | 1, 0, (unsigned char *)hdr, cmd); | 1519 | (unsigned char *)hdr); |
1548 | } | 1520 | } |
1549 | 1521 | ||
1550 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { | 1522 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { |
@@ -1552,8 +1524,8 @@ int iscsit_setup_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1552 | " greater than MaxXmitDataSegmentLength: %u, protocol" | 1524 | " greater than MaxXmitDataSegmentLength: %u, protocol" |
1553 | " error.\n", payload_length, | 1525 | " error.\n", payload_length, |
1554 | conn->conn_ops->MaxXmitDataSegmentLength); | 1526 | conn->conn_ops->MaxXmitDataSegmentLength); |
1555 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 1527 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, |
1556 | 1, 0, (unsigned char *)hdr, cmd); | 1528 | (unsigned char *)hdr); |
1557 | } | 1529 | } |
1558 | 1530 | ||
1559 | pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%08x," | 1531 | pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%08x," |
@@ -1612,9 +1584,7 @@ int iscsit_process_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1612 | return 0; | 1584 | return 0; |
1613 | 1585 | ||
1614 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | 1586 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) |
1615 | return iscsit_add_reject_from_cmd( | 1587 | return -1; |
1616 | ISCSI_REASON_PROTOCOL_ERROR, | ||
1617 | 1, 0, (unsigned char *)hdr, cmd); | ||
1618 | 1588 | ||
1619 | return 0; | 1589 | return 0; |
1620 | } | 1590 | } |
@@ -1780,8 +1750,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1780 | pr_err("Task Management Request TASK_REASSIGN not" | 1750 | pr_err("Task Management Request TASK_REASSIGN not" |
1781 | " issued as immediate command, bad iSCSI Initiator" | 1751 | " issued as immediate command, bad iSCSI Initiator" |
1782 | "implementation\n"); | 1752 | "implementation\n"); |
1783 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 1753 | return iscsit_add_reject_cmd(cmd, |
1784 | 1, 1, buf, cmd); | 1754 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
1785 | } | 1755 | } |
1786 | if ((function != ISCSI_TM_FUNC_ABORT_TASK) && | 1756 | if ((function != ISCSI_TM_FUNC_ABORT_TASK) && |
1787 | be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG) | 1757 | be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG) |
@@ -1793,9 +1763,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1793 | if (!cmd->tmr_req) { | 1763 | if (!cmd->tmr_req) { |
1794 | pr_err("Unable to allocate memory for" | 1764 | pr_err("Unable to allocate memory for" |
1795 | " Task Management command!\n"); | 1765 | " Task Management command!\n"); |
1796 | return iscsit_add_reject_from_cmd( | 1766 | return iscsit_add_reject_cmd(cmd, |
1797 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1767 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
1798 | 1, 1, buf, cmd); | 1768 | buf); |
1799 | } | 1769 | } |
1800 | 1770 | ||
1801 | /* | 1771 | /* |
@@ -1837,17 +1807,15 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1837 | default: | 1807 | default: |
1838 | pr_err("Unknown iSCSI TMR Function:" | 1808 | pr_err("Unknown iSCSI TMR Function:" |
1839 | " 0x%02x\n", function); | 1809 | " 0x%02x\n", function); |
1840 | return iscsit_add_reject_from_cmd( | 1810 | return iscsit_add_reject_cmd(cmd, |
1841 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1811 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
1842 | 1, 1, buf, cmd); | ||
1843 | } | 1812 | } |
1844 | 1813 | ||
1845 | ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req, | 1814 | ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req, |
1846 | tcm_function, GFP_KERNEL); | 1815 | tcm_function, GFP_KERNEL); |
1847 | if (ret < 0) | 1816 | if (ret < 0) |
1848 | return iscsit_add_reject_from_cmd( | 1817 | return iscsit_add_reject_cmd(cmd, |
1849 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1818 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
1850 | 1, 1, buf, cmd); | ||
1851 | 1819 | ||
1852 | cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req; | 1820 | cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req; |
1853 | } | 1821 | } |
@@ -1906,9 +1874,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1906 | break; | 1874 | break; |
1907 | 1875 | ||
1908 | if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0) | 1876 | if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0) |
1909 | return iscsit_add_reject_from_cmd( | 1877 | return iscsit_add_reject_cmd(cmd, |
1910 | ISCSI_REASON_BOOKMARK_INVALID, 1, 1, | 1878 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
1911 | buf, cmd); | ||
1912 | break; | 1879 | break; |
1913 | default: | 1880 | default: |
1914 | pr_err("Unknown TMR function: 0x%02x, protocol" | 1881 | pr_err("Unknown TMR function: 0x%02x, protocol" |
@@ -1932,9 +1899,7 @@ attach: | |||
1932 | else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) | 1899 | else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) |
1933 | return 0; | 1900 | return 0; |
1934 | else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | 1901 | else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) |
1935 | return iscsit_add_reject_from_cmd( | 1902 | return -1; |
1936 | ISCSI_REASON_PROTOCOL_ERROR, | ||
1937 | 1, 0, buf, cmd); | ||
1938 | } | 1903 | } |
1939 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); | 1904 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); |
1940 | 1905 | ||
@@ -1970,8 +1935,8 @@ iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1970 | pr_err("Unable to accept text parameter length: %u" | 1935 | pr_err("Unable to accept text parameter length: %u" |
1971 | "greater than MaxXmitDataSegmentLength %u.\n", | 1936 | "greater than MaxXmitDataSegmentLength %u.\n", |
1972 | payload_length, conn->conn_ops->MaxXmitDataSegmentLength); | 1937 | payload_length, conn->conn_ops->MaxXmitDataSegmentLength); |
1973 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 1938 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, |
1974 | 1, 0, (unsigned char *)hdr, cmd); | 1939 | (unsigned char *)hdr); |
1975 | } | 1940 | } |
1976 | 1941 | ||
1977 | pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x," | 1942 | pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x," |
@@ -2033,17 +1998,16 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2033 | if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { | 1998 | if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { |
2034 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); | 1999 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); |
2035 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | 2000 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) |
2036 | return iscsit_add_reject_from_cmd( | 2001 | return -1; |
2037 | ISCSI_REASON_PROTOCOL_ERROR, | 2002 | |
2038 | 1, 0, (unsigned char *)hdr, cmd); | ||
2039 | return 0; | 2003 | return 0; |
2040 | } | 2004 | } |
2041 | 2005 | ||
2042 | return iscsit_execute_cmd(cmd, 0); | 2006 | return iscsit_execute_cmd(cmd, 0); |
2043 | 2007 | ||
2044 | reject: | 2008 | reject: |
2045 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 2009 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, |
2046 | 0, 0, (unsigned char *)hdr, cmd); | 2010 | (unsigned char *)hdr); |
2047 | } | 2011 | } |
2048 | EXPORT_SYMBOL(iscsit_process_text_cmd); | 2012 | EXPORT_SYMBOL(iscsit_process_text_cmd); |
2049 | 2013 | ||
@@ -2139,8 +2103,7 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2139 | reject: | 2103 | reject: |
2140 | kfree(cmd->text_in_ptr); | 2104 | kfree(cmd->text_in_ptr); |
2141 | cmd->text_in_ptr = NULL; | 2105 | cmd->text_in_ptr = NULL; |
2142 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 2106 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf); |
2143 | 0, 0, buf, cmd); | ||
2144 | } | 2107 | } |
2145 | EXPORT_SYMBOL(iscsit_handle_text_cmd); | 2108 | EXPORT_SYMBOL(iscsit_handle_text_cmd); |
2146 | 2109 | ||
@@ -2322,13 +2285,10 @@ iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2322 | return ret; | 2285 | return ret; |
2323 | } else { | 2286 | } else { |
2324 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); | 2287 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); |
2325 | if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) { | 2288 | if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) |
2326 | logout_remove = 0; | 2289 | logout_remove = 0; |
2327 | } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) { | 2290 | else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) |
2328 | return iscsit_add_reject_from_cmd( | 2291 | return -1; |
2329 | ISCSI_REASON_PROTOCOL_ERROR, | ||
2330 | 1, 0, buf, cmd); | ||
2331 | } | ||
2332 | } | 2292 | } |
2333 | 2293 | ||
2334 | return logout_remove; | 2294 | return logout_remove; |
@@ -2352,8 +2312,8 @@ static int iscsit_handle_snack( | |||
2352 | if (!conn->sess->sess_ops->ErrorRecoveryLevel) { | 2312 | if (!conn->sess->sess_ops->ErrorRecoveryLevel) { |
2353 | pr_err("Initiator sent SNACK request while in" | 2313 | pr_err("Initiator sent SNACK request while in" |
2354 | " ErrorRecoveryLevel=0.\n"); | 2314 | " ErrorRecoveryLevel=0.\n"); |
2355 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 2315 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
2356 | buf, conn); | 2316 | buf); |
2357 | } | 2317 | } |
2358 | /* | 2318 | /* |
2359 | * SNACK_DATA and SNACK_R2T are both 0, so check which function to | 2319 | * SNACK_DATA and SNACK_R2T are both 0, so check which function to |
@@ -2377,13 +2337,13 @@ static int iscsit_handle_snack( | |||
2377 | case ISCSI_FLAG_SNACK_TYPE_RDATA: | 2337 | case ISCSI_FLAG_SNACK_TYPE_RDATA: |
2378 | /* FIXME: Support R-Data SNACK */ | 2338 | /* FIXME: Support R-Data SNACK */ |
2379 | pr_err("R-Data SNACK Not Supported.\n"); | 2339 | pr_err("R-Data SNACK Not Supported.\n"); |
2380 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 2340 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
2381 | buf, conn); | 2341 | buf); |
2382 | default: | 2342 | default: |
2383 | pr_err("Unknown SNACK type 0x%02x, protocol" | 2343 | pr_err("Unknown SNACK type 0x%02x, protocol" |
2384 | " error.\n", hdr->flags & 0x0f); | 2344 | " error.\n", hdr->flags & 0x0f); |
2385 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 2345 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
2386 | buf, conn); | 2346 | buf); |
2387 | } | 2347 | } |
2388 | 2348 | ||
2389 | return 0; | 2349 | return 0; |
@@ -2455,14 +2415,14 @@ static int iscsit_handle_immediate_data( | |||
2455 | pr_err("Unable to recover from" | 2415 | pr_err("Unable to recover from" |
2456 | " Immediate Data digest failure while" | 2416 | " Immediate Data digest failure while" |
2457 | " in ERL=0.\n"); | 2417 | " in ERL=0.\n"); |
2458 | iscsit_add_reject_from_cmd( | 2418 | iscsit_reject_cmd(cmd, |
2459 | ISCSI_REASON_DATA_DIGEST_ERROR, | 2419 | ISCSI_REASON_DATA_DIGEST_ERROR, |
2460 | 1, 0, (unsigned char *)hdr, cmd); | 2420 | (unsigned char *)hdr); |
2461 | return IMMEDIATE_DATA_CANNOT_RECOVER; | 2421 | return IMMEDIATE_DATA_CANNOT_RECOVER; |
2462 | } else { | 2422 | } else { |
2463 | iscsit_add_reject_from_cmd( | 2423 | iscsit_reject_cmd(cmd, |
2464 | ISCSI_REASON_DATA_DIGEST_ERROR, | 2424 | ISCSI_REASON_DATA_DIGEST_ERROR, |
2465 | 0, 0, (unsigned char *)hdr, cmd); | 2425 | (unsigned char *)hdr); |
2466 | return IMMEDIATE_DATA_ERL1_CRC_FAILURE; | 2426 | return IMMEDIATE_DATA_ERL1_CRC_FAILURE; |
2467 | } | 2427 | } |
2468 | } else { | 2428 | } else { |
@@ -3595,6 +3555,7 @@ iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | |||
3595 | struct iscsi_reject *hdr) | 3555 | struct iscsi_reject *hdr) |
3596 | { | 3556 | { |
3597 | hdr->opcode = ISCSI_OP_REJECT; | 3557 | hdr->opcode = ISCSI_OP_REJECT; |
3558 | hdr->reason = cmd->reject_reason; | ||
3598 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | 3559 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; |
3599 | hton24(hdr->dlength, ISCSI_HDR_LEN); | 3560 | hton24(hdr->dlength, ISCSI_HDR_LEN); |
3600 | hdr->ffffffff = cpu_to_be32(0xffffffff); | 3561 | hdr->ffffffff = cpu_to_be32(0xffffffff); |
@@ -3868,18 +3829,11 @@ check_rsp_state: | |||
3868 | case ISTATE_SEND_STATUS_RECOVERY: | 3829 | case ISTATE_SEND_STATUS_RECOVERY: |
3869 | case ISTATE_SEND_TEXTRSP: | 3830 | case ISTATE_SEND_TEXTRSP: |
3870 | case ISTATE_SEND_TASKMGTRSP: | 3831 | case ISTATE_SEND_TASKMGTRSP: |
3832 | case ISTATE_SEND_REJECT: | ||
3871 | spin_lock_bh(&cmd->istate_lock); | 3833 | spin_lock_bh(&cmd->istate_lock); |
3872 | cmd->i_state = ISTATE_SENT_STATUS; | 3834 | cmd->i_state = ISTATE_SENT_STATUS; |
3873 | spin_unlock_bh(&cmd->istate_lock); | 3835 | spin_unlock_bh(&cmd->istate_lock); |
3874 | break; | 3836 | break; |
3875 | case ISTATE_SEND_REJECT: | ||
3876 | if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) { | ||
3877 | cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN; | ||
3878 | complete(&cmd->reject_comp); | ||
3879 | goto err; | ||
3880 | } | ||
3881 | complete(&cmd->reject_comp); | ||
3882 | break; | ||
3883 | default: | 3837 | default: |
3884 | pr_err("Unknown Opcode: 0x%02x ITT:" | 3838 | pr_err("Unknown Opcode: 0x%02x ITT:" |
3885 | " 0x%08x, i_state: %d on CID: %hu\n", | 3839 | " 0x%08x, i_state: %d on CID: %hu\n", |
@@ -3984,8 +3938,7 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) | |||
3984 | case ISCSI_OP_SCSI_CMD: | 3938 | case ISCSI_OP_SCSI_CMD: |
3985 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 3939 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
3986 | if (!cmd) | 3940 | if (!cmd) |
3987 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 3941 | goto reject; |
3988 | 1, buf, conn); | ||
3989 | 3942 | ||
3990 | ret = iscsit_handle_scsi_cmd(conn, cmd, buf); | 3943 | ret = iscsit_handle_scsi_cmd(conn, cmd, buf); |
3991 | break; | 3944 | break; |
@@ -3997,32 +3950,28 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) | |||
3997 | if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { | 3950 | if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { |
3998 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 3951 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
3999 | if (!cmd) | 3952 | if (!cmd) |
4000 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 3953 | goto reject; |
4001 | 1, buf, conn); | ||
4002 | } | 3954 | } |
4003 | ret = iscsit_handle_nop_out(conn, cmd, buf); | 3955 | ret = iscsit_handle_nop_out(conn, cmd, buf); |
4004 | break; | 3956 | break; |
4005 | case ISCSI_OP_SCSI_TMFUNC: | 3957 | case ISCSI_OP_SCSI_TMFUNC: |
4006 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 3958 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
4007 | if (!cmd) | 3959 | if (!cmd) |
4008 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 3960 | goto reject; |
4009 | 1, buf, conn); | ||
4010 | 3961 | ||
4011 | ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf); | 3962 | ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf); |
4012 | break; | 3963 | break; |
4013 | case ISCSI_OP_TEXT: | 3964 | case ISCSI_OP_TEXT: |
4014 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 3965 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
4015 | if (!cmd) | 3966 | if (!cmd) |
4016 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 3967 | goto reject; |
4017 | 1, buf, conn); | ||
4018 | 3968 | ||
4019 | ret = iscsit_handle_text_cmd(conn, cmd, buf); | 3969 | ret = iscsit_handle_text_cmd(conn, cmd, buf); |
4020 | break; | 3970 | break; |
4021 | case ISCSI_OP_LOGOUT: | 3971 | case ISCSI_OP_LOGOUT: |
4022 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 3972 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
4023 | if (!cmd) | 3973 | if (!cmd) |
4024 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 3974 | goto reject; |
4025 | 1, buf, conn); | ||
4026 | 3975 | ||
4027 | ret = iscsit_handle_logout_cmd(conn, cmd, buf); | 3976 | ret = iscsit_handle_logout_cmd(conn, cmd, buf); |
4028 | if (ret > 0) | 3977 | if (ret > 0) |
@@ -4054,6 +4003,8 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) | |||
4054 | } | 4003 | } |
4055 | 4004 | ||
4056 | return ret; | 4005 | return ret; |
4006 | reject: | ||
4007 | return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); | ||
4057 | } | 4008 | } |
4058 | 4009 | ||
4059 | int iscsi_target_rx_thread(void *arg) | 4010 | int iscsi_target_rx_thread(void *arg) |
@@ -4148,8 +4099,8 @@ restart: | |||
4148 | (!(opcode & ISCSI_OP_LOGOUT)))) { | 4099 | (!(opcode & ISCSI_OP_LOGOUT)))) { |
4149 | pr_err("Received illegal iSCSI Opcode: 0x%02x" | 4100 | pr_err("Received illegal iSCSI Opcode: 0x%02x" |
4150 | " while in Discovery Session, rejecting.\n", opcode); | 4101 | " while in Discovery Session, rejecting.\n", opcode); |
4151 | iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 4102 | iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
4152 | buffer, conn); | 4103 | buffer); |
4153 | goto transport_err; | 4104 | goto transport_err; |
4154 | } | 4105 | } |
4155 | 4106 | ||
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index a0050b2f294e..2c437cb8ca00 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h | |||
@@ -15,7 +15,7 @@ extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *, | |||
15 | extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, | 15 | extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, |
16 | struct iscsi_portal_group *); | 16 | struct iscsi_portal_group *); |
17 | extern int iscsit_del_np(struct iscsi_np *); | 17 | extern int iscsit_del_np(struct iscsi_np *); |
18 | extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *, struct iscsi_cmd *); | 18 | extern int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8, unsigned char *); |
19 | extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); | 19 | extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); |
20 | extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *); | 20 | extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *); |
21 | extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); | 21 | extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index caa0ad9a778b..4f77a78edef9 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -132,9 +132,8 @@ enum cmd_flags_table { | |||
132 | ICF_CONTIG_MEMORY = 0x00000020, | 132 | ICF_CONTIG_MEMORY = 0x00000020, |
133 | ICF_ATTACHED_TO_RQUEUE = 0x00000040, | 133 | ICF_ATTACHED_TO_RQUEUE = 0x00000040, |
134 | ICF_OOO_CMDSN = 0x00000080, | 134 | ICF_OOO_CMDSN = 0x00000080, |
135 | ICF_REJECT_FAIL_CONN = 0x00000100, | 135 | IFC_SENDTARGETS_ALL = 0x00000100, |
136 | IFC_SENDTARGETS_ALL = 0x00000200, | 136 | IFC_SENDTARGETS_SINGLE = 0x00000200, |
137 | IFC_SENDTARGETS_SINGLE = 0x00000400, | ||
138 | }; | 137 | }; |
139 | 138 | ||
140 | /* struct iscsi_cmd->i_state */ | 139 | /* struct iscsi_cmd->i_state */ |
@@ -368,6 +367,8 @@ struct iscsi_cmd { | |||
368 | u8 maxcmdsn_inc; | 367 | u8 maxcmdsn_inc; |
369 | /* Immediate Unsolicited Dataout */ | 368 | /* Immediate Unsolicited Dataout */ |
370 | u8 unsolicited_data; | 369 | u8 unsolicited_data; |
370 | /* Reject reason code */ | ||
371 | u8 reject_reason; | ||
371 | /* CID contained in logout PDU when opcode == ISCSI_INIT_LOGOUT_CMND */ | 372 | /* CID contained in logout PDU when opcode == ISCSI_INIT_LOGOUT_CMND */ |
372 | u16 logout_cid; | 373 | u16 logout_cid; |
373 | /* Command flags */ | 374 | /* Command flags */ |
@@ -450,7 +451,6 @@ struct iscsi_cmd { | |||
450 | struct list_head datain_list; | 451 | struct list_head datain_list; |
451 | /* R2T List */ | 452 | /* R2T List */ |
452 | struct list_head cmd_r2t_list; | 453 | struct list_head cmd_r2t_list; |
453 | struct completion reject_comp; | ||
454 | /* Timer for DataOUT */ | 454 | /* Timer for DataOUT */ |
455 | struct timer_list dataout_timer; | 455 | struct timer_list dataout_timer; |
456 | /* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */ | 456 | /* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */ |
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index 8e6298cc8839..8f074e0b6099 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c | |||
@@ -746,13 +746,12 @@ int iscsit_check_post_dataout( | |||
746 | if (!conn->sess->sess_ops->ErrorRecoveryLevel) { | 746 | if (!conn->sess->sess_ops->ErrorRecoveryLevel) { |
747 | pr_err("Unable to recover from DataOUT CRC" | 747 | pr_err("Unable to recover from DataOUT CRC" |
748 | " failure while ERL=0, closing session.\n"); | 748 | " failure while ERL=0, closing session.\n"); |
749 | iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR, | 749 | iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, |
750 | 1, 0, buf, cmd); | 750 | buf); |
751 | return DATAOUT_CANNOT_RECOVER; | 751 | return DATAOUT_CANNOT_RECOVER; |
752 | } | 752 | } |
753 | 753 | ||
754 | iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR, | 754 | iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, buf); |
755 | 0, 0, buf, cmd); | ||
756 | return iscsit_dataout_post_crc_failed(cmd, buf); | 755 | return iscsit_dataout_post_crc_failed(cmd, buf); |
757 | } | 756 | } |
758 | } | 757 | } |
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index 40d9dbca987b..d00f1326f0c8 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c | |||
@@ -162,9 +162,8 @@ static int iscsit_handle_r2t_snack( | |||
162 | " protocol error.\n", cmd->init_task_tag, begrun, | 162 | " protocol error.\n", cmd->init_task_tag, begrun, |
163 | (begrun + runlength), cmd->acked_data_sn); | 163 | (begrun + runlength), cmd->acked_data_sn); |
164 | 164 | ||
165 | return iscsit_add_reject_from_cmd( | 165 | return iscsit_reject_cmd(cmd, |
166 | ISCSI_REASON_PROTOCOL_ERROR, | 166 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
167 | 1, 0, buf, cmd); | ||
168 | } | 167 | } |
169 | 168 | ||
170 | if (runlength) { | 169 | if (runlength) { |
@@ -173,8 +172,8 @@ static int iscsit_handle_r2t_snack( | |||
173 | " with BegRun: 0x%08x, RunLength: 0x%08x, exceeds" | 172 | " with BegRun: 0x%08x, RunLength: 0x%08x, exceeds" |
174 | " current R2TSN: 0x%08x, protocol error.\n", | 173 | " current R2TSN: 0x%08x, protocol error.\n", |
175 | cmd->init_task_tag, begrun, runlength, cmd->r2t_sn); | 174 | cmd->init_task_tag, begrun, runlength, cmd->r2t_sn); |
176 | return iscsit_add_reject_from_cmd( | 175 | return iscsit_reject_cmd(cmd, |
177 | ISCSI_REASON_BOOKMARK_INVALID, 1, 0, buf, cmd); | 176 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
178 | } | 177 | } |
179 | last_r2tsn = (begrun + runlength); | 178 | last_r2tsn = (begrun + runlength); |
180 | } else | 179 | } else |
@@ -433,8 +432,7 @@ static int iscsit_handle_recovery_datain( | |||
433 | " protocol error.\n", cmd->init_task_tag, begrun, | 432 | " protocol error.\n", cmd->init_task_tag, begrun, |
434 | (begrun + runlength), cmd->acked_data_sn); | 433 | (begrun + runlength), cmd->acked_data_sn); |
435 | 434 | ||
436 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 435 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf); |
437 | 1, 0, buf, cmd); | ||
438 | } | 436 | } |
439 | 437 | ||
440 | /* | 438 | /* |
@@ -445,14 +443,14 @@ static int iscsit_handle_recovery_datain( | |||
445 | pr_err("Initiator requesting BegRun: 0x%08x, RunLength" | 443 | pr_err("Initiator requesting BegRun: 0x%08x, RunLength" |
446 | ": 0x%08x greater than maximum DataSN: 0x%08x.\n", | 444 | ": 0x%08x greater than maximum DataSN: 0x%08x.\n", |
447 | begrun, runlength, (cmd->data_sn - 1)); | 445 | begrun, runlength, (cmd->data_sn - 1)); |
448 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 446 | return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID, |
449 | 1, 0, buf, cmd); | 447 | buf); |
450 | } | 448 | } |
451 | 449 | ||
452 | dr = iscsit_allocate_datain_req(); | 450 | dr = iscsit_allocate_datain_req(); |
453 | if (!dr) | 451 | if (!dr) |
454 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 452 | return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
455 | 1, 0, buf, cmd); | 453 | buf); |
456 | 454 | ||
457 | dr->data_sn = dr->begrun = begrun; | 455 | dr->data_sn = dr->begrun = begrun; |
458 | dr->runlength = runlength; | 456 | dr->runlength = runlength; |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index fe712d6cc478..96ce6f2ec428 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -178,7 +178,6 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask) | |||
178 | INIT_LIST_HEAD(&cmd->i_conn_node); | 178 | INIT_LIST_HEAD(&cmd->i_conn_node); |
179 | INIT_LIST_HEAD(&cmd->datain_list); | 179 | INIT_LIST_HEAD(&cmd->datain_list); |
180 | INIT_LIST_HEAD(&cmd->cmd_r2t_list); | 180 | INIT_LIST_HEAD(&cmd->cmd_r2t_list); |
181 | init_completion(&cmd->reject_comp); | ||
182 | spin_lock_init(&cmd->datain_lock); | 181 | spin_lock_init(&cmd->datain_lock); |
183 | spin_lock_init(&cmd->dataout_timeout_lock); | 182 | spin_lock_init(&cmd->dataout_timeout_lock); |
184 | spin_lock_init(&cmd->istate_lock); | 183 | spin_lock_init(&cmd->istate_lock); |