diff options
author | Christoph Hellwig <hch@lst.de> | 2012-11-06 15:24:09 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-11-06 23:55:46 -0500 |
commit | de103c93aff0bed0ae984274e5dc8b95899badab (patch) | |
tree | 7db9bba755fa95772052e8d31285a38ba48f1a84 /drivers/target/iscsi | |
parent | fecae40abb1ae9218bdbaa8b8e30bfb5ae43f522 (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.c | 80 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_core.h | 2 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_erl1.c | 11 |
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 | ||
993 | attach_cmd: | 980 | attach_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 | ||
480 | struct iscsi_tmr_req { | 480 | struct 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); |