Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de103c93 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Nicholas Bellinger
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Cc: Roland Dreier <roland@purestorage.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent fecae40a
Loading
Loading
Loading
Loading
+18 −25
Original line number Original line Diff line number Diff line
@@ -1730,7 +1730,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
	uint64_t unpacked_lun;
	uint64_t unpacked_lun;
	u64 data_len;
	u64 data_len;
	enum dma_data_direction dir;
	enum dma_data_direction dir;
	int ret;
	sense_reason_t ret;


	BUG_ON(!send_ioctx);
	BUG_ON(!send_ioctx);


@@ -1755,12 +1755,10 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
		break;
		break;
	}
	}


	ret = srpt_get_desc_tbl(send_ioctx, srp_cmd, &dir, &data_len);
	if (srpt_get_desc_tbl(send_ioctx, srp_cmd, &dir, &data_len)) {
	if (ret) {
		printk(KERN_ERR "0x%llx: parsing SRP descriptor table failed.\n",
		printk(KERN_ERR "0x%llx: parsing SRP descriptor table failed.\n",
		       srp_cmd->tag);
		       srp_cmd->tag);
		cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
		ret = TCM_INVALID_CDB_FIELD;
		cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
		kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
		kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
		goto send_sense;
		goto send_sense;
	}
	}
@@ -1769,17 +1767,18 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
	cmd->data_direction = dir;
	cmd->data_direction = dir;
	unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun,
	unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun,
				       sizeof(srp_cmd->lun));
				       sizeof(srp_cmd->lun));
	if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0) {
	ret = transport_lookup_cmd_lun(cmd, unpacked_lun);
	if (ret) {
		kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
		kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
		goto send_sense;
		goto send_sense;
	}
	}
	ret = target_setup_cmd_from_cdb(cmd, srp_cmd->cdb);
	ret = target_setup_cmd_from_cdb(cmd, srp_cmd->cdb);
	if (ret < 0) {
	if (ret) {
		kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
		kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
		if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) {
		if (ret == TCM_RESERVATION_CONFLICT) {
			srpt_queue_status(cmd);
			srpt_queue_status(cmd);
			return 0;
			return 0;
		} else
		}
		goto send_sense;
		goto send_sense;
	}
	}


@@ -1787,8 +1786,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
	return 0;
	return 0;


send_sense:
send_sense:
	transport_send_check_condition_and_sense(cmd, cmd->scsi_sense_reason,
	transport_send_check_condition_and_sense(cmd, ret, 0);
						 0);
	return -1;
	return -1;
}
}


@@ -1882,16 +1880,14 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch,
	send_ioctx->tag = srp_tsk->tag;
	send_ioctx->tag = srp_tsk->tag;
	tcm_tmr = srp_tmr_to_tcm(srp_tsk->tsk_mgmt_func);
	tcm_tmr = srp_tmr_to_tcm(srp_tsk->tsk_mgmt_func);
	if (tcm_tmr < 0) {
	if (tcm_tmr < 0) {
		send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
		send_ioctx->cmd.se_tmr_req->response =
		send_ioctx->cmd.se_tmr_req->response =
			TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
			TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
		goto process_tmr;
		goto fail;
	}
	}
	res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL);
	res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL);
	if (res < 0) {
	if (res < 0) {
		send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
		send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED;
		send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED;
		goto process_tmr;
		goto fail;
	}
	}


	unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_tsk->lun,
	unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_tsk->lun,
@@ -1899,22 +1895,19 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch,
	res = transport_lookup_tmr_lun(&send_ioctx->cmd, unpacked_lun);
	res = transport_lookup_tmr_lun(&send_ioctx->cmd, unpacked_lun);
	if (res) {
	if (res) {
		pr_debug("rejecting TMR for LUN %lld\n", unpacked_lun);
		pr_debug("rejecting TMR for LUN %lld\n", unpacked_lun);
		send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
		send_ioctx->cmd.se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST;
		send_ioctx->cmd.se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST;
		goto process_tmr;
		goto fail;
	}
	}


	if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK)
	if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK)
		srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag);
		srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag);


