From patchwork Wed Mar 7 03:21:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Douglas Gilbert X-Patchwork-Id: 10263331 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 927AE60247 for ; Wed, 7 Mar 2018 03:21:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 88D1A2945A for ; Wed, 7 Mar 2018 03:21:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 87A5629462; Wed, 7 Mar 2018 03:21:44 +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 F282329476 for ; Wed, 7 Mar 2018 03:21:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933048AbeCGDVn (ORCPT ); Tue, 6 Mar 2018 22:21:43 -0500 Received: from smtp.infotech.no ([82.134.31.41]:56301 "EHLO smtp.infotech.no" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933020AbeCGDVm (ORCPT ); Tue, 6 Mar 2018 22:21:42 -0500 Received: from localhost (localhost [127.0.0.1]) by smtp.infotech.no (Postfix) with ESMTP id 64FE620423B; Wed, 7 Mar 2018 04:21:41 +0100 (CET) X-Virus-Scanned: by amavisd-new-2.6.6 (20110518) (Debian) at infotech.no Received: from smtp.infotech.no ([127.0.0.1]) by localhost (smtp.infotech.no [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id UTG+7O4LQ2BJ; Wed, 7 Mar 2018 04:21:39 +0100 (CET) Received: from xtwo70.bingwo.ca (host-184-164-15-239.dyn.295.ca [184.164.15.239]) by smtp.infotech.no (Postfix) with ESMTPA id 98B8220414D; Wed, 7 Mar 2018 04:21:38 +0100 (CET) From: Douglas Gilbert To: linux-scsi@vger.kernel.org Cc: martin.petersen@oracle.com, jejb@linux.vnet.ibm.com, hare@suse.de, bart.vanassche@wdc.com, jthumshirn@suse.de Subject: [PATCH 2/5] scsi_io_completion: add _nz_result helper Date: Tue, 6 Mar 2018 22:21:31 -0500 Message-Id: <20180307032134.18978-3-dgilbert@interlog.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180307032134.18978-1-dgilbert@interlog.com> References: <20180307032134.18978-1-dgilbert@interlog.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP ChangeLog: - break out several interwined paths when cmd->result is non zero and place them in scsi_io_completion_nz_result helper function - after a review comment that proposed reducing the helper's former 2 return values to a single return value, use BLK_STS_NOTSUPP as a marker that the helper did not change the blk_status. This is cleaned up just after its invocation in scsi_io_completion. Signed-off-by: Douglas Gilbert --- drivers/scsi/scsi_lib.c | 125 ++++++++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 51 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 92eea43cfa6f..e19531b39394 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -739,6 +739,74 @@ static blk_status_t __scsi_error_from_host_byte(struct scsi_cmnd *cmd, } } +/* + * Helper for scsi_io_completion() when cmd->result is non-zero. Returns + * BLK_STS_NOTSUPP if this function does not change blk_status . + */ +static blk_status_t scsi_io_completion_nz_result(struct scsi_cmnd *cmd, + int result) +{ + bool sense_valid; + bool about_current; + /* __scsi_error_from_host_byte() does not return BLK_STS_NOTSUPP */ + blk_status_t blk_stat = BLK_STS_NOTSUPP; + struct request *req = cmd->request; + struct scsi_sense_hdr sshdr; + + sense_valid = scsi_command_normalize_sense(cmd, &sshdr); + about_current = sense_valid ? !scsi_sense_is_deferred(&sshdr) : true; + + if (blk_rq_is_passthrough(req)) { + if (sense_valid) { + /* + * SG_IO wants current and deferred errors + */ + scsi_req(req)->sense_len = + min(8 + cmd->sense_buffer[7], + SCSI_SENSE_BUFFERSIZE); + } + if (about_current) + blk_stat = __scsi_error_from_host_byte(cmd, result); + } else if (blk_rq_bytes(req) == 0 && about_current) { + /* + * Flush commands do not transfers any data, and thus cannot use + * good_bytes != blk_rq_bytes(req) as the signal for an error. + * This sets blk_stat explicitly for the problem case. + */ + blk_stat = __scsi_error_from_host_byte(cmd, result); + } + /* + * Recovered errors need reporting, but they're always treated as + * success, so fiddle the result code here. For passthrough requests + * we already took a copy of the original into sreq->result which + * is what gets returned to the user + */ + if (sense_valid && (sshdr.sense_key == RECOVERED_ERROR)) { + /* + * if ATA PASS-THROUGH INFORMATION AVAILABLE skip + * print since caller wants ATA registers. Only occurs + * on SCSI ATA PASS_THROUGH commands when CK_COND=1 + */ + if ((sshdr.asc == 0x0) && (sshdr.ascq == 0x1d)) + ; + else if (!(req->rq_flags & RQF_QUIET)) + scsi_print_sense(cmd); + /* for passthrough, blk_stat may be set */ + blk_stat = BLK_STS_OK; + } + /* + * Another corner case: the SCSI status byte is non-zero but 'good'. + * Example: PRE-FETCH command returns SAM_STAT_CONDITION_MET when + * it is able to fit nominated LBs in its cache (and SAM_STAT_GOOD + * if it can't fit). Treat SAM_STAT_CONDITION_MET and the related + * intermediate statuses (both obsolete in SAM-4) as good. + */ + if (status_byte(result) && scsi_status_is_good(result)) + blk_stat = BLK_STS_OK; + + return blk_stat; +} + /* * Function: scsi_io_completion() * @@ -786,22 +854,15 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) sense_valid = scsi_command_normalize_sense(cmd, &sshdr); if (sense_valid) sense_current = !scsi_sense_is_deferred(&sshdr); + blk_stat = scsi_io_completion_nz_result(cmd, result); + if (blk_stat == BLK_STS_OK) + result = 0; + if (blk_stat == BLK_STS_NOTSUPP) /* flagging no change */ + blk_stat = BLK_STS_OK; + } if (blk_rq_is_passthrough(req)) { - if (result) { - if (sense_valid) { - /* - * SG_IO wants current and deferred errors - */ - scsi_req(req)->sense_len = - min(8 + cmd->sense_buffer[7], - SCSI_SENSE_BUFFERSIZE); - } - if (sense_current) - blk_stat = __scsi_error_from_host_byte(cmd, - result); - } /* * __scsi_error_from_host_byte may have reset the host_byte */ @@ -819,13 +880,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) BUG(); return; } - } else if (blk_rq_bytes(req) == 0 && result && sense_current) { - /* - * Flush commands do not transfers any data, and thus cannot use - * good_bytes != blk_rq_bytes(req) as the signal for an error. - * This sets blk_stat explicitly for the problem case. - */ - blk_stat = __scsi_error_from_host_byte(cmd, result); } /* no bidi support for !blk_rq_is_passthrough yet */ @@ -839,37 +893,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) "%u sectors total, %d bytes done.\n", blk_rq_sectors(req), good_bytes)); - /* - * Recovered errors need reporting, but they're always treated as - * success, so fiddle the result code here. For passthrough requests - * we already took a copy of the original into sreq->result which - * is what gets returned to the user - */ - if (sense_valid && (sshdr.sense_key == RECOVERED_ERROR)) { - /* if ATA PASS-THROUGH INFORMATION AVAILABLE skip - * print since caller wants ATA registers. Only occurs on - * SCSI ATA PASS_THROUGH commands when CK_COND=1 - */ - if ((sshdr.asc == 0x0) && (sshdr.ascq == 0x1d)) - ; - else if (!(req->rq_flags & RQF_QUIET)) - scsi_print_sense(cmd); - result = 0; - /* for passthrough, blk_stat may be set */ - blk_stat = BLK_STS_OK; - } - /* - * Another corner case: the SCSI status byte is non-zero but 'good'. - * Example: PRE-FETCH command returns SAM_STAT_CONDITION_MET when - * it is able to fit nominated LBs in its cache (and SAM_STAT_GOOD - * if it can't fit). Treat SAM_STAT_CONDITION_MET and the related - * intermediate statuses (both obsolete in SAM-4) as good. - */ - if (status_byte(result) && scsi_status_is_good(result)) { - result = 0; - blk_stat = BLK_STS_OK; - } - /* * Next deal with any sectors which we were able to correctly * handle. Failed, zero length commands always need to drop down