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

Commit 03e98c9e authored by Nicholas Bellinger's avatar Nicholas Bellinger
Browse files

target: Address legacy PYX_TRANSPORT_* return code breakage



This patch removes legacy usage of PYX_TRANSPORT_* return codes in a number
of locations and addresses cases where transport_generic_request_failure()
was returning the incorrect sense upon CHECK_CONDITION status after the
v3.1 converson to use errno return codes.

This includes the conversion of transport_generic_request_failure() to
process cmd->scsi_sense_reason and handle extra TCM_RESERVATION_CONFLICT
before calling transport_send_check_condition_and_sense() to queue up
response status.  It also drops PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES legacy
usgae, and returns TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE w/ a response
for these cases.

transport_generic_allocate_tasks(), transport_generic_new_cmd(), backend
SCF_SCSI_DATA_SG_IO_CDB ->do_task(), and emulated ->execute_task() have
all been updated to set se_cmd->scsi_sense_reason and return errno codes
universally upon failure.  This includes cmd->scsi_sense_reason assignment
in target_core_alua.c, target_core_pr.c and target_core_cdb.c emulation code.

Finally it updates fabric modules to remove the legacy usage, and for
TFO->new_cmd_map() callers forwards return values outside of fabric code.
iscsi-target has also been updated to remove a handful of special cases
related to the cleanup and signaling QUEUE_FULL handling w/ ft_write_pending()

(v2: Drop extra SCF_SCSI_CDB_EXCEPTION check during failure from
     transport_generic_new_cmd, and re-add missing task->task_error_status
     assignment in transport_complete_task)

Cc: Christoph Hellwig <hch@lst.de>
Cc: stable@kernel.org
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 5611cc45
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -1017,11 +1017,6 @@ static int iscsit_handle_scsi_cmd(
				" non-existent or non-exported iSCSI LUN:"
				" 0x%016Lx\n", get_unaligned_le64(&hdr->lun));
		}
		if (ret == PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES)
			return iscsit_add_reject_from_cmd(
					ISCSI_REASON_BOOKMARK_NO_RESOURCES,
					1, 1, buf, cmd);

		send_check_condition = 1;
		goto attach_cmd;
	}
@@ -1123,7 +1118,7 @@ static int iscsit_handle_scsi_cmd(
	 * the backend memory allocation.
	 */
	ret = transport_generic_new_cmd(&cmd->se_cmd);
	if ((ret < 0) || (cmd->se_cmd.se_cmd_flags & SCF_SE_CMD_FAILED)) {
	if (ret < 0) {
		immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
		dump_immediate_data = 1;
		goto after_immediate_data;
@@ -1341,7 +1336,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)

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

+1 −2
Original line number Diff line number Diff line
@@ -938,8 +938,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
		 * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well.
		 */
		if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) {
			if (se_cmd->se_cmd_flags &
					SCF_SCSI_RESERVATION_CONFLICT) {
			if (se_cmd->scsi_sense_reason == TCM_RESERVATION_CONFLICT) {
				cmd->i_state = ISTATE_SEND_STATUS;
				spin_unlock_bh(&cmd->istate_lock);
				iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
+3 −21
Original line number Diff line number Diff line
@@ -148,22 +148,8 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
	 * Allocate the necessary tasks to complete the received CDB+data
	 */
	ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd);
	if (ret == -ENOMEM) {
		/* Out of Resources */
		return PYX_TRANSPORT_LU_COMM_FAILURE;
	} else if (ret == -EINVAL) {
		/*
		 * Handle case for SAM_STAT_RESERVATION_CONFLICT
		 */
		if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
			return PYX_TRANSPORT_RESERVATION_CONFLICT;
		/*
		 * Otherwise, return SAM_STAT_CHECK_CONDITION and return
		 * sense data.
		 */
		return PYX_TRANSPORT_USE_SENSE_REASON;
	}

	if (ret != 0)
		return ret;
	/*
	 * For BIDI commands, pass in the extra READ buffer
	 * to transport_generic_map_mem_to_cmd() below..
@@ -194,12 +180,8 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
	}

	/* Tell the core about our preallocated memory */
	ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
	return transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
			scsi_sg_count(sc), sgl_bidi, sgl_bidi_count);
	if (ret < 0)
		return PYX_TRANSPORT_LU_COMM_FAILURE;

	return 0;
}

/*
+16 −9
Original line number Diff line number Diff line
@@ -191,9 +191,10 @@ int target_emulate_set_target_port_groups(struct se_task *task)
	int alua_access_state, primary = 0, rc;
	u16 tg_pt_id, rtpi;

	if (!l_port)
		return PYX_TRANSPORT_LU_COMM_FAILURE;

	if (!l_port) {
		cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
		return -EINVAL;
	}
	buf = transport_kmap_first_data_page(cmd);

	/*
@@ -203,7 +204,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
	l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem;
	if (!l_tg_pt_gp_mem) {
		pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n");
		rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
		cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
		rc = -EINVAL;
		goto out;
	}
	spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
@@ -211,7 +213,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
	if (!l_tg_pt_gp) {
		spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
		pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n");
		rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
		cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
		rc = -EINVAL;
		goto out;
	}
	rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA);
@@ -220,7 +223,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
	if (!rc) {
		pr_debug("Unable to process SET_TARGET_PORT_GROUPS"
				" while TPGS_EXPLICT_ALUA is disabled\n");
		rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
		cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
		rc = -EINVAL;
		goto out;
	}

@@ -245,7 +249,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
			 * REQUEST, and the additional sense code set to INVALID
			 * FIELD IN PARAMETER LIST.
			 */
			rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
			cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
			rc = -EINVAL;
			goto out;
		}
		rc = -1;