process_tmr:
	kref_get(&send_ioctx->kref);
	kref_get(&send_ioctx->kref);
	if (!(send_ioctx->cmd.se_cmd_flags & SCF_SCSI_CDB_EXCEPTION))
	transport_generic_handle_tmr(&send_ioctx->cmd);
	transport_generic_handle_tmr(&send_ioctx->cmd);
	else
	return;
		transport_send_check_condition_and_sense(cmd,
fail:
						cmd->scsi_sense_reason, 0);
	kref_get(&send_ioctx->kref);

	transport_send_check_condition_and_sense(cmd, 0, 0); // XXX:
}
}


/**
/**
+2 −2
Original line number Original line Diff line number Diff line
@@ -620,8 +620,8 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
			return;
			return;
		}
		}


		cmd->se_cmd.scsi_sense_reason = TCM_CHECK_CONDITION_ABORT_CMD;
		transport_generic_request_failure(&cmd->se_cmd,
		transport_generic_request_failure(&cmd->se_cmd);
						  TCM_CHECK_CONDITION_ABORT_CMD);
		return;
		return;
	}
	}


+28 −52
Original line number Original line Diff line number Diff line
@@ -767,8 +767,7 @@ static int iscsit_handle_scsi_cmd(
	struct iscsi_conn *conn,
	struct iscsi_conn *conn,
	unsigned char *buf)
	unsigned char *buf)
{
{
	int	data_direction, cmdsn_ret = 0, immed_ret, ret, transport_ret;
	int data_direction, payload_length, cmdsn_ret = 0, immed_ret;
	int	dump_immediate_data = 0, send_check_condition = 0, payload_length;
	struct iscsi_cmd *cmd = NULL;
	struct iscsi_cmd *cmd = NULL;
	struct iscsi_scsi_req *hdr;
	struct iscsi_scsi_req *hdr;
	int iscsi_task_attr;
	int iscsi_task_attr;
@@ -956,35 +955,23 @@ static int iscsit_handle_scsi_cmd(
		" ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
		" ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
		hdr->cmdsn, hdr->data_length, payload_length, conn->cid);
		hdr->cmdsn, hdr->data_length, payload_length, conn->cid);


	/*
	cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
	 * The CDB is going to an se_device_t.
	 */
	ret = transport_lookup_cmd_lun(&cmd->se_cmd,
						     scsilun_to_int(&hdr->lun));
						     scsilun_to_int(&hdr->lun));
	if (ret < 0) {
	if (cmd->sense_reason)
		if (cmd->se_cmd.scsi_sense_reason == TCM_NON_EXISTENT_LUN) {
			pr_debug("Responding to non-acl'ed,"
				" non-existent or non-exported iSCSI LUN:"
				" 0x%016Lx\n", get_unaligned_le64(&hdr->lun));
		}
		send_check_condition = 1;
		goto attach_cmd;
		goto attach_cmd;
	}


	transport_ret = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
	cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
	if (transport_ret == -ENOMEM) {
	if (cmd->sense_reason) {
		if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) {
			return iscsit_add_reject_from_cmd(
			return iscsit_add_reject_from_cmd(
					ISCSI_REASON_BOOKMARK_NO_RESOURCES,
					ISCSI_REASON_BOOKMARK_NO_RESOURCES,
					1, 1, buf, cmd);
					1, 1, buf, cmd);
	} else if (transport_ret < 0) {
		}
		/*

		 * Unsupported SAM Opcode.  CHECK_CONDITION will be sent
		goto attach_cmd;
		 * in iscsit_execute_cmd() during the CmdSN OOO Execution
	}
		 * Mechinism.

		 */
	if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) {
		send_check_condition = 1;
	} else {
		if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0)
		return iscsit_add_reject_from_cmd(
		return iscsit_add_reject_from_cmd(
			ISCSI_REASON_BOOKMARK_NO_RESOURCES,
			ISCSI_REASON_BOOKMARK_NO_RESOURCES,
			1, 1, buf, cmd);
			1, 1, buf, cmd);
