diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-03-07 01:18:24 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-04-25 04:05:27 -0400 |
commit | 3e1c81a95f0d776cea68a36cfc78a0ce8f6d3a77 (patch) | |
tree | 99ceb306765cc6231c32b65c0a9766ab781caf76 | |
parent | cdb726651c357c19c02b17ee3c99a224b03022b6 (diff) |
iscsi-target: Refactor RX PDU logic + export request PDU handling
This patch refactors existing traditional iscsi RX side PDU handling
to use iscsit_transport, and exports the necessary logic for external
transport modules.
This includes:
- Refactor iscsit_handle_scsi_cmd() into PDU setup / processing
- Add updated iscsit_handle_scsi_cmd() for tradtional iscsi code
- Add iscsit_set_unsoliticed_dataout() wrapper
- Refactor iscsit_handle_data_out() into PDU check / processing
- Add updated iscsit_handle_data_out() for tradtional iscsi code
- Add iscsit_handle_nop_out() + iscsit_handle_task_mgt_cmd() to
accept pre-allocated struct iscsi_cmd
- Add iscsit_build_r2ts_for_cmd() caller for iscsi_target_transport
to handle ISTATE_SEND_R2T for TX immediate queue
- Refactor main traditional iscsi iscsi_target_rx_thread() PDU switch
into iscsi_target_rx_opcode() using iscsit_allocate_cmd()
- Turn iscsi_target_rx_thread() process context into NOP for
ib_isert side work-queue.
v5 changes:
- Make iscsit_handle_scsi_cmd() static (Fengguang)
- Fix iscsit_handle_scsi_cmd() exception se_cmd leak (nab)
v3 changes:
- Add extra target_put_sess_cmd call in iscsit_add_reject_from_cmd
after completion
v2 changes:
- Disable iscsit_ack_from_expstatsn() usage for RDMAExtentions=Yes
- Disable iscsit_allocate_datain_req() usage for RDMAExtentions=Yes
- Add target_get_sess_cmd() reference counting to
iscsit_setup_scsi_cmd()
- Add TFO->lio_check_stop_free() fabric API caller
- Add export of iscsit_stop_dataout_timer() symbol
- Add iscsit_build_r2ts_for_cmd() for iscsit_transport->iscsit_get_dataout()
- Convert existing usage of iscsit_build_r2ts_for_cmd() to
->iscsit_get_dataout()
- Drop RDMAExtentions=Yes specific check in iscsit_build_r2ts_for_cmd()
- Fix RDMAExtentions -> RDMAExtensions typo (andy)
- Pass correct dump_payload value into iscsit_get_immediate_data()
for iscsit_handle_scsi_cmd()
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 503 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target.h | 3 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_configfs.c | 9 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_erl1.c | 13 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_login.c | 3 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_nego.c | 15 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_tmr.c | 3 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 1 |
8 files changed, 346 insertions, 204 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index b01a10eae365..40bb916f57ff 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -492,6 +492,7 @@ static struct iscsit_transport iscsi_target_transport = { | |||
492 | .iscsit_alloc_cmd = iscsit_alloc_cmd, | 492 | .iscsit_alloc_cmd = iscsit_alloc_cmd, |
493 | .iscsit_get_login_rx = iscsit_get_login_rx, | 493 | .iscsit_get_login_rx = iscsit_get_login_rx, |
494 | .iscsit_put_login_tx = iscsit_put_login_tx, | 494 | .iscsit_put_login_tx = iscsit_put_login_tx, |
495 | .iscsit_get_dataout = iscsit_build_r2ts_for_cmd, | ||
495 | }; | 496 | }; |
496 | 497 | ||
497 | static int __init iscsi_target_init_module(void) | 498 | static int __init iscsi_target_init_module(void) |
@@ -650,6 +651,14 @@ static int iscsit_add_reject( | |||
650 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); | 651 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); |
651 | 652 | ||
652 | ret = wait_for_completion_interruptible(&cmd->reject_comp); | 653 | ret = wait_for_completion_interruptible(&cmd->reject_comp); |
654 | /* | ||
655 | * Perform the kref_put now if se_cmd has been setup by | ||
656 | * iscsit_setup_scsi_cmd() | ||
657 | */ | ||
658 | if (cmd->se_cmd.se_tfo != NULL) { | ||
659 | pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n"); | ||
660 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | ||
661 | } | ||
653 | if (ret != 0) | 662 | if (ret != 0) |
654 | return -1; | 663 | return -1; |
655 | 664 | ||
@@ -698,11 +707,20 @@ int iscsit_add_reject_from_cmd( | |||
698 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); | 707 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); |
699 | 708 | ||
700 | ret = wait_for_completion_interruptible(&cmd->reject_comp); | 709 | ret = wait_for_completion_interruptible(&cmd->reject_comp); |
710 | /* | ||
711 | * Perform the kref_put now if se_cmd has already been setup by | ||
712 | * scsit_setup_scsi_cmd() | ||
713 | */ | ||
714 | if (cmd->se_cmd.se_tfo != NULL) { | ||
715 | pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n"); | ||
716 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | ||
717 | } | ||
701 | if (ret != 0) | 718 | if (ret != 0) |
702 | return -1; | 719 | return -1; |
703 | 720 | ||
704 | return (!fail_conn) ? 0 : -1; | 721 | return (!fail_conn) ? 0 : -1; |
705 | } | 722 | } |
723 | EXPORT_SYMBOL(iscsit_add_reject_from_cmd); | ||
706 | 724 | ||
707 | /* | 725 | /* |
708 | * Map some portion of the allocated scatterlist to an iovec, suitable for | 726 | * Map some portion of the allocated scatterlist to an iovec, suitable for |
@@ -761,6 +779,9 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) | |||
761 | 779 | ||
762 | conn->exp_statsn = exp_statsn; | 780 | conn->exp_statsn = exp_statsn; |
763 | 781 | ||
782 | if (conn->sess->sess_ops->RDMAExtensions) | ||
783 | return; | ||
784 | |||
764 | spin_lock_bh(&conn->cmd_lock); | 785 | spin_lock_bh(&conn->cmd_lock); |
765 | list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { | 786 | list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { |
766 | spin_lock(&cmd->istate_lock); | 787 | spin_lock(&cmd->istate_lock); |
@@ -793,12 +814,10 @@ static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) | |||
793 | return 0; | 814 | return 0; |
794 | } | 815 | } |
795 | 816 | ||
796 | static int iscsit_handle_scsi_cmd( | 817 | int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, |
797 | struct iscsi_conn *conn, | 818 | unsigned char *buf) |
798 | unsigned char *buf) | ||
799 | { | 819 | { |
800 | int data_direction, payload_length, cmdsn_ret = 0, immed_ret; | 820 | int data_direction, payload_length; |
801 | struct iscsi_cmd *cmd = NULL; | ||
802 | struct iscsi_scsi_req *hdr; | 821 | struct iscsi_scsi_req *hdr; |
803 | int iscsi_task_attr; | 822 | int iscsi_task_attr; |
804 | int sam_task_attr; | 823 | int sam_task_attr; |
@@ -821,8 +840,8 @@ static int iscsit_handle_scsi_cmd( | |||
821 | !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) { | 840 | !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) { |
822 | pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL" | 841 | pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL" |
823 | " not set. Bad iSCSI Initiator.\n"); | 842 | " not set. Bad iSCSI Initiator.\n"); |
824 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1, | 843 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, |
825 | buf, conn); | 844 | 1, 1, buf, cmd); |
826 | } | 845 | } |
827 | 846 | ||
828 | if (((hdr->flags & ISCSI_FLAG_CMD_READ) || | 847 | if (((hdr->flags & ISCSI_FLAG_CMD_READ) || |
@@ -842,8 +861,8 @@ static int iscsit_handle_scsi_cmd( | |||
842 | pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE" | 861 | pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE" |
843 | " set when Expected Data Transfer Length is 0 for" | 862 | " set when Expected Data Transfer Length is 0 for" |
844 | " CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]); | 863 | " CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]); |
845 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1, | 864 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, |
846 | buf, conn); | 865 | 1, 1, buf, cmd); |
847 | } | 866 | } |
848 | done: | 867 | done: |
849 | 868 | ||
@@ -852,29 +871,29 @@ done: | |||
852 | pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE" | 871 | pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE" |
853 | " MUST be set if Expected Data Transfer Length is not 0." | 872 | " MUST be set if Expected Data Transfer Length is not 0." |
854 | " Bad iSCSI Initiator\n"); | 873 | " Bad iSCSI Initiator\n"); |
855 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1, | 874 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, |
856 | buf, conn); | 875 | 1, 1, buf, cmd); |
857 | } | 876 | } |
858 | 877 | ||
859 | if ((hdr->flags & ISCSI_FLAG_CMD_READ) && | 878 | if ((hdr->flags & ISCSI_FLAG_CMD_READ) && |
860 | (hdr->flags & ISCSI_FLAG_CMD_WRITE)) { | 879 | (hdr->flags & ISCSI_FLAG_CMD_WRITE)) { |
861 | pr_err("Bidirectional operations not supported!\n"); | 880 | pr_err("Bidirectional operations not supported!\n"); |
862 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1, | 881 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, |
863 | buf, conn); | 882 | 1, 1, buf, cmd); |
864 | } | 883 | } |
865 | 884 | ||
866 | if (hdr->opcode & ISCSI_OP_IMMEDIATE) { | 885 | if (hdr->opcode & ISCSI_OP_IMMEDIATE) { |
867 | pr_err("Illegally set Immediate Bit in iSCSI Initiator" | 886 | pr_err("Illegally set Immediate Bit in iSCSI Initiator" |
868 | " Scsi Command PDU.\n"); | 887 | " Scsi Command PDU.\n"); |
869 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1, | 888 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, |
870 | buf, conn); | 889 | 1, 1, buf, cmd); |
871 | } | 890 | } |
872 | 891 | ||
873 | if (payload_length && !conn->sess->sess_ops->ImmediateData) { | 892 | if (payload_length && !conn->sess->sess_ops->ImmediateData) { |
874 | pr_err("ImmediateData=No but DataSegmentLength=%u," | 893 | pr_err("ImmediateData=No but DataSegmentLength=%u," |
875 | " protocol error.\n", payload_length); | 894 | " protocol error.\n", payload_length); |
876 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 895 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, |
877 | buf, conn); | 896 | 1, 1, buf, cmd); |
878 | } | 897 | } |
879 | 898 | ||
880 | if ((be32_to_cpu(hdr->data_length )== payload_length) && | 899 | if ((be32_to_cpu(hdr->data_length )== payload_length) && |
@@ -882,43 +901,38 @@ done: | |||
882 | pr_err("Expected Data Transfer Length and Length of" | 901 | pr_err("Expected Data Transfer Length and Length of" |
883 | " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL" | 902 | " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL" |
884 | " bit is not set protocol error\n"); | 903 | " bit is not set protocol error\n"); |
885 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 904 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, |
886 | buf, conn); | 905 | 1, 1, buf, cmd); |
887 | } | 906 | } |
888 | 907 | ||
889 | if (payload_length > be32_to_cpu(hdr->data_length)) { | 908 | if (payload_length > be32_to_cpu(hdr->data_length)) { |
890 | pr_err("DataSegmentLength: %u is greater than" | 909 | pr_err("DataSegmentLength: %u is greater than" |
891 | " EDTL: %u, protocol error.\n", payload_length, | 910 | " EDTL: %u, protocol error.\n", payload_length, |
892 | hdr->data_length); | 911 | hdr->data_length); |
893 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 912 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, |
894 | buf, conn); | 913 | 1, 1, buf, cmd); |
895 | } | 914 | } |
896 | 915 | ||
897 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { | 916 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { |
898 | pr_err("DataSegmentLength: %u is greater than" | 917 | pr_err("DataSegmentLength: %u is greater than" |
899 | " MaxXmitDataSegmentLength: %u, protocol error.\n", | 918 | " MaxXmitDataSegmentLength: %u, protocol error.\n", |
900 | payload_length, conn->conn_ops->MaxXmitDataSegmentLength); | 919 | payload_length, conn->conn_ops->MaxXmitDataSegmentLength); |
901 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 920 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, |
902 | buf, conn); | 921 | 1, 1, buf, cmd); |
903 | } | 922 | } |
904 | 923 | ||
905 | if (payload_length > conn->sess->sess_ops->FirstBurstLength) { | 924 | if (payload_length > conn->sess->sess_ops->FirstBurstLength) { |
906 | pr_err("DataSegmentLength: %u is greater than" | 925 | pr_err("DataSegmentLength: %u is greater than" |
907 | " FirstBurstLength: %u, protocol error.\n", | 926 | " FirstBurstLength: %u, protocol error.\n", |
908 | payload_length, conn->sess->sess_ops->FirstBurstLength); | 927 | payload_length, conn->sess->sess_ops->FirstBurstLength); |
909 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1, | 928 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, |
910 | buf, conn); | 929 | 1, 1, buf, cmd); |
911 | } | 930 | } |
912 | 931 | ||
913 | data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : | 932 | data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : |
914 | (hdr->flags & ISCSI_FLAG_CMD_READ) ? DMA_FROM_DEVICE : | 933 | (hdr->flags & ISCSI_FLAG_CMD_READ) ? DMA_FROM_DEVICE : |
915 | DMA_NONE; | 934 | DMA_NONE; |
916 | 935 | ||
917 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | ||
918 | if (!cmd) | ||
919 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, 1, | ||
920 | buf, conn); | ||
921 | |||
922 | cmd->data_direction = data_direction; | 936 | cmd->data_direction = data_direction; |
923 | iscsi_task_attr = hdr->flags & ISCSI_FLAG_CMD_ATTR_MASK; | 937 | iscsi_task_attr = hdr->flags & ISCSI_FLAG_CMD_ATTR_MASK; |
924 | /* | 938 | /* |
@@ -961,7 +975,8 @@ done: | |||
961 | cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); | 975 | cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); |
962 | cmd->first_burst_len = payload_length; | 976 | cmd->first_burst_len = payload_length; |
963 | 977 | ||
964 | if (cmd->data_direction == DMA_FROM_DEVICE) { | 978 | if (!conn->sess->sess_ops->RDMAExtensions && |
979 | cmd->data_direction == DMA_FROM_DEVICE) { | ||
965 | struct iscsi_datain_req *dr; | 980 | struct iscsi_datain_req *dr; |
966 | 981 | ||
967 | dr = iscsit_allocate_datain_req(); | 982 | dr = iscsit_allocate_datain_req(); |
@@ -983,7 +998,10 @@ done: | |||
983 | 998 | ||
984 | pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x," | 999 | pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x," |
985 | " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, | 1000 | " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, |
986 | hdr->cmdsn, hdr->data_length, payload_length, conn->cid); | 1001 | hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length, |
1002 | conn->cid); | ||
1003 | |||
1004 | target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true); | ||
987 | 1005 | ||
988 | cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd, | 1006 | cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd, |
989 | scsilun_to_int(&hdr->lun)); | 1007 | scsilun_to_int(&hdr->lun)); |
@@ -1017,12 +1035,24 @@ attach_cmd: | |||
1017 | */ | 1035 | */ |
1018 | core_alua_check_nonop_delay(&cmd->se_cmd); | 1036 | core_alua_check_nonop_delay(&cmd->se_cmd); |
1019 | 1037 | ||
1020 | if (iscsit_allocate_iovecs(cmd) < 0) { | 1038 | return 0; |
1021 | return iscsit_add_reject_from_cmd( | 1039 | } |
1022 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1040 | EXPORT_SYMBOL(iscsit_setup_scsi_cmd); |
1023 | 1, 0, buf, cmd); | ||
1024 | } | ||
1025 | 1041 | ||
1042 | void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *cmd) | ||
1043 | { | ||
1044 | iscsit_set_dataout_sequence_values(cmd); | ||
1045 | |||
1046 | spin_lock_bh(&cmd->dataout_timeout_lock); | ||
1047 | iscsit_start_dataout_timer(cmd, cmd->conn); | ||
1048 | spin_unlock_bh(&cmd->dataout_timeout_lock); | ||
1049 | } | ||
1050 | EXPORT_SYMBOL(iscsit_set_unsoliticed_dataout); | ||
1051 | |||
1052 | int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | ||
1053 | struct iscsi_scsi_req *hdr) | ||
1054 | { | ||
1055 | int cmdsn_ret = 0; | ||
1026 | /* | 1056 | /* |
1027 | * Check the CmdSN against ExpCmdSN/MaxCmdSN here if | 1057 | * Check the CmdSN against ExpCmdSN/MaxCmdSN here if |
1028 | * the Immediate Bit is not set, and no Immediate | 1058 | * the Immediate Bit is not set, and no Immediate |
@@ -1035,12 +1065,17 @@ attach_cmd: | |||
1035 | */ | 1065 | */ |
1036 | if (!cmd->immediate_data) { | 1066 | if (!cmd->immediate_data) { |
1037 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); | 1067 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); |
1038 | if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) | 1068 | if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) { |
1069 | if (!cmd->sense_reason) | ||
1070 | return 0; | ||
1071 | |||
1072 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | ||
1039 | return 0; | 1073 | return 0; |
1040 | else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | 1074 | } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) { |
1041 | return iscsit_add_reject_from_cmd( | 1075 | return iscsit_add_reject_from_cmd( |
1042 | ISCSI_REASON_PROTOCOL_ERROR, | 1076 | ISCSI_REASON_PROTOCOL_ERROR, |
1043 | 1, 0, buf, cmd); | 1077 | 1, 0, (unsigned char *)hdr, cmd); |
1078 | } | ||
1044 | } | 1079 | } |
1045 | 1080 | ||
1046 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); | 1081 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); |
@@ -1049,25 +1084,23 @@ attach_cmd: | |||
1049 | * If no Immediate Data is attached, it's OK to return now. | 1084 | * If no Immediate Data is attached, it's OK to return now. |
1050 | */ | 1085 | */ |
1051 | if (!cmd->immediate_data) { | 1086 | if (!cmd->immediate_data) { |
1052 | if (!cmd->sense_reason && cmd->unsolicited_data) { | 1087 | if (!cmd->sense_reason && cmd->unsolicited_data) |
1053 | iscsit_set_dataout_sequence_values(cmd); | 1088 | iscsit_set_unsoliticed_dataout(cmd); |
1054 | 1089 | if (!cmd->sense_reason) | |
1055 | spin_lock_bh(&cmd->dataout_timeout_lock); | 1090 | return 0; |
1056 | iscsit_start_dataout_timer(cmd, cmd->conn); | ||
1057 | spin_unlock_bh(&cmd->dataout_timeout_lock); | ||
1058 | } | ||
1059 | 1091 | ||
1092 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | ||
1060 | return 0; | 1093 | return 0; |
1061 | } | 1094 | } |
1062 | 1095 | ||
1063 | /* | 1096 | /* |
1064 | * Early CHECK_CONDITIONs never make it to the transport processing | 1097 | * Early CHECK_CONDITIONs with ImmediateData never make it to command |
1065 | * thread. They are processed in CmdSN order by | 1098 | * execution. These exceptions are processed in CmdSN order using |
1066 | * iscsit_check_received_cmdsn() below. | 1099 | * iscsit_check_received_cmdsn() in iscsit_get_immediate_data() below. |
1067 | */ | 1100 | */ |
1068 | if (cmd->sense_reason) { | 1101 | if (cmd->sense_reason) { |
1069 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; | 1102 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); |
1070 | goto after_immediate_data; | 1103 | return 1; |
1071 | } | 1104 | } |
1072 | /* | 1105 | /* |
1073 | * Call directly into transport_generic_new_cmd() to perform | 1106 | * Call directly into transport_generic_new_cmd() to perform |
@@ -1075,11 +1108,27 @@ attach_cmd: | |||
1075 | */ | 1108 | */ |
1076 | cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd); | 1109 | cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd); |
1077 | if (cmd->sense_reason) { | 1110 | if (cmd->sense_reason) { |
1078 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; | 1111 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); |
1079 | goto after_immediate_data; | 1112 | return 1; |
1080 | } | 1113 | } |
1081 | 1114 | ||
1082 | immed_ret = iscsit_handle_immediate_data(cmd, buf, payload_length); | 1115 | return 0; |
1116 | } | ||
1117 | EXPORT_SYMBOL(iscsit_process_scsi_cmd); | ||
1118 | |||
1119 | static int | ||
1120 | iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr, | ||
1121 | bool dump_payload) | ||
1122 | { | ||
1123 | int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; | ||
1124 | /* | ||
1125 | * Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes. | ||
1126 | */ | ||
1127 | if (dump_payload == true) | ||
1128 | goto after_immediate_data; | ||
1129 | |||
1130 | immed_ret = iscsit_handle_immediate_data(cmd, hdr, | ||
1131 | cmd->first_burst_len); | ||
1083 | after_immediate_data: | 1132 | after_immediate_data: |
1084 | if (immed_ret == IMMEDIATE_DATA_NORMAL_OPERATION) { | 1133 | if (immed_ret == IMMEDIATE_DATA_NORMAL_OPERATION) { |
1085 | /* | 1134 | /* |
@@ -1087,26 +1136,19 @@ after_immediate_data: | |||
1087 | * DataCRC, check against ExpCmdSN/MaxCmdSN if | 1136 | * DataCRC, check against ExpCmdSN/MaxCmdSN if |
1088 | * Immediate Bit is not set. | 1137 | * Immediate Bit is not set. |
1089 | */ | 1138 | */ |
1090 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); | 1139 | cmdsn_ret = iscsit_sequence_cmd(cmd->conn, cmd, hdr->cmdsn); |
1091 | /* | 1140 | |
1092 | * Special case for Unsupported SAM WRITE Opcodes | ||
1093 | * and ImmediateData=Yes. | ||
1094 | */ | ||
1095 | if (cmd->sense_reason) { | 1141 | if (cmd->sense_reason) { |
1096 | if (iscsit_dump_data_payload(conn, payload_length, 1) < 0) | 1142 | if (iscsit_dump_data_payload(cmd->conn, |
1143 | cmd->first_burst_len, 1) < 0) | ||
1097 | return -1; | 1144 | return -1; |
1098 | } else if (cmd->unsolicited_data) { | 1145 | } else if (cmd->unsolicited_data) |
1099 | iscsit_set_dataout_sequence_values(cmd); | 1146 | iscsit_set_unsoliticed_dataout(cmd); |
1100 | |||
1101 | spin_lock_bh(&cmd->dataout_timeout_lock); | ||
1102 | iscsit_start_dataout_timer(cmd, cmd->conn); | ||
1103 | spin_unlock_bh(&cmd->dataout_timeout_lock); | ||
1104 | } | ||
1105 | 1147 | ||
1106 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | 1148 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) |
1107 | return iscsit_add_reject_from_cmd( | 1149 | return iscsit_add_reject_from_cmd( |
1108 | ISCSI_REASON_PROTOCOL_ERROR, | 1150 | ISCSI_REASON_PROTOCOL_ERROR, |
1109 | 1, 0, buf, cmd); | 1151 | 1, 0, (unsigned char *)hdr, cmd); |
1110 | 1152 | ||
1111 | } else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) { | 1153 | } else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) { |
1112 | /* | 1154 | /* |
@@ -1121,13 +1163,47 @@ after_immediate_data: | |||
1121 | * CmdSN and issue a retry to plug the sequence. | 1163 | * CmdSN and issue a retry to plug the sequence. |
1122 | */ | 1164 | */ |
1123 | cmd->i_state = ISTATE_REMOVE; | 1165 | cmd->i_state = ISTATE_REMOVE; |
1124 | iscsit_add_cmd_to_immediate_queue(cmd, conn, cmd->i_state); | 1166 | iscsit_add_cmd_to_immediate_queue(cmd, cmd->conn, cmd->i_state); |
1125 | } else /* immed_ret == IMMEDIATE_DATA_CANNOT_RECOVER */ | 1167 | } else /* immed_ret == IMMEDIATE_DATA_CANNOT_RECOVER */ |
1126 | return -1; | 1168 | return -1; |
1127 | 1169 | ||
1128 | return 0; | 1170 | return 0; |
1129 | } | 1171 | } |
1130 | 1172 | ||
1173 | static int | ||
1174 | iscsit_handle_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | ||
1175 | unsigned char *buf) | ||
1176 | { | ||
1177 | struct iscsi_scsi_req *hdr = (struct iscsi_scsi_req *)buf; | ||
1178 | int rc, immed_data; | ||
1179 | bool dump_payload = false; | ||
1180 | |||
1181 | rc = iscsit_setup_scsi_cmd(conn, cmd, buf); | ||
1182 | if (rc < 0) | ||
1183 | return rc; | ||
1184 | /* | ||
1185 | * Allocation iovecs needed for struct socket operations for | ||
1186 | * traditional iSCSI block I/O. | ||
1187 | */ | ||
1188 | if (iscsit_allocate_iovecs(cmd) < 0) { | ||
1189 | return iscsit_add_reject_from_cmd( | ||
1190 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
1191 | 1, 0, buf, cmd); | ||
1192 | } | ||
1193 | immed_data = cmd->immediate_data; | ||
1194 | |||
1195 | rc = iscsit_process_scsi_cmd(conn, cmd, hdr); | ||
1196 | if (rc < 0) | ||
1197 | return rc; | ||
1198 | else if (rc > 0) | ||
1199 | dump_payload = true; | ||
1200 | |||
1201 | if (!immed_data) | ||
1202 | return 0; | ||
1203 | |||
1204 | return iscsit_get_immediate_data(cmd, hdr, dump_payload); | ||
1205 | } | ||
1206 | |||
1131 | static u32 iscsit_do_crypto_hash_sg( | 1207 | static u32 iscsit_do_crypto_hash_sg( |
1132 | struct hash_desc *hash, | 1208 | struct hash_desc *hash, |
1133 | struct iscsi_cmd *cmd, | 1209 | struct iscsi_cmd *cmd, |
@@ -1190,20 +1266,16 @@ static void iscsit_do_crypto_hash_buf( | |||
1190 | crypto_hash_final(hash, data_crc); | 1266 | crypto_hash_final(hash, data_crc); |
1191 | } | 1267 | } |
1192 | 1268 | ||
1193 | static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | 1269 | int |
1270 | iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, | ||
1271 | struct iscsi_cmd **out_cmd) | ||
1194 | { | 1272 | { |
1195 | int iov_ret, ooo_cmdsn = 0, ret; | 1273 | struct iscsi_data *hdr = (struct iscsi_data *)buf; |
1196 | u8 data_crc_failed = 0; | ||
1197 | u32 checksum, iov_count = 0, padding = 0, rx_got = 0; | ||
1198 | u32 rx_size = 0, payload_length; | ||
1199 | struct iscsi_cmd *cmd = NULL; | 1274 | struct iscsi_cmd *cmd = NULL; |
1200 | struct se_cmd *se_cmd; | 1275 | struct se_cmd *se_cmd; |
1201 | struct iscsi_data *hdr; | ||
1202 | struct kvec *iov; | ||
1203 | unsigned long flags; | 1276 | unsigned long flags; |
1204 | 1277 | u32 payload_length = ntoh24(hdr->dlength); | |
1205 | hdr = (struct iscsi_data *) buf; | 1278 | int rc; |
1206 | payload_length = ntoh24(hdr->dlength); | ||
1207 | 1279 | ||
1208 | if (!payload_length) { | 1280 | if (!payload_length) { |
1209 | pr_err("DataOUT payload is ZERO, protocol error.\n"); | 1281 | pr_err("DataOUT payload is ZERO, protocol error.\n"); |
@@ -1236,7 +1308,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | |||
1236 | 1308 | ||
1237 | pr_debug("Got DataOut ITT: 0x%08x, TTT: 0x%08x," | 1309 | pr_debug("Got DataOut ITT: 0x%08x, TTT: 0x%08x," |
1238 | " DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n", | 1310 | " DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n", |
1239 | hdr->itt, hdr->ttt, hdr->datasn, hdr->offset, | 1311 | hdr->itt, hdr->ttt, hdr->datasn, ntohl(hdr->offset), |
1240 | payload_length, conn->cid); | 1312 | payload_length, conn->cid); |
1241 | 1313 | ||
1242 | if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) { | 1314 | if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) { |
@@ -1328,12 +1400,26 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | |||
1328 | * Preform DataSN, DataSequenceInOrder, DataPDUInOrder, and | 1400 | * Preform DataSN, DataSequenceInOrder, DataPDUInOrder, and |
1329 | * within-command recovery checks before receiving the payload. | 1401 | * within-command recovery checks before receiving the payload. |
1330 | */ | 1402 | */ |
1331 | ret = iscsit_check_pre_dataout(cmd, buf); | 1403 | rc = iscsit_check_pre_dataout(cmd, buf); |
1332 | if (ret == DATAOUT_WITHIN_COMMAND_RECOVERY) | 1404 | if (rc == DATAOUT_WITHIN_COMMAND_RECOVERY) |
1333 | return 0; | 1405 | return 0; |
1334 | else if (ret == DATAOUT_CANNOT_RECOVER) | 1406 | else if (rc == DATAOUT_CANNOT_RECOVER) |
1335 | return -1; | 1407 | return -1; |
1336 | 1408 | ||
1409 | *out_cmd = cmd; | ||
1410 | return 0; | ||
1411 | } | ||
1412 | EXPORT_SYMBOL(iscsit_check_dataout_hdr); | ||
1413 | |||
1414 | static int | ||
1415 | iscsit_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | ||
1416 | struct iscsi_data *hdr) | ||
1417 | { | ||
1418 | struct kvec *iov; | ||
1419 | u32 checksum, iov_count = 0, padding = 0, rx_got = 0, rx_size = 0; | ||
1420 | u32 payload_length = ntoh24(hdr->dlength); | ||
1421 | int iov_ret, data_crc_failed = 0; | ||
1422 | |||
1337 | rx_size += payload_length; | 1423 | rx_size += payload_length; |
1338 | iov = &cmd->iov_data[0]; | 1424 | iov = &cmd->iov_data[0]; |
1339 | 1425 | ||
@@ -1386,17 +1472,27 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | |||
1386 | payload_length); | 1472 | payload_length); |
1387 | } | 1473 | } |
1388 | } | 1474 | } |
1475 | |||
1476 | return data_crc_failed; | ||
1477 | } | ||
1478 | |||
1479 | int | ||
1480 | iscsit_check_dataout_payload(struct iscsi_cmd *cmd, struct iscsi_data *hdr, | ||
1481 | bool data_crc_failed) | ||
1482 | { | ||
1483 | struct iscsi_conn *conn = cmd->conn; | ||
1484 | int rc, ooo_cmdsn; | ||
1389 | /* | 1485 | /* |
1390 | * Increment post receive data and CRC values or perform | 1486 | * Increment post receive data and CRC values or perform |
1391 | * within-command recovery. | 1487 | * within-command recovery. |
1392 | */ | 1488 | */ |
1393 | ret = iscsit_check_post_dataout(cmd, buf, data_crc_failed); | 1489 | rc = iscsit_check_post_dataout(cmd, (unsigned char *)hdr, data_crc_failed); |
1394 | if ((ret == DATAOUT_NORMAL) || (ret == DATAOUT_WITHIN_COMMAND_RECOVERY)) | 1490 | if ((rc == DATAOUT_NORMAL) || (rc == DATAOUT_WITHIN_COMMAND_RECOVERY)) |
1395 | return 0; | 1491 | return 0; |
1396 | else if (ret == DATAOUT_SEND_R2T) { | 1492 | else if (rc == DATAOUT_SEND_R2T) { |
1397 | iscsit_set_dataout_sequence_values(cmd); | 1493 | iscsit_set_dataout_sequence_values(cmd); |
1398 | iscsit_build_r2ts_for_cmd(cmd, conn, false); | 1494 | conn->conn_transport->iscsit_get_dataout(conn, cmd, false); |
1399 | } else if (ret == DATAOUT_SEND_TO_TRANSPORT) { | 1495 | } else if (rc == DATAOUT_SEND_TO_TRANSPORT) { |
1400 | /* | 1496 | /* |
1401 | * Handle extra special case for out of order | 1497 | * Handle extra special case for out of order |
1402 | * Unsolicited Data Out. | 1498 | * Unsolicited Data Out. |
@@ -1417,15 +1513,37 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | |||
1417 | 1513 | ||
1418 | return 0; | 1514 | return 0; |
1419 | } | 1515 | } |
1516 | EXPORT_SYMBOL(iscsit_check_dataout_payload); | ||
1420 | 1517 | ||
1421 | static int iscsit_handle_nop_out( | 1518 | static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) |
1422 | struct iscsi_conn *conn, | 1519 | { |
1423 | unsigned char *buf) | 1520 | struct iscsi_cmd *cmd; |
1521 | struct iscsi_data *hdr = (struct iscsi_data *)buf; | ||
1522 | int rc; | ||
1523 | bool data_crc_failed = false; | ||
1524 | |||
1525 | rc = iscsit_check_dataout_hdr(conn, buf, &cmd); | ||
1526 | if (rc < 0) | ||
1527 | return rc; | ||
1528 | else if (!cmd) | ||
1529 | return 0; | ||
1530 | |||
1531 | rc = iscsit_get_dataout(conn, cmd, hdr); | ||
1532 | if (rc < 0) | ||
1533 | return rc; | ||
1534 | else if (rc > 0) | ||
1535 | data_crc_failed = true; | ||
1536 | |||
1537 | return iscsit_check_dataout_payload(cmd, hdr, data_crc_failed); | ||
1538 | } | ||
1539 | |||
1540 | int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | ||
1541 | unsigned char *buf) | ||
1424 | { | 1542 | { |
1425 | unsigned char *ping_data = NULL; | 1543 | unsigned char *ping_data = NULL; |
1426 | int cmdsn_ret, niov = 0, ret = 0, rx_got, rx_size; | 1544 | int cmdsn_ret, niov = 0, ret = 0, rx_got, rx_size; |
1427 | u32 checksum, data_crc, padding = 0, payload_length; | 1545 | u32 checksum, data_crc, padding = 0, payload_length; |
1428 | struct iscsi_cmd *cmd = NULL; | 1546 | struct iscsi_cmd *cmd_p = NULL; |
1429 | struct kvec *iov = NULL; | 1547 | struct kvec *iov = NULL; |
1430 | struct iscsi_nopout *hdr; | 1548 | struct iscsi_nopout *hdr; |
1431 | 1549 | ||
@@ -1448,7 +1566,7 @@ static int iscsit_handle_nop_out( | |||
1448 | buf, conn); | 1566 | buf, conn); |
1449 | } | 1567 | } |
1450 | 1568 | ||
1451 | pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%09x," | 1569 | pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%08x," |
1452 | " CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n", | 1570 | " CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n", |
1453 | hdr->itt == RESERVED_ITT ? "Response" : "Request", | 1571 | hdr->itt == RESERVED_ITT ? "Response" : "Request", |
1454 | hdr->itt, hdr->ttt, hdr->cmdsn, hdr->exp_statsn, | 1572 | hdr->itt, hdr->ttt, hdr->cmdsn, hdr->exp_statsn, |
@@ -1461,7 +1579,6 @@ static int iscsit_handle_nop_out( | |||
1461 | * can contain ping data. | 1579 | * can contain ping data. |
1462 | */ | 1580 | */ |
1463 | if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { | 1581 | if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { |
1464 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | ||
1465 | if (!cmd) | 1582 | if (!cmd) |
1466 | return iscsit_add_reject( | 1583 | return iscsit_add_reject( |
1467 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1584 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
@@ -1596,14 +1713,14 @@ static int iscsit_handle_nop_out( | |||
1596 | /* | 1713 | /* |
1597 | * This was a response to a unsolicited NOPIN ping. | 1714 | * This was a response to a unsolicited NOPIN ping. |
1598 | */ | 1715 | */ |
1599 | cmd = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt)); | 1716 | cmd_p = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt)); |
1600 | if (!cmd) | 1717 | if (!cmd_p) |
1601 | return -1; | 1718 | return -1; |
1602 | 1719 | ||
1603 | iscsit_stop_nopin_response_timer(conn); | 1720 | iscsit_stop_nopin_response_timer(conn); |
1604 | 1721 | ||
1605 | cmd->i_state = ISTATE_REMOVE; | 1722 | cmd_p->i_state = ISTATE_REMOVE; |
1606 | iscsit_add_cmd_to_immediate_queue(cmd, conn, cmd->i_state); | 1723 | iscsit_add_cmd_to_immediate_queue(cmd_p, conn, cmd_p->i_state); |
1607 | iscsit_start_nopin_timer(conn); | 1724 | iscsit_start_nopin_timer(conn); |
1608 | } else { | 1725 | } else { |
1609 | /* | 1726 | /* |
@@ -1627,12 +1744,12 @@ ping_out: | |||
1627 | kfree(ping_data); | 1744 | kfree(ping_data); |
1628 | return ret; | 1745 | return ret; |
1629 | } | 1746 | } |
1747 | EXPORT_SYMBOL(iscsit_handle_nop_out); | ||
1630 | 1748 | ||
1631 | static int iscsit_handle_task_mgt_cmd( | 1749 | int |
1632 | struct iscsi_conn *conn, | 1750 | iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, |
1633 | unsigned char *buf) | 1751 | unsigned char *buf) |
1634 | { | 1752 | { |
1635 | struct iscsi_cmd *cmd; | ||
1636 | struct se_tmr_req *se_tmr; | 1753 | struct se_tmr_req *se_tmr; |
1637 | struct iscsi_tmr_req *tmr_req; | 1754 | struct iscsi_tmr_req *tmr_req; |
1638 | struct iscsi_tm *hdr; | 1755 | struct iscsi_tm *hdr; |
@@ -1661,18 +1778,13 @@ static int iscsit_handle_task_mgt_cmd( | |||
1661 | pr_err("Task Management Request TASK_REASSIGN not" | 1778 | pr_err("Task Management Request TASK_REASSIGN not" |
1662 | " issued as immediate command, bad iSCSI Initiator" | 1779 | " issued as immediate command, bad iSCSI Initiator" |
1663 | "implementation\n"); | 1780 | "implementation\n"); |
1664 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 1781 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, |
1665 | buf, conn); | 1782 | 1, 1, buf, cmd); |
1666 | } | 1783 | } |
1667 | if ((function != ISCSI_TM_FUNC_ABORT_TASK) && | 1784 | if ((function != ISCSI_TM_FUNC_ABORT_TASK) && |
1668 | be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG) | 1785 | be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG) |
1669 | hdr->refcmdsn = cpu_to_be32(ISCSI_RESERVED_TAG); | 1786 | hdr->refcmdsn = cpu_to_be32(ISCSI_RESERVED_TAG); |
1670 | 1787 | ||
1671 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | ||
1672 | if (!cmd) | ||
1673 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
1674 | 1, buf, conn); | ||
1675 | |||
1676 | cmd->data_direction = DMA_NONE; | 1788 | cmd->data_direction = DMA_NONE; |
1677 | 1789 | ||
1678 | cmd->tmr_req = kzalloc(sizeof(struct iscsi_tmr_req), GFP_KERNEL); | 1790 | cmd->tmr_req = kzalloc(sizeof(struct iscsi_tmr_req), GFP_KERNEL); |
@@ -1843,6 +1955,7 @@ attach: | |||
1843 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); | 1955 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); |
1844 | return 0; | 1956 | return 0; |
1845 | } | 1957 | } |
1958 | EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd); | ||
1846 | 1959 | ||
1847 | /* #warning FIXME: Support Text Command parameters besides SendTargets */ | 1960 | /* #warning FIXME: Support Text Command parameters besides SendTargets */ |
1848 | static int iscsit_handle_text_cmd( | 1961 | static int iscsit_handle_text_cmd( |
@@ -2105,13 +2218,12 @@ int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *cmd, struct iscsi_conn | |||
2105 | return 0; | 2218 | return 0; |
2106 | } | 2219 | } |
2107 | 2220 | ||
2108 | static int iscsit_handle_logout_cmd( | 2221 | int |
2109 | struct iscsi_conn *conn, | 2222 | iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, |
2110 | unsigned char *buf) | 2223 | unsigned char *buf) |
2111 | { | 2224 | { |
2112 | int cmdsn_ret, logout_remove = 0; | 2225 | int cmdsn_ret, logout_remove = 0; |
2113 | u8 reason_code = 0; | 2226 | u8 reason_code = 0; |
2114 | struct iscsi_cmd *cmd; | ||
2115 | struct iscsi_logout *hdr; | 2227 | struct iscsi_logout *hdr; |
2116 | struct iscsi_tiqn *tiqn = iscsit_snmp_get_tiqn(conn); | 2228 | struct iscsi_tiqn *tiqn = iscsit_snmp_get_tiqn(conn); |
2117 | 2229 | ||
@@ -2135,14 +2247,10 @@ static int iscsit_handle_logout_cmd( | |||
2135 | if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) { | 2247 | if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) { |
2136 | pr_err("Received logout request on connection that" | 2248 | pr_err("Received logout request on connection that" |
2137 | " is not in logged in state, ignoring request.\n"); | 2249 | " is not in logged in state, ignoring request.\n"); |
2250 | iscsit_release_cmd(cmd); | ||
2138 | return 0; | 2251 | return 0; |
2139 | } | 2252 | } |
2140 | 2253 | ||
2141 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | ||
2142 | if (!cmd) | ||
2143 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, 1, | ||
2144 | buf, conn); | ||
2145 | |||
2146 | cmd->iscsi_opcode = ISCSI_OP_LOGOUT; | 2254 | cmd->iscsi_opcode = ISCSI_OP_LOGOUT; |
2147 | cmd->i_state = ISTATE_SEND_LOGOUTRSP; | 2255 | cmd->i_state = ISTATE_SEND_LOGOUTRSP; |
2148 | cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); | 2256 | cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); |
@@ -2192,6 +2300,7 @@ static int iscsit_handle_logout_cmd( | |||
2192 | 2300 | ||
2193 | return logout_remove; | 2301 | return logout_remove; |
2194 | } | 2302 | } |
2303 | EXPORT_SYMBOL(iscsit_handle_logout_cmd); | ||
2195 | 2304 | ||
2196 | static int iscsit_handle_snack( | 2305 | static int iscsit_handle_snack( |
2197 | struct iscsi_conn *conn, | 2306 | struct iscsi_conn *conn, |
@@ -2259,7 +2368,7 @@ static void iscsit_rx_thread_wait_for_tcp(struct iscsi_conn *conn) | |||
2259 | 2368 | ||
2260 | static int iscsit_handle_immediate_data( | 2369 | static int iscsit_handle_immediate_data( |
2261 | struct iscsi_cmd *cmd, | 2370 | struct iscsi_cmd *cmd, |
2262 | unsigned char *buf, | 2371 | struct iscsi_scsi_req *hdr, |
2263 | u32 length) | 2372 | u32 length) |
2264 | { | 2373 | { |
2265 | int iov_ret, rx_got = 0, rx_size = 0; | 2374 | int iov_ret, rx_got = 0, rx_size = 0; |
@@ -2315,12 +2424,12 @@ static int iscsit_handle_immediate_data( | |||
2315 | " in ERL=0.\n"); | 2424 | " in ERL=0.\n"); |
2316 | iscsit_add_reject_from_cmd( | 2425 | iscsit_add_reject_from_cmd( |
2317 | ISCSI_REASON_DATA_DIGEST_ERROR, | 2426 | ISCSI_REASON_DATA_DIGEST_ERROR, |
2318 | 1, 0, buf, cmd); | 2427 | 1, 0, (unsigned char *)hdr, cmd); |
2319 | return IMMEDIATE_DATA_CANNOT_RECOVER; | 2428 | return IMMEDIATE_DATA_CANNOT_RECOVER; |
2320 | } else { | 2429 | } else { |
2321 | iscsit_add_reject_from_cmd( | 2430 | iscsit_add_reject_from_cmd( |
2322 | ISCSI_REASON_DATA_DIGEST_ERROR, | 2431 | ISCSI_REASON_DATA_DIGEST_ERROR, |
2323 | 0, 0, buf, cmd); | 2432 | 0, 0, (unsigned char *)hdr, cmd); |
2324 | return IMMEDIATE_DATA_ERL1_CRC_FAILURE; | 2433 | return IMMEDIATE_DATA_ERL1_CRC_FAILURE; |
2325 | } | 2434 | } |
2326 | } else { | 2435 | } else { |
@@ -2955,8 +3064,8 @@ static int iscsit_send_r2t( | |||
2955 | * connection recovery. | 3064 | * connection recovery. |
2956 | */ | 3065 | */ |
2957 | int iscsit_build_r2ts_for_cmd( | 3066 | int iscsit_build_r2ts_for_cmd( |
2958 | struct iscsi_cmd *cmd, | ||
2959 | struct iscsi_conn *conn, | 3067 | struct iscsi_conn *conn, |
3068 | struct iscsi_cmd *cmd, | ||
2960 | bool recovery) | 3069 | bool recovery) |
2961 | { | 3070 | { |
2962 | int first_r2t = 1; | 3071 | int first_r2t = 1; |
@@ -3758,6 +3867,83 @@ out: | |||
3758 | return 0; | 3867 | return 0; |
3759 | } | 3868 | } |
3760 | 3869 | ||
3870 | static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) | ||
3871 | { | ||
3872 | struct iscsi_hdr *hdr = (struct iscsi_hdr *)buf; | ||
3873 | struct iscsi_cmd *cmd; | ||
3874 | int ret = 0; | ||
3875 | |||
3876 | switch (hdr->opcode & ISCSI_OPCODE_MASK) { | ||
3877 | case ISCSI_OP_SCSI_CMD: | ||
3878 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | ||
3879 | if (!cmd) | ||
3880 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
3881 | 1, buf, conn); | ||
3882 | |||
3883 | ret = iscsit_handle_scsi_cmd(conn, cmd, buf); | ||
3884 | break; | ||
3885 | case ISCSI_OP_SCSI_DATA_OUT: | ||
3886 | ret = iscsit_handle_data_out(conn, buf); | ||
3887 | break; | ||
3888 | case ISCSI_OP_NOOP_OUT: | ||
3889 | cmd = NULL; | ||
3890 | if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { | ||
3891 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | ||
3892 | if (!cmd) | ||
3893 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
3894 | 1, buf, conn); | ||
3895 | } | ||
3896 | ret = iscsit_handle_nop_out(conn, cmd, buf); | ||
3897 | break; | ||
3898 | case ISCSI_OP_SCSI_TMFUNC: | ||
3899 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | ||
3900 | if (!cmd) | ||
3901 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
3902 | 1, buf, conn); | ||
3903 | |||
3904 | ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf); | ||
3905 | break; | ||
3906 | case ISCSI_OP_TEXT: | ||
3907 | ret = iscsit_handle_text_cmd(conn, buf); | ||
3908 | break; | ||
3909 | case ISCSI_OP_LOGOUT: | ||
3910 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | ||
3911 | if (!cmd) | ||
3912 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
3913 | 1, buf, conn); | ||
3914 | |||
3915 | ret = iscsit_handle_logout_cmd(conn, cmd, buf); | ||
3916 | if (ret > 0) | ||
3917 | wait_for_completion_timeout(&conn->conn_logout_comp, | ||
3918 | SECONDS_FOR_LOGOUT_COMP * HZ); | ||
3919 | break; | ||
3920 | case ISCSI_OP_SNACK: | ||
3921 | ret = iscsit_handle_snack(conn, buf); | ||
3922 | break; | ||
3923 | default: | ||
3924 | pr_err("Got unknown iSCSI OpCode: 0x%02x\n", hdr->opcode); | ||
3925 | if (!conn->sess->sess_ops->ErrorRecoveryLevel) { | ||
3926 | pr_err("Cannot recover from unknown" | ||
3927 | " opcode while ERL=0, closing iSCSI connection.\n"); | ||
3928 | return -1; | ||
3929 | } | ||
3930 | if (!conn->conn_ops->OFMarker) { | ||
3931 | pr_err("Unable to recover from unknown" | ||
3932 | " opcode while OFMarker=No, closing iSCSI" | ||
3933 | " connection.\n"); | ||
3934 | return -1; | ||
3935 | } | ||
3936 | if (iscsit_recover_from_unknown_opcode(conn) < 0) { | ||
3937 | pr_err("Unable to recover from unknown" | ||
3938 | " opcode, closing iSCSI connection.\n"); | ||
3939 | return -1; | ||
3940 | } | ||
3941 | break; | ||
3942 | } | ||
3943 | |||
3944 | return ret; | ||
3945 | } | ||
3946 | |||
3761 | int iscsi_target_rx_thread(void *arg) | 3947 | int iscsi_target_rx_thread(void *arg) |
3762 | { | 3948 | { |
3763 | int ret; | 3949 | int ret; |
@@ -3777,6 +3963,18 @@ restart: | |||
3777 | if (!conn) | 3963 | if (!conn) |
3778 | goto out; | 3964 | goto out; |
3779 | 3965 | ||
3966 | if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) { | ||
3967 | struct completion comp; | ||
3968 | int rc; | ||
3969 | |||
3970 | init_completion(&comp); | ||
3971 | rc = wait_for_completion_interruptible(&comp); | ||
3972 | if (rc < 0) | ||
3973 | goto transport_err; | ||
3974 | |||
3975 | goto out; | ||
3976 | } | ||
3977 | |||
3780 | while (!kthread_should_stop()) { | 3978 | while (!kthread_should_stop()) { |
3781 | /* | 3979 | /* |
3782 | * Ensure that both TX and RX per connection kthreads | 3980 | * Ensure that both TX and RX per connection kthreads |
@@ -3848,62 +4046,9 @@ restart: | |||
3848 | goto transport_err; | 4046 | goto transport_err; |
3849 | } | 4047 | } |
3850 | 4048 | ||
3851 | switch (opcode) { | 4049 | ret = iscsi_target_rx_opcode(conn, buffer); |
3852 | case ISCSI_OP_SCSI_CMD: | 4050 | if (ret < 0) |
3853 | if (iscsit_handle_scsi_cmd(conn, buffer) < 0) | 4051 | goto transport_err; |
3854 | goto transport_err; | ||
3855 | break; | ||
3856 | case ISCSI_OP_SCSI_DATA_OUT: | ||
3857 | if (iscsit_handle_data_out(conn, buffer) < 0) | ||
3858 | goto transport_err; | ||
3859 | break; | ||
3860 | case ISCSI_OP_NOOP_OUT: | ||
3861 | if (iscsit_handle_nop_out(conn, buffer) < 0) | ||
3862 | goto transport_err; | ||
3863 | break; | ||
3864 | case ISCSI_OP_SCSI_TMFUNC: | ||
3865 | if (iscsit_handle_task_mgt_cmd(conn, buffer) < 0) | ||
3866 | goto transport_err; | ||
3867 | break; | ||
3868 | case ISCSI_OP_TEXT: | ||
3869 | if (iscsit_handle_text_cmd(conn, buffer) < 0) | ||
3870 | goto transport_err; | ||
3871 | break; | ||
3872 | case ISCSI_OP_LOGOUT: | ||
3873 | ret = iscsit_handle_logout_cmd(conn, buffer); | ||
3874 | if (ret > 0) { | ||
3875 | wait_for_completion_timeout(&conn->conn_logout_comp, | ||
3876 | SECONDS_FOR_LOGOUT_COMP * HZ); | ||
3877 | goto transport_err; | ||
3878 | } else if (ret < 0) | ||
3879 | goto transport_err; | ||
3880 | break; | ||
3881 | case ISCSI_OP_SNACK: | ||
3882 | if (iscsit_handle_snack(conn, buffer) < 0) | ||
3883 | goto transport_err; | ||
3884 | break; | ||
3885 | default: | ||
3886 | pr_err("Got unknown iSCSI OpCode: 0x%02x\n", | ||
3887 | opcode); | ||
3888 | if (!conn->sess->sess_ops->ErrorRecoveryLevel) { | ||
3889 | pr_err("Cannot recover from unknown" | ||
3890 | " opcode while ERL=0, closing iSCSI connection" | ||
3891 | ".\n"); | ||
3892 | goto transport_err; | ||
3893 | } | ||
3894 | if (!conn->conn_ops->OFMarker) { | ||
3895 | pr_err("Unable to recover from unknown" | ||
3896 | " opcode while OFMarker=No, closing iSCSI" | ||
3897 | " connection.\n"); | ||
3898 | goto transport_err; | ||
3899 | } | ||
3900 | if (iscsit_recover_from_unknown_opcode(conn) < 0) { | ||
3901 | pr_err("Unable to recover from unknown" | ||
3902 | " opcode, closing iSCSI connection.\n"); | ||
3903 | goto transport_err; | ||
3904 | } | ||
3905 | break; | ||
3906 | } | ||
3907 | } | 4052 | } |
3908 | 4053 | ||
3909 | transport_err: | 4054 | transport_err: |
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index b1a1e6350707..a0050b2f294e 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h | |||
@@ -16,11 +16,12 @@ 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_add_reject_from_cmd(u8, int, int, unsigned char *, struct iscsi_cmd *); |
19 | extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); | ||
19 | extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *); | 20 | extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *); |
20 | extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); | 21 | extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); |
21 | extern int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *, struct iscsi_conn *); | 22 | extern int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *, struct iscsi_conn *); |
22 | extern int iscsit_send_async_msg(struct iscsi_conn *, u16, u8, u8); | 23 | extern int iscsit_send_async_msg(struct iscsi_conn *, u16, u8, u8); |
23 | extern int iscsit_build_r2ts_for_cmd(struct iscsi_cmd *, struct iscsi_conn *, bool recovery); | 24 | extern int iscsit_build_r2ts_for_cmd(struct iscsi_conn *, struct iscsi_cmd *, bool recovery); |
24 | extern void iscsit_thread_get_cpumask(struct iscsi_conn *); | 25 | extern void iscsit_thread_get_cpumask(struct iscsi_conn *); |
25 | extern int iscsi_target_tx_thread(void *); | 26 | extern int iscsi_target_tx_thread(void *); |
26 | extern int iscsi_target_rx_thread(void *); | 27 | extern int iscsi_target_rx_thread(void *); |
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index c78b824194e6..ce3d3210fe41 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c | |||
@@ -1543,9 +1543,10 @@ static int lio_queue_data_in(struct se_cmd *se_cmd) | |||
1543 | static int lio_write_pending(struct se_cmd *se_cmd) | 1543 | static int lio_write_pending(struct se_cmd *se_cmd) |
1544 | { | 1544 | { |
1545 | struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); | 1545 | struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); |
1546 | struct iscsi_conn *conn = cmd->conn; | ||
1546 | 1547 | ||
1547 | if (!cmd->immediate_data && !cmd->unsolicited_data) | 1548 | if (!cmd->immediate_data && !cmd->unsolicited_data) |
1548 | return iscsit_build_r2ts_for_cmd(cmd, cmd->conn, false); | 1549 | return conn->conn_transport->iscsit_get_dataout(conn, cmd, false); |
1549 | 1550 | ||
1550 | return 0; | 1551 | return 0; |
1551 | } | 1552 | } |
@@ -1696,6 +1697,11 @@ static void lio_set_default_node_attributes(struct se_node_acl *se_acl) | |||
1696 | iscsit_set_default_node_attribues(acl); | 1697 | iscsit_set_default_node_attribues(acl); |
1697 | } | 1698 | } |
1698 | 1699 | ||
1700 | static int lio_check_stop_free(struct se_cmd *se_cmd) | ||
1701 | { | ||
1702 | return target_put_sess_cmd(se_cmd->se_sess, se_cmd); | ||
1703 | } | ||
1704 | |||
1699 | static void lio_release_cmd(struct se_cmd *se_cmd) | 1705 | static void lio_release_cmd(struct se_cmd *se_cmd) |
1700 | { | 1706 | { |
1701 | struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); | 1707 | struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); |
@@ -1741,6 +1747,7 @@ int iscsi_target_register_configfs(void) | |||
1741 | fabric->tf_ops.tpg_alloc_fabric_acl = &lio_tpg_alloc_fabric_acl; | 1747 | fabric->tf_ops.tpg_alloc_fabric_acl = &lio_tpg_alloc_fabric_acl; |
1742 | fabric->tf_ops.tpg_release_fabric_acl = &lio_tpg_release_fabric_acl; | 1748 | fabric->tf_ops.tpg_release_fabric_acl = &lio_tpg_release_fabric_acl; |
1743 | fabric->tf_ops.tpg_get_inst_index = &lio_tpg_get_inst_index; | 1749 | fabric->tf_ops.tpg_get_inst_index = &lio_tpg_get_inst_index; |
1750 | fabric->tf_ops.check_stop_free = &lio_check_stop_free, | ||
1744 | fabric->tf_ops.release_cmd = &lio_release_cmd; | 1751 | fabric->tf_ops.release_cmd = &lio_release_cmd; |
1745 | fabric->tf_ops.shutdown_session = &lio_tpg_shutdown_session; | 1752 | fabric->tf_ops.shutdown_session = &lio_tpg_shutdown_session; |
1746 | fabric->tf_ops.close_session = &lio_tpg_close_session; | 1753 | fabric->tf_ops.close_session = &lio_tpg_close_session; |
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index 0b52a2371305..7816af6cdd12 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <scsi/iscsi_proto.h> | 22 | #include <scsi/iscsi_proto.h> |
23 | #include <target/target_core_base.h> | 23 | #include <target/target_core_base.h> |
24 | #include <target/target_core_fabric.h> | 24 | #include <target/target_core_fabric.h> |
25 | #include <target/iscsi/iscsi_transport.h> | ||
25 | 26 | ||
26 | #include "iscsi_target_core.h" | 27 | #include "iscsi_target_core.h" |
27 | #include "iscsi_target_seq_pdu_list.h" | 28 | #include "iscsi_target_seq_pdu_list.h" |
@@ -53,6 +54,9 @@ int iscsit_dump_data_payload( | |||
53 | u32 length, padding, offset = 0, size; | 54 | u32 length, padding, offset = 0, size; |
54 | struct kvec iov; | 55 | struct kvec iov; |
55 | 56 | ||
57 | if (conn->sess->sess_ops->RDMAExtensions) | ||
58 | return 0; | ||
59 | |||
56 | length = (buf_len > OFFLOAD_BUF_SIZE) ? OFFLOAD_BUF_SIZE : buf_len; | 60 | length = (buf_len > OFFLOAD_BUF_SIZE) ? OFFLOAD_BUF_SIZE : buf_len; |
57 | 61 | ||
58 | buf = kzalloc(length, GFP_ATOMIC); | 62 | buf = kzalloc(length, GFP_ATOMIC); |
@@ -919,6 +923,7 @@ int iscsit_execute_ooo_cmdsns(struct iscsi_session *sess) | |||
919 | int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) | 923 | int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) |
920 | { | 924 | { |
921 | struct se_cmd *se_cmd = &cmd->se_cmd; | 925 | struct se_cmd *se_cmd = &cmd->se_cmd; |
926 | struct iscsi_conn *conn = cmd->conn; | ||
922 | int lr = 0; | 927 | int lr = 0; |
923 | 928 | ||
924 | spin_lock_bh(&cmd->istate_lock); | 929 | spin_lock_bh(&cmd->istate_lock); |
@@ -981,7 +986,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) | |||
981 | return 0; | 986 | return 0; |
982 | 987 | ||
983 | iscsit_set_dataout_sequence_values(cmd); | 988 | iscsit_set_dataout_sequence_values(cmd); |
984 | iscsit_build_r2ts_for_cmd(cmd, cmd->conn, false); | 989 | conn->conn_transport->iscsit_get_dataout(conn, cmd, false); |
985 | } | 990 | } |
986 | return 0; | 991 | return 0; |
987 | } | 992 | } |
@@ -999,10 +1004,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) | |||
999 | if (transport_check_aborted_status(se_cmd, 1) != 0) | 1004 | if (transport_check_aborted_status(se_cmd, 1) != 0) |
1000 | return 0; | 1005 | return 0; |
1001 | 1006 | ||
1002 | iscsit_set_dataout_sequence_values(cmd); | 1007 | iscsit_set_unsoliticed_dataout(cmd); |
1003 | spin_lock_bh(&cmd->dataout_timeout_lock); | ||
1004 | iscsit_start_dataout_timer(cmd, cmd->conn); | ||
1005 | spin_unlock_bh(&cmd->dataout_timeout_lock); | ||
1006 | } | 1008 | } |
1007 | return transport_handle_cdb_direct(&cmd->se_cmd); | 1009 | return transport_handle_cdb_direct(&cmd->se_cmd); |
1008 | 1010 | ||
@@ -1290,3 +1292,4 @@ void iscsit_stop_dataout_timer(struct iscsi_cmd *cmd) | |||
1290 | cmd->init_task_tag); | 1292 | cmd->init_task_tag); |
1291 | spin_unlock_bh(&cmd->dataout_timeout_lock); | 1293 | spin_unlock_bh(&cmd->dataout_timeout_lock); |
1292 | } | 1294 | } |
1295 | EXPORT_SYMBOL(iscsit_stop_dataout_timer); | ||
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index e6a826927a40..bb5d5c5bce65 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -1068,8 +1068,7 @@ int iscsit_get_login_rx(struct iscsi_conn *conn, struct iscsi_login *login) | |||
1068 | if (login->first_request) { | 1068 | if (login->first_request) { |
1069 | login_req = (struct iscsi_login_req *)login->req; | 1069 | login_req = (struct iscsi_login_req *)login->req; |
1070 | login->leading_connection = (!login_req->tsih) ? 1 : 0; | 1070 | login->leading_connection = (!login_req->tsih) ? 1 : 0; |
1071 | login->current_stage = | 1071 | login->current_stage = ISCSI_LOGIN_CURRENT_STAGE(login_req->flags); |
1072 | (login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2; | ||
1073 | login->version_min = login_req->min_version; | 1072 | login->version_min = login_req->min_version; |
1074 | login->version_max = login_req->max_version; | 1073 | login->version_max = login_req->max_version; |
1075 | memcpy(login->isid, login_req->isid, 6); | 1074 | memcpy(login->isid, login_req->isid, 6); |
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 879a0cb44bc3..7ad912060e21 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c | |||
@@ -691,21 +691,6 @@ int iscsi_target_locate_portal( | |||
691 | login_req = (struct iscsi_login_req *) login->req; | 691 | login_req = (struct iscsi_login_req *) login->req; |
692 | payload_length = ntoh24(login_req->dlength); | 692 | payload_length = ntoh24(login_req->dlength); |
693 | 693 | ||
694 | login->first_request = 1; | ||
695 | login->leading_connection = (!login_req->tsih) ? 1 : 0; | ||
696 | login->current_stage = ISCSI_LOGIN_CURRENT_STAGE(login_req->flags); | ||
697 | login->version_min = login_req->min_version; | ||
698 | login->version_max = login_req->max_version; | ||
699 | memcpy(login->isid, login_req->isid, 6); | ||
700 | login->cmd_sn = be32_to_cpu(login_req->cmdsn); | ||
701 | login->init_task_tag = login_req->itt; | ||
702 | login->initial_exp_statsn = be32_to_cpu(login_req->exp_statsn); | ||
703 | login->cid = be16_to_cpu(login_req->cid); | ||
704 | login->tsih = be16_to_cpu(login_req->tsih); | ||
705 | |||
706 | if (iscsi_target_get_initial_payload(conn, login) < 0) | ||
707 | return -1; | ||
708 | |||
709 | tmpbuf = kzalloc(payload_length + 1, GFP_KERNEL); | 694 | tmpbuf = kzalloc(payload_length + 1, GFP_KERNEL); |
710 | if (!tmpbuf) { | 695 | if (!tmpbuf) { |
711 | pr_err("Unable to allocate memory for tmpbuf.\n"); | 696 | pr_err("Unable to allocate memory for tmpbuf.\n"); |
diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c index 9d4417aae921..16ca0ef9266f 100644 --- a/drivers/target/iscsi/iscsi_target_tmr.c +++ b/drivers/target/iscsi/iscsi_target_tmr.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <scsi/iscsi_proto.h> | 23 | #include <scsi/iscsi_proto.h> |
24 | #include <target/target_core_base.h> | 24 | #include <target/target_core_base.h> |
25 | #include <target/target_core_fabric.h> | 25 | #include <target/target_core_fabric.h> |
26 | #include <target/iscsi/iscsi_transport.h> | ||
26 | 27 | ||
27 | #include "iscsi_target_core.h" | 28 | #include "iscsi_target_core.h" |
28 | #include "iscsi_target_seq_pdu_list.h" | 29 | #include "iscsi_target_seq_pdu_list.h" |
@@ -301,7 +302,7 @@ static int iscsit_task_reassign_complete_write( | |||
301 | /* | 302 | /* |
302 | * iscsit_build_r2ts_for_cmd() can handle the rest from here. | 303 | * iscsit_build_r2ts_for_cmd() can handle the rest from here. |
303 | */ | 304 | */ |
304 | return iscsit_build_r2ts_for_cmd(cmd, conn, true); | 305 | return conn->conn_transport->iscsit_get_dataout(conn, cmd, true); |
305 | } | 306 | } |
306 | 307 | ||
307 | static int iscsit_task_reassign_complete_read( | 308 | static int iscsit_task_reassign_complete_read( |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 0b73f90c9c54..2cc6c9a3ffb8 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -317,6 +317,7 @@ int iscsit_sequence_cmd( | |||
317 | 317 | ||
318 | return ret; | 318 | return ret; |
319 | } | 319 | } |
320 | EXPORT_SYMBOL(iscsit_sequence_cmd); | ||
320 | 321 | ||
321 | int iscsit_check_unsolicited_dataout(struct iscsi_cmd *cmd, unsigned char *buf) | 322 | int iscsit_check_unsolicited_dataout(struct iscsi_cmd *cmd, unsigned char *buf) |
322 | { | 323 | { |