static void target_complete_ok_work()

in target_core_transport.c [2476:2619]


static void target_complete_ok_work(struct work_struct *work)
{
	struct se_cmd *cmd = container_of(work, struct se_cmd, work);
	int ret;

	/*
	 * Check if we need to move delayed/dormant tasks from cmds on the
	 * delayed execution list after a HEAD_OF_QUEUE or ORDERED Task
	 * Attribute.
	 */
	transport_complete_task_attr(cmd);

	/*
	 * Check to schedule QUEUE_FULL work, or execute an existing
	 * cmd->transport_qf_callback()
	 */
	if (atomic_read(&cmd->se_dev->dev_qf_count) != 0)
		schedule_work(&cmd->se_dev->qf_work_queue);

	/*
	 * Check if we need to send a sense buffer from
	 * the struct se_cmd in question. We do NOT want
	 * to take this path of the IO has been marked as
	 * needing to be treated like a "normal read". This
	 * is the case if it's a tape read, and either the
	 * FM, EOM, or ILI bits are set, but there is no
	 * sense data.
	 */
	if (!(cmd->se_cmd_flags & SCF_TREAT_READ_AS_NORMAL) &&
	    cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) {
		WARN_ON(!cmd->scsi_status);
		ret = transport_send_check_condition_and_sense(
					cmd, 0, 1);
		if (ret)
			goto queue_full;

		transport_lun_remove_cmd(cmd);
		transport_cmd_check_stop_to_fabric(cmd);
		return;
	}
	/*
	 * Check for a callback, used by amongst other things
	 * XDWRITE_READ_10 and COMPARE_AND_WRITE emulation.
	 */
	if (cmd->transport_complete_callback) {
		sense_reason_t rc;
		bool caw = (cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE);
		bool zero_dl = !(cmd->data_length);
		int post_ret = 0;

		rc = cmd->transport_complete_callback(cmd, true, &post_ret);
		if (!rc && !post_ret) {
			if (caw && zero_dl)
				goto queue_rsp;

			return;
		} else if (rc) {
			ret = transport_send_check_condition_and_sense(cmd,
						rc, 0);
			if (ret)
				goto queue_full;

			transport_lun_remove_cmd(cmd);
			transport_cmd_check_stop_to_fabric(cmd);
			return;
		}
	}

queue_rsp:
	switch (cmd->data_direction) {
	case DMA_FROM_DEVICE:
		/*
		 * if this is a READ-type IO, but SCSI status
		 * is set, then skip returning data and just
		 * return the status -- unless this IO is marked
		 * as needing to be treated as a normal read,
		 * in which case we want to go ahead and return
		 * the data. This happens, for example, for tape
		 * reads with the FM, EOM, or ILI bits set, with
		 * no sense data.
		 */
		if (cmd->scsi_status &&
		    !(cmd->se_cmd_flags & SCF_TREAT_READ_AS_NORMAL))
			goto queue_status;

		atomic_long_add(cmd->data_length,
				&cmd->se_lun->lun_stats.tx_data_octets);
		/*
		 * Perform READ_STRIP of PI using software emulation when
		 * backend had PI enabled, if the transport will not be
		 * performing hardware READ_STRIP offload.
		 */
		if (target_read_prot_action(cmd)) {
			ret = transport_send_check_condition_and_sense(cmd,
						cmd->pi_err, 0);
			if (ret)
				goto queue_full;

			transport_lun_remove_cmd(cmd);
			transport_cmd_check_stop_to_fabric(cmd);
			return;
		}

		trace_target_cmd_complete(cmd);
		ret = cmd->se_tfo->queue_data_in(cmd);
		if (ret)
			goto queue_full;
		break;
	case DMA_TO_DEVICE:
		atomic_long_add(cmd->data_length,
				&cmd->se_lun->lun_stats.rx_data_octets);
		/*
		 * Check if we need to send READ payload for BIDI-COMMAND
		 */
		if (cmd->se_cmd_flags & SCF_BIDI) {
			atomic_long_add(cmd->data_length,
					&cmd->se_lun->lun_stats.tx_data_octets);
			ret = cmd->se_tfo->queue_data_in(cmd);
			if (ret)
				goto queue_full;
			break;
		}
		fallthrough;
	case DMA_NONE:
queue_status:
		trace_target_cmd_complete(cmd);
		ret = cmd->se_tfo->queue_status(cmd);
		if (ret)
			goto queue_full;
		break;
	default:
		break;
	}

	transport_lun_remove_cmd(cmd);
	transport_cmd_check_stop_to_fabric(cmd);
	return;

queue_full:
	pr_debug("Handling complete_ok QUEUE_FULL: se_cmd: %p,"
		" data_direction: %d\n", cmd, cmd->data_direction);

	transport_handle_queue_full(cmd, cmd->se_dev, ret, false);
}