@@ -1000,11 +987,12 @@ static int iscsit_handle_scsi_cmd(
	 */
	 */
	core_alua_check_nonop_delay(&cmd->se_cmd);
	core_alua_check_nonop_delay(&cmd->se_cmd);


	ret = iscsit_allocate_iovecs(cmd);
	if (iscsit_allocate_iovecs(cmd) < 0) {
	if (ret < 0)
		return iscsit_add_reject_from_cmd(
		return iscsit_add_reject_from_cmd(
				ISCSI_REASON_BOOKMARK_NO_RESOURCES,
				ISCSI_REASON_BOOKMARK_NO_RESOURCES,
				1, 0, buf, cmd);
				1, 0, buf, cmd);
	}

	/*
	/*
	 * Check the CmdSN against ExpCmdSN/MaxCmdSN here if
	 * Check the CmdSN against ExpCmdSN/MaxCmdSN here if
	 * the Immediate Bit is not set, and no Immediate
	 * the Immediate Bit is not set, and no Immediate
@@ -1031,10 +1019,7 @@ static int iscsit_handle_scsi_cmd(
	 * If no Immediate Data is attached, it's OK to return now.
	 * If no Immediate Data is attached, it's OK to return now.
	 */
	 */
	if (!cmd->immediate_data) {
	if (!cmd->immediate_data) {
		if (send_check_condition)
		if (!cmd->sense_reason && cmd->unsolicited_data) {
			return 0;

		if (cmd->unsolicited_data) {
			iscsit_set_dataout_sequence_values(cmd);
			iscsit_set_dataout_sequence_values(cmd);


			spin_lock_bh(&cmd->dataout_timeout_lock);
			spin_lock_bh(&cmd->dataout_timeout_lock);
@@ -1050,19 +1035,17 @@ static int iscsit_handle_scsi_cmd(
	 * thread.  They are processed in CmdSN order by
	 * thread.  They are processed in CmdSN order by
	 * iscsit_check_received_cmdsn() below.
	 * iscsit_check_received_cmdsn() below.
	 */
	 */
	if (send_check_condition) {
	if (cmd->sense_reason) {
		immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
		immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
		dump_immediate_data = 1;
		goto after_immediate_data;
		goto after_immediate_data;
	}
	}
	/*
	/*
	 * Call directly into transport_generic_new_cmd() to perform
	 * Call directly into transport_generic_new_cmd() to perform
	 * the backend memory allocation.
	 * the backend memory allocation.
	 */
	 */
	ret = transport_generic_new_cmd(&cmd->se_cmd);
	cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd);
	if (ret < 0) {
	if (cmd->sense_reason) {
		immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
		immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
		dump_immediate_data = 1;
		goto after_immediate_data;
		goto after_immediate_data;
	}
	}


@@ -1079,7 +1062,7 @@ static int iscsit_handle_scsi_cmd(
		 * Special case for Unsupported SAM WRITE Opcodes
		 * Special case for Unsupported SAM WRITE Opcodes
		 * and ImmediateData=Yes.
		 * and ImmediateData=Yes.
		 */
		 */
		if (dump_immediate_data) {
		if (cmd->sense_reason) {
			if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
			if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
				return -1;
				return -1;
		} else if (cmd->unsolicited_data) {
		} else if (cmd->unsolicited_data) {
@@ -1272,8 +1255,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
		spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
		spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);


		spin_lock_irqsave(&se_cmd->t_state_lock, flags);
		spin_lock_irqsave(&se_cmd->t_state_lock, flags);
		if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) ||
		if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE))
		     (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION))
			dump_unsolicited_data = 1;
			dump_unsolicited_data = 1;
		spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
		spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);


@@ -1742,7 +1724,6 @@ static int iscsit_handle_task_mgt_cmd(
		ret = transport_lookup_tmr_lun(&cmd->se_cmd,
		ret = transport_lookup_tmr_lun(&cmd->se_cmd,
					       scsilun_to_int(&hdr->lun));
					       scsilun_to_int(&hdr->lun));
		if (ret < 0) {
		if (ret < 0) {
			cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
			se_tmr->response = ISCSI_TMF_RSP_NO_LUN;
			se_tmr->response = ISCSI_TMF_RSP_NO_LUN;
			goto attach;
			goto attach;
		}
		}
@@ -1751,10 +1732,8 @@ static int iscsit_handle_task_mgt_cmd(
	switch (function) {
	switch (function) {
	case ISCSI_TM_FUNC_ABORT_TASK:
	case ISCSI_TM_FUNC_ABORT_TASK:
		se_tmr->response = iscsit_tmr_abort_task(cmd, buf);
		se_tmr->response = iscsit_tmr_abort_task(cmd, buf);
		if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE) {
		if (se_tmr->response)
			cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
			goto attach;
			goto attach;
		}
		break;
		break;
	case ISCSI_TM_FUNC_ABORT_TASK_SET:
	case ISCSI_TM_FUNC_ABORT_TASK_SET:
	case ISCSI_TM_FUNC_CLEAR_ACA:
	case ISCSI_TM_FUNC_CLEAR_ACA:
@@ -1763,14 +1742,12 @@ static int iscsit_handle_task_mgt_cmd(
		break;
		break;
	case ISCSI_TM_FUNC_TARGET_WARM_RESET:
	case ISCSI_TM_FUNC_TARGET_WARM_RESET:
		if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) {
		if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) {
			cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
			se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
			se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
			goto attach;
			goto attach;
		}
		}
		break;
		break;
	case ISCSI_TM_FUNC_TARGET_COLD_RESET:
	case ISCSI_TM_FUNC_TARGET_COLD_RESET:
		if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) {
		if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) {
			cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
			se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
			se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
			goto attach;
			goto attach;
		}
		}
@@ -1781,7 +1758,7 @@ static int iscsit_handle_task_mgt_cmd(
		 * Perform sanity checks on the ExpDataSN only if the
		 * Perform sanity checks on the ExpDataSN only if the
		 * TASK_REASSIGN was successful.
		 * TASK_REASSIGN was successful.
		 */
		 */
		if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE)
		if (se_tmr->response)
			break;
			break;


		if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0)
		if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0)
@@ -1792,7 +1769,6 @@ static int iscsit_handle_task_mgt_cmd(
	default:
	default:
		pr_err("Unknown TMR function: 0x%02x, protocol"
		pr_err("Unknown TMR function: 0x%02x, protocol"
			" error.\n", function);
			" error.\n", function);
		cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
		se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED;
		se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED;
		goto attach;
		goto attach;
	}
	}
+1 −1
Original line number Original line Diff line number Diff line
@@ -474,7 +474,7 @@ struct iscsi_cmd {
	struct scatterlist	*first_data_sg;
	struct scatterlist	*first_data_sg;
	u32			first_data_sg_off;
	u32			first_data_sg_off;
	u32			kmapped_nents;
	u32			kmapped_nents;

	sense_reason_t		sense_reason;
}  ____cacheline_aligned;
}  ____cacheline_aligned;


struct iscsi_tmr_req {
struct iscsi_tmr_req {
+5 −6
Original line number Original line Diff line number Diff line
@@ -929,11 +929,10 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
	case ISCSI_OP_SCSI_CMD:
	case ISCSI_OP_SCSI_CMD:
		/*
		/*
		 * Go ahead and send the CHECK_CONDITION status for
		 * Go ahead and send the CHECK_CONDITION status for
		 * any SCSI CDB exceptions that may have occurred, also
		 * any SCSI CDB exceptions that may have occurred.
		 * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well.
		 */
		 */
		if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) {
		if (cmd->sense_reason) {
			if (se_cmd->scsi_sense_reason == TCM_RESERVATION_CONFLICT) {
			if (cmd->sense_reason == TCM_RESERVATION_CONFLICT) {
				cmd->i_state = ISTATE_SEND_STATUS;
				cmd->i_state = ISTATE_SEND_STATUS;
				spin_unlock_bh(&cmd->istate_lock);
				spin_unlock_bh(&cmd->istate_lock);
				iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
				iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
@@ -956,7 +955,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
			 * exception
			 * exception
			 */
			 */
			return transport_send_check_condition_and_sense(se_cmd,
			return transport_send_check_condition_and_sense(se_cmd,
					se_cmd->scsi_sense_reason, 0);
					cmd->sense_reason, 0);
		}
		}
		/*
		/*
		 * Special case for delayed CmdSN with Immediate
		 * Special case for delayed CmdSN with Immediate
@@ -1013,7 +1012,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
		iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
		iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
		break;
		break;
	case ISCSI_OP_SCSI_TMFUNC:
	case ISCSI_OP_SCSI_TMFUNC:
		if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) {
		if (cmd->se_cmd.se_tmr_req->response) {
			spin_unlock_bh(&cmd->istate_lock);
			spin_unlock_bh(&cmd->istate_lock);
			iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
			iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
					cmd->i_state);
					cmd->i_state);
Loading