@@ -298,7 +303,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
			 * throw an exception with ASCQ: INVALID_PARAMETER_LIST
			 */
			if (rc != 0) {
				rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
				cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
				rc = -EINVAL;
				goto out;
			}
		} else {
@@ -335,7 +341,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
			 * INVALID_PARAMETER_LIST
			 */
			if (rc != 0) {
				rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
				cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
				rc = -EINVAL;
				goto out;
			}
		}
+13 −5
Original line number Diff line number Diff line
@@ -703,6 +703,7 @@ int target_emulate_inquiry(struct se_task *task)
	if (cmd->data_length < 4) {
		pr_err("SCSI Inquiry payload length: %u"
			" too small for EVPD=1\n", cmd->data_length);
		cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
		return -EINVAL;
	}

@@ -719,6 +720,7 @@ int target_emulate_inquiry(struct se_task *task)
	}

	pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]);
	cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
	ret = -EINVAL;

out_unmap:
@@ -969,7 +971,8 @@ int target_emulate_modesense(struct se_task *task)
	default:
		pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n",
		       cdb[2] & 0x3f, cdb[3]);
		return PYX_TRANSPORT_UNKNOWN_MODE_PAGE;
		cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE;
		return -EINVAL;
	}
	offset += length;

@@ -1027,7 +1030,8 @@ int target_emulate_request_sense(struct se_task *task)
	if (cdb[1] & 0x01) {
		pr_err("REQUEST_SENSE description emulation not"
			" supported\n");
		return PYX_TRANSPORT_INVALID_CDB_FIELD;
		cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
		return -ENOSYS;
	}

	buf = transport_kmap_first_data_page(cmd);
@@ -1100,7 +1104,8 @@ int target_emulate_unmap(struct se_task *task)
	if (!dev->transport->do_discard) {
		pr_err("UNMAP emulation not supported for: %s\n",
				dev->transport->name);
		return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
		cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
		return -ENOSYS;
	}

	/* First UNMAP block descriptor starts at 8 byte offset */
@@ -1157,7 +1162,8 @@ int target_emulate_write_same(struct se_task *task)
	if (!dev->transport->do_discard) {
		pr_err("WRITE_SAME emulation not supported"
				" for: %s\n", dev->transport->name);
		return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
		cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
		return -ENOSYS;
	}

	if (cmd->t_task_cdb[0] == WRITE_SAME)
@@ -1193,11 +1199,13 @@ int target_emulate_write_same(struct se_task *task)
int target_emulate_synchronize_cache(struct se_task *task)
{
	struct se_device *dev = task->task_se_cmd->se_dev;
	struct se_cmd *cmd = task->task_se_cmd;

	if (!dev->transport->do_sync_cache) {
		pr_err("SYNCHRONIZE_CACHE emulation not supported"
			" for: %s\n", dev->transport->name);
		return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
		cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
		return -ENOSYS;
	}

	dev->transport->do_sync_cache(task);
Loading