aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/iscsi
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2012-11-06 15:24:09 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2012-11-06 23:55:46 -0500
commitde103c93aff0bed0ae984274e5dc8b95899badab (patch)
tree7db9bba755fa95772052e8d31285a38ba48f1a84 /drivers/target/iscsi
parentfecae40abb1ae9218bdbaa8b8e30bfb5ae43f522 (diff)
target: pass sense_reason as a return value
Pass the sense reason as an explicit return value from the I/O submission path instead of storing it in struct se_cmd and using negative return values. This cleans up a lot of the code pathes, and with the sparse annotations for the new sense_reason_t type allows for much better error checking. (nab: Convert spc_emulate_modesense + spc_emulate_modeselect to use sense_reason_t with Roland's MODE SELECT changes) Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Roland Dreier <roland@purestorage.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/iscsi')
-rw-r--r--drivers/target/iscsi/iscsi_target.c80
-rw-r--r--drivers/target/iscsi/iscsi_target_core.h2
-rw-r--r--drivers/target/iscsi/iscsi_target_erl1.c11
3 files changed, 34 insertions, 59 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 035c2c762537..093fb6010272 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -767,9 +767,8 @@ static int iscsit_handle_scsi_cmd(
767 struct iscsi_conn *conn, 767 struct iscsi_conn *conn,
768 unsigned char *buf) 768 unsigned char *buf)
769{ 769{
770 int data_direction, cmdsn_ret = 0, immed_ret, ret, transport_ret; 770 int data_direction, payload_length, cmdsn_ret = 0, immed_ret;
771 int dump_immediate_data = 0, send_check_condition = 0, payload_length; 771 struct iscsi_cmd *cmd = NULL;
772 struct iscsi_cmd *cmd = NULL;
773 struct iscsi_scsi_req *hdr; 772 struct iscsi_scsi_req *hdr;
774 int iscsi_task_attr; 773 int iscsi_task_attr;
775 int sam_task_attr; 774 int sam_task_attr;
@@ -956,38 +955,26 @@ done:
956 " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, 955 " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
957 hdr->cmdsn, hdr->data_length, payload_length, conn->cid); 956 hdr->cmdsn, hdr->data_length, payload_length, conn->cid);
958 957
959 /* 958 cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
960 * The CDB is going to an se_device_t. 959 scsilun_to_int(&hdr->lun));
961 */ 960 if (cmd->sense_reason)
962 ret = transport_lookup_cmd_lun(&cmd->se_cmd, 961 goto attach_cmd;
963 scsilun_to_int(&hdr->lun)); 962
964 if (ret < 0) { 963 cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
965 if (cmd->se_cmd.scsi_sense_reason == TCM_NON_EXISTENT_LUN) { 964 if (cmd->sense_reason) {
966 pr_debug("Responding to non-acl'ed," 965 if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) {
967 " non-existent or non-exported iSCSI LUN:" 966 return iscsit_add_reject_from_cmd(
968 " 0x%016Lx\n", get_unaligned_le64(&hdr->lun)); 967 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
968 1, 1, buf, cmd);
969 } 969 }
970 send_check_condition = 1; 970
971 goto attach_cmd; 971 goto attach_cmd;
972 } 972 }
973 973
974 transport_ret = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); 974 if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) {
975 if (transport_ret == -ENOMEM) {
976 return iscsit_add_reject_from_cmd( 975 return iscsit_add_reject_from_cmd(
977 ISCSI_REASON_BOOKMARK_NO_RESOURCES, 976 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
978 1, 1, buf, cmd); 977 1, 1, buf, cmd);
979 } else if (transport_ret < 0) {
980 /*
981 * Unsupported SAM Opcode. CHECK_CONDITION will be sent
982 * in iscsit_execute_cmd() during the CmdSN OOO Execution
983 * Mechinism.
984 */
985 send_check_condition = 1;
986 } else {
987 if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0)
988 return iscsit_add_reject_from_cmd(
989 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
990 1, 1, buf, cmd);
991 } 978 }
992 979
993attach_cmd: 980attach_cmd:
@@ -1000,11 +987,12 @@ attach_cmd:
1000 */ 987 */
1001 core_alua_check_nonop_delay(&cmd->se_cmd); 988 core_alua_check_nonop_delay(&cmd->se_cmd);
1002 989
1003 ret = iscsit_allocate_iovecs(cmd); 990 if (iscsit_allocate_iovecs(cmd) < 0) {
1004 if (ret < 0)
1005 return iscsit_add_reject_from_cmd( 991 return iscsit_add_reject_from_cmd(
1006 ISCSI_REASON_BOOKMARK_NO_RESOURCES, 992 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1007 1, 0, buf, cmd); 993 1, 0, buf, cmd);
994 }
995
1008 /* 996 /*
1009 * Check the CmdSN against ExpCmdSN/MaxCmdSN here if 997 * Check the CmdSN against ExpCmdSN/MaxCmdSN here if
1010 * the Immediate Bit is not set, and no Immediate 998 * the Immediate Bit is not set, and no Immediate
@@ -1031,10 +1019,7 @@ attach_cmd:
1031 * If no Immediate Data is attached, it's OK to return now. 1019 * If no Immediate Data is attached, it's OK to return now.
1032 */ 1020 */
1033 if (!cmd->immediate_data) { 1021 if (!cmd->immediate_data) {
1034 if (send_check_condition) 1022 if (!cmd->sense_reason && cmd->unsolicited_data) {
1035 return 0;
1036
1037 if (cmd->unsolicited_data) {
1038 iscsit_set_dataout_sequence_values(cmd); 1023 iscsit_set_dataout_sequence_values(cmd);
1039 1024
1040 spin_lock_bh(&cmd->dataout_timeout_lock); 1025 spin_lock_bh(&cmd->dataout_timeout_lock);
@@ -1050,19 +1035,17 @@ attach_cmd:
1050 * thread. They are processed in CmdSN order by 1035 * thread. They are processed in CmdSN order by
1051 * iscsit_check_received_cmdsn() below. 1036 * iscsit_check_received_cmdsn() below.
1052 */ 1037 */
1053 if (send_check_condition) { 1038 if (cmd->sense_reason) {
1054 immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; 1039 immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
1055 dump_immediate_data = 1;
1056 goto after_immediate_data; 1040 goto after_immediate_data;
1057 } 1041 }
1058 /* 1042 /*
1059 * Call directly into transport_generic_new_cmd() to perform 1043 * Call directly into transport_generic_new_cmd() to perform
1060 * the backend memory allocation. 1044 * the backend memory allocation.
1061 */ 1045 */
1062 ret = transport_generic_new_cmd(&cmd->se_cmd); 1046 cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd);
1063 if (ret < 0) { 1047 if (cmd->sense_reason) {
1064 immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; 1048 immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
1065 dump_immediate_data = 1;
1066 goto after_immediate_data; 1049 goto after_immediate_data;
1067 } 1050 }
1068 1051
@@ -1079,7 +1062,7 @@ after_immediate_data:
1079 * Special case for Unsupported SAM WRITE Opcodes 1062 * Special case for Unsupported SAM WRITE Opcodes
1080 * and ImmediateData=Yes. 1063 * and ImmediateData=Yes.
1081 */ 1064 */
1082 if (dump_immediate_data) { 1065 if (cmd->sense_reason) {
1083 if (iscsit_dump_data_payload(conn, payload_length, 1) < 0) 1066 if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
1084 return -1; 1067 return -1;
1085 } else if (cmd->unsolicited_data) { 1068 } else if (cmd->unsolicited_data) {
@@ -1272,8 +1255,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
1272 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); 1255 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
1273 1256
1274 spin_lock_irqsave(&se_cmd->t_state_lock, flags); 1257 spin_lock_irqsave(&se_cmd->t_state_lock, flags);
1275 if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) || 1258 if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE))
1276 (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION))
1277 dump_unsolicited_data = 1; 1259 dump_unsolicited_data = 1;
1278 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); 1260 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
1279 1261
@@ -1742,7 +1724,6 @@ static int iscsit_handle_task_mgt_cmd(
1742 ret = transport_lookup_tmr_lun(&cmd->se_cmd, 1724 ret = transport_lookup_tmr_lun(&cmd->se_cmd,
1743 scsilun_to_int(&hdr->lun)); 1725 scsilun_to_int(&hdr->lun));
1744 if (ret < 0) { 1726 if (ret < 0) {
1745 cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
1746 se_tmr->response = ISCSI_TMF_RSP_NO_LUN; 1727 se_tmr->response = ISCSI_TMF_RSP_NO_LUN;
1747 goto attach; 1728 goto attach;
1748 } 1729 }
@@ -1751,10 +1732,8 @@ static int iscsit_handle_task_mgt_cmd(
1751 switch (function) { 1732 switch (function) {
1752 case ISCSI_TM_FUNC_ABORT_TASK: 1733 case ISCSI_TM_FUNC_ABORT_TASK:
1753 se_tmr->response = iscsit_tmr_abort_task(cmd, buf); 1734 se_tmr->response = iscsit_tmr_abort_task(cmd, buf);
1754 if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE) { 1735 if (se_tmr->response)
1755 cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
1756 goto attach; 1736 goto attach;
1757 }
1758 break; 1737 break;
1759 case ISCSI_TM_FUNC_ABORT_TASK_SET: 1738 case ISCSI_TM_FUNC_ABORT_TASK_SET:
1760 case ISCSI_TM_FUNC_CLEAR_ACA: 1739 case ISCSI_TM_FUNC_CLEAR_ACA:
@@ -1763,14 +1742,12 @@ static int iscsit_handle_task_mgt_cmd(
1763 break; 1742 break;
1764 case ISCSI_TM_FUNC_TARGET_WARM_RESET: 1743 case ISCSI_TM_FUNC_TARGET_WARM_RESET:
1765 if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) { 1744 if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) {
1766 cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
1767 se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; 1745 se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
1768 goto attach; 1746 goto attach;
1769 } 1747 }
1770 break; 1748 break;
1771 case ISCSI_TM_FUNC_TARGET_COLD_RESET: 1749 case ISCSI_TM_FUNC_TARGET_COLD_RESET:
1772 if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) { 1750 if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) {
1773 cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
1774 se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; 1751 se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
1775 goto attach; 1752 goto attach;
1776 } 1753 }
@@ -1781,7 +1758,7 @@ static int iscsit_handle_task_mgt_cmd(
1781 * Perform sanity checks on the ExpDataSN only if the 1758 * Perform sanity checks on the ExpDataSN only if the
1782 * TASK_REASSIGN was successful. 1759 * TASK_REASSIGN was successful.
1783 */ 1760 */
1784 if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE) 1761 if (se_tmr->response)
1785 break; 1762 break;
1786 1763
1787 if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0) 1764 if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0)
@@ -1792,7 +1769,6 @@ static int iscsit_handle_task_mgt_cmd(
1792 default: 1769 default:
1793 pr_err("Unknown TMR function: 0x%02x, protocol" 1770 pr_err("Unknown TMR function: 0x%02x, protocol"
1794 " error.\n", function); 1771 " error.\n", function);
1795 cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
1796 se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED; 1772 se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED;
1797 goto attach; 1773 goto attach;
1798 } 1774 }
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h
index 21048dbf7d13..7a333d28d9a2 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -474,7 +474,7 @@ struct iscsi_cmd {
474 struct scatterlist *first_data_sg; 474 struct scatterlist *first_data_sg;
475 u32 first_data_sg_off; 475 u32 first_data_sg_off;
476 u32 kmapped_nents; 476 u32 kmapped_nents;
477 477 sense_reason_t sense_reason;
478} ____cacheline_aligned; 478} ____cacheline_aligned;
479 479
480struct iscsi_tmr_req { 480struct iscsi_tmr_req {
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c
index 21f29d91a8cb..0b52a2371305 100644
--- a/drivers/target/iscsi/iscsi_target_erl1.c
+++ b/drivers/target/iscsi/iscsi_target_erl1.c
@@ -929,11 +929,10 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
929 case ISCSI_OP_SCSI_CMD: 929 case ISCSI_OP_SCSI_CMD:
930 /* 930 /*
931 * Go ahead and send the CHECK_CONDITION status for 931 * Go ahead and send the CHECK_CONDITION status for
932 * any SCSI CDB exceptions that may have occurred, also 932 * any SCSI CDB exceptions that may have occurred.
933 * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well.
934 */ 933 */
935 if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { 934 if (cmd->sense_reason) {
936 if (se_cmd->scsi_sense_reason == TCM_RESERVATION_CONFLICT) { 935 if (cmd->sense_reason == TCM_RESERVATION_CONFLICT) {
937 cmd->i_state = ISTATE_SEND_STATUS; 936 cmd->i_state = ISTATE_SEND_STATUS;
938 spin_unlock_bh(&cmd->istate_lock); 937 spin_unlock_bh(&cmd->istate_lock);
939 iscsit_add_cmd_to_response_queue(cmd, cmd->conn, 938 iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
@@ -956,7 +955,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
956 * exception 955 * exception
957 */ 956 */
958 return transport_send_check_condition_and_sense(se_cmd, 957 return transport_send_check_condition_and_sense(se_cmd,
959 se_cmd->scsi_sense_reason, 0); 958 cmd->sense_reason, 0);
960 } 959 }
961 /* 960 /*
962 * Special case for delayed CmdSN with Immediate 961 * Special case for delayed CmdSN with Immediate
@@ -1013,7 +1012,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
1013 iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); 1012 iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
1014 break; 1013 break;
1015 case ISCSI_OP_SCSI_TMFUNC: 1014 case ISCSI_OP_SCSI_TMFUNC:
1016 if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { 1015 if (cmd->se_cmd.se_tmr_req->response) {
1017 spin_unlock_bh(&cmd->istate_lock); 1016 spin_unlock_bh(&cmd->istate_lock);
1018 iscsit_add_cmd_to_response_queue(cmd, cmd->conn, 1017 iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
1019 cmd->i_state); 1018 cmd->i_state);