From patchwork Wed May 31 20:52:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 9758113 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 04E3760390 for ; Wed, 31 May 2017 20:53:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EB8DB284C4 for ; Wed, 31 May 2017 20:53:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E0735284C8; Wed, 31 May 2017 20:53:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 39961284C4 for ; Wed, 31 May 2017 20:53:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750898AbdEaUxC (ORCPT ); Wed, 31 May 2017 16:53:02 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56578 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751152AbdEaUxC (ORCPT ); Wed, 31 May 2017 16:53:02 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B2B0F2D9FC5; Wed, 31 May 2017 20:53:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B2B0F2D9FC5 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=mchristi@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com B2B0F2D9FC5 Received: from rh2.redhat.com (ovpn-126-11.rdu2.redhat.com [10.10.126.11]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1EDC417F54; Wed, 31 May 2017 20:53:01 +0000 (UTC) From: Mike Christie To: target-devel@vger.kernel.org, nab@linux-iscsi.org Cc: Mike Christie Subject: [RFC PATCH 12/13] target: merge cmd completion functions Date: Wed, 31 May 2017 15:52:49 -0500 Message-Id: <1496263970-7632-13-git-send-email-mchristi@redhat.com> In-Reply-To: <1496263970-7632-1-git-send-email-mchristi@redhat.com> References: <1496263970-7632-1-git-send-email-mchristi@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 31 May 2017 20:53:01 +0000 (UTC) Sender: target-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: target-devel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch merges the cmd completion functions so there is a common code path. Signed-off-by: Mike Christie --- drivers/target/target_core_transport.c | 156 +++++++++++---------------------- 1 file changed, 49 insertions(+), 107 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 6aee378..faad7b4 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -68,7 +68,7 @@ static void transport_handle_queue_full(struct se_cmd *cmd, struct se_device *dev, int err, bool write_pending); static int transport_put_cmd(struct se_cmd *cmd); -static void target_complete_ok_work(struct work_struct *work); +static void target_complete_cmd_work(struct work_struct *work); int init_se_kmem_caches(void) { @@ -670,14 +670,6 @@ void transport_cmd_finish_abort(struct se_cmd *cmd, int remove) transport_put_cmd(cmd); } -static void target_complete_failure_work(struct work_struct *work) -{ - struct se_cmd *cmd = container_of(work, struct se_cmd, work); - - transport_generic_request_failure(cmd, - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE); -} - /* * Used when asking transport to copy Sense Data from the underlying * Linux/SCSI struct scsi_cmnd @@ -721,24 +713,10 @@ void transport_copy_sense_to_cmd(struct se_cmd *cmd, unsigned char *sense) void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) { - int success; unsigned long flags; - cmd->scsi_status = scsi_status; spin_lock_irqsave(&cmd->t_state_lock, flags); - switch (cmd->scsi_status) { - case SAM_STAT_CHECK_CONDITION: - if (cmd->se_cmd_flags & SCF_TASK_SENSE) - success = 1; - else - success = 0; - break; - default: - success = 1; - break; - } - /* * Check for case where an explicit ABORT_TASK has been received * and transport_wait_for_tasks() will be waiting for completion.. @@ -748,12 +726,9 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) spin_unlock_irqrestore(&cmd->t_state_lock, flags); complete_all(&cmd->t_transport_stop_comp); return; - } else if (!success) { - INIT_WORK(&cmd->work, target_complete_failure_work); - } else { - INIT_WORK(&cmd->work, target_complete_ok_work); } + INIT_WORK(&cmd->work, target_complete_cmd_work); cmd->t_state = TRANSPORT_COMPLETE; cmd->transport_state |= (CMD_T_COMPLETE | CMD_T_ACTIVE); spin_unlock_irqrestore(&cmd->t_state_lock, flags); @@ -1678,19 +1653,8 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, void transport_generic_request_failure(struct se_cmd *cmd, sense_reason_t sense_reason) { - int ret = 0, post_ret = 0; - - /* - * For SAM Task Attribute emulation for failed struct se_cmd - */ - transport_complete_task_attr(cmd); - /* - * Handle special case for COMPARE_AND_WRITE failure, where the - * callback is expected to drop the per device ->caw_sem. - */ - if ((cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) && - cmd->transport_complete_callback) - cmd->transport_complete_callback(cmd, false, &post_ret); + u8 scsi_status = SAM_STAT_CHECK_CONDITION; + unsigned long flags; if (transport_check_aborted_status(cmd, 1)) return; @@ -1737,7 +1701,7 @@ void transport_generic_request_failure(struct se_cmd *cmd, * * Uses linux/include/scsi/scsi.h SAM status codes defs */ - cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; + scsi_status = SAM_STAT_RESERVATION_CONFLICT; /* * For UA Interlock Code 11b, a RESERVATION CONFLICT will * establish a UNIT ATTENTION with PREVIOUS RESERVATION @@ -1751,11 +1715,8 @@ void transport_generic_request_failure(struct se_cmd *cmd, cmd->orig_fe_lun, 0x2C, ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS); } - trace_target_cmd_complete(cmd); - ret = cmd->se_tfo->queue_status(cmd); - if (ret) - goto queue_full; - goto check_stop; + + goto queue_completion; default: pr_err("Unknown transport error for CDB 0x%02x: %d\n", cmd->t_task_cdb[0], sense_reason); @@ -1763,17 +1724,12 @@ void transport_generic_request_failure(struct se_cmd *cmd, break; } - ret = transport_send_check_condition_and_sense(cmd, sense_reason); - if (ret) - goto queue_full; - -check_stop: - transport_lun_remove_cmd(cmd); - transport_cmd_check_stop_to_fabric(cmd); - return; + spin_lock_irqsave(&cmd->t_state_lock, flags); + transport_setup_sense(cmd, sense_reason); + spin_unlock_irqrestore(&cmd->t_state_lock, flags); -queue_full: - transport_handle_queue_full(cmd, cmd->se_dev, ret, false); +queue_completion: + target_complete_cmd(cmd, scsi_status); } EXPORT_SYMBOL(transport_generic_request_failure); @@ -2119,10 +2075,10 @@ static bool target_read_prot_action(struct se_cmd *cmd) return false; } -static void target_complete_ok_work(struct work_struct *work) +static void target_complete_cmd_work(struct work_struct *work) { struct se_cmd *cmd = container_of(work, struct se_cmd, work); - int ret; + int ret = 0; /* * Check if we need to move delayed/dormant tasks from cmds on the @@ -2139,20 +2095,6 @@ static void target_complete_ok_work(struct work_struct *work) schedule_work(&cmd->se_dev->qf_work_queue); /* - * Check if we need to send a sense buffer from - * the struct se_cmd in question. - */ - if (cmd->se_cmd_flags & SCF_TASK_SENSE) { - WARN_ON(!cmd->scsi_status); - ret = transport_send_check_condition_and_sense(cmd, 0); - 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. */ @@ -2161,22 +2103,33 @@ static void target_complete_ok_work(struct work_struct *work) bool caw = (cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE); bool zero_dl = !(cmd->data_length); int post_ret = 0; + bool good = !(cmd->scsi_status); + + if (good || caw) { + rc = cmd->transport_complete_callback(cmd, good, + &post_ret); + if (!rc && !post_ret) { + if (caw && zero_dl) + goto queue_rsp; + + return; + } else if (rc && good) { + transport_setup_sense(cmd, rc); + } + } + } - 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); - if (ret) - goto queue_full; + if (transport_check_aborted_status(cmd, 1)) + return; - transport_lun_remove_cmd(cmd); - transport_cmd_check_stop_to_fabric(cmd); - return; - } + /* + * Check if we need to send a sense buffer from + * the struct se_cmd in question. + */ + if (cmd->se_cmd_flags & SCF_TASK_SENSE) { + WARN_ON(!cmd->scsi_status); + ret = transport_send_check_condition_and_sense(cmd, 0); + goto done; } queue_rsp: @@ -2195,18 +2148,11 @@ static void target_complete_ok_work(struct work_struct *work) if (target_read_prot_action(cmd)) { ret = transport_send_check_condition_and_sense(cmd, cmd->pi_err); - if (ret) - goto queue_full; - - transport_lun_remove_cmd(cmd); - transport_cmd_check_stop_to_fabric(cmd); - return; + break; } 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, @@ -2218,8 +2164,6 @@ static void target_complete_ok_work(struct work_struct *work) 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; } /* Fall through for DMA_TO_DEVICE */ @@ -2227,22 +2171,20 @@ static void target_complete_ok_work(struct work_struct *work) 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); +done: + if (ret) { + 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); + } else { + transport_lun_remove_cmd(cmd); + transport_cmd_check_stop_to_fabric(cmd); + } } void target_free_sgl(struct scatterlist *sgl, int nents)