From patchwork Mon Oct 26 19:06:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Disseldorp X-Patchwork-Id: 287063 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DCF59C388F9 for ; Mon, 26 Oct 2020 19:13:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A632C2225C for ; Mon, 26 Oct 2020 19:13:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1792645AbgJZTNr (ORCPT ); Mon, 26 Oct 2020 15:13:47 -0400 Received: from mx2.suse.de ([195.135.220.15]:44164 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2406080AbgJZTH1 (ORCPT ); Mon, 26 Oct 2020 15:07:27 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 04504AF0D; Mon, 26 Oct 2020 19:07:26 +0000 (UTC) From: David Disseldorp To: target-devel@vger.kernel.org Cc: linux-scsi@vger.kernel.org, David Disseldorp Subject: [PATCH v2 2/5] scsi: target: rename struct sense_info to sense_detail Date: Mon, 26 Oct 2020 20:06:43 +0100 Message-Id: <20201026190646.8727-3-ddiss@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201026190646.8727-1-ddiss@suse.de> References: <20201026190646.8727-1-ddiss@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org This helps distinguish it from the SCSI sense INFORMATION field. Signed-off-by: David Disseldorp --- drivers/target/target_core_transport.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index ff26ab0a5f60..caa3a7b34826 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -3094,14 +3094,14 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) } EXPORT_SYMBOL(transport_wait_for_tasks); -struct sense_info { +struct sense_detail { u8 key; u8 asc; u8 ascq; bool add_sector_info; }; -static const struct sense_info sense_info_table[] = { +static const struct sense_detail sense_detail_table[] = { [TCM_NO_SENSE] = { .key = NOT_READY }, @@ -3261,39 +3261,39 @@ static const struct sense_info sense_info_table[] = { */ static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason) { - const struct sense_info *si; + const struct sense_detail *sd; u8 *buffer = cmd->sense_buffer; int r = (__force int)reason; u8 key, asc, ascq; bool desc_format = target_sense_desc_format(cmd->se_dev); - if (r < ARRAY_SIZE(sense_info_table) && sense_info_table[r].key) - si = &sense_info_table[r]; + if (r < ARRAY_SIZE(sense_detail_table) && sense_detail_table[r].key) + sd = &sense_detail_table[r]; else - si = &sense_info_table[(__force int) + sd = &sense_detail_table[(__force int) TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE]; - key = si->key; + key = sd->key; if (reason == TCM_CHECK_CONDITION_UNIT_ATTENTION) { if (!core_scsi3_ua_for_check_condition(cmd, &key, &asc, &ascq)) { cmd->scsi_status = SAM_STAT_BUSY; return; } - } else if (si->asc == 0) { + } else if (sd->asc == 0) { WARN_ON_ONCE(cmd->scsi_asc == 0); asc = cmd->scsi_asc; ascq = cmd->scsi_ascq; } else { - asc = si->asc; - ascq = si->ascq; + asc = sd->asc; + ascq = sd->ascq; } cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE; cmd->scsi_status = SAM_STAT_CHECK_CONDITION; cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; scsi_build_sense_buffer(desc_format, buffer, key, asc, ascq); - if (si->add_sector_info) + if (sd->add_sector_info) WARN_ON_ONCE(scsi_set_sense_information(buffer, cmd->scsi_sense_length, cmd->bad_sector) < 0); From patchwork Mon Oct 26 19:06:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Disseldorp X-Patchwork-Id: 287062 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BFAD0C4363A for ; Mon, 26 Oct 2020 19:13:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 78AB92085B for ; Mon, 26 Oct 2020 19:13:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1792650AbgJZTNx (ORCPT ); Mon, 26 Oct 2020 15:13:53 -0400 Received: from mx2.suse.de ([195.135.220.15]:44208 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1736957AbgJZTH3 (ORCPT ); Mon, 26 Oct 2020 15:07:29 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id C8BBBAFCD; Mon, 26 Oct 2020 19:07:26 +0000 (UTC) From: David Disseldorp To: target-devel@vger.kernel.org Cc: linux-scsi@vger.kernel.org, David Disseldorp Subject: [PATCH v2 5/5] scsi: target: return COMPARE AND WRITE miscompare offsets Date: Mon, 26 Oct 2020 20:06:46 +0100 Message-Id: <20201026190646.8727-6-ddiss@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201026190646.8727-1-ddiss@suse.de> References: <20201026190646.8727-1-ddiss@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org SBC-4 r15 5.3 COMPARE AND WRITE command states: if the compare operation does not indicate a match, then terminate the command with CHECK CONDITION status with the sense key set to MISCOMPARE and the additional sense code set to MISCOMPARE DURING VERIFY OPERATION. In the sense data (see 4.18 and SPC-5) the offset from the start of the Data-Out Buffer to the first byte of data that was not equal shall be reported in the INFORMATION field. This change implements the missing logic to report the miscompare offset in the sense data INFORMATION field. Signed-off-by: David Disseldorp --- drivers/target/target_core_sbc.c | 34 ++++++++++++++++++-------- drivers/target/target_core_transport.c | 1 + 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 22d0cbba6ff3..0fa52a98d6cf 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -435,13 +435,13 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success, } /* - * compare @cmp_len bytes of @read_sgl with @cmp_sgl. On miscompare return - * TCM_MISCOMPARE_VERIFY. + * compare @cmp_len bytes of @read_sgl with @cmp_sgl. On miscompare, fill + * @miscmp_off and return TCM_MISCOMPARE_VERIFY. */ static sense_reason_t compare_and_write_do_cmp(struct scatterlist *read_sgl, unsigned int read_nents, struct scatterlist *cmp_sgl, unsigned int cmp_nents, - unsigned int cmp_len) + unsigned int cmp_len, unsigned int *miscmp_off) { unsigned char *buf = NULL; struct scatterlist *sg; @@ -467,17 +467,20 @@ compare_and_write_do_cmp(struct scatterlist *read_sgl, unsigned int read_nents, */ offset = 0; for_each_sg(read_sgl, sg, read_nents, i) { + unsigned int i; unsigned int len = min(sg->length, cmp_len); unsigned char *addr = kmap_atomic(sg_page(sg)); - if (memcmp(addr, buf + offset, len)) { - pr_warn("Detected MISCOMPARE for addr: %p buf: %p\n", - addr, buf + offset); - kunmap_atomic(addr); + for (i = 0; i < len && addr[i] == buf[offset + i]; i++) + ; + kunmap_atomic(addr); + if (i < len) { + *miscmp_off = offset + i; + pr_warn("Detected MISCOMPARE at offset %u\n", + *miscmp_off); ret = TCM_MISCOMPARE_VERIFY; goto out; } - kunmap_atomic(addr); offset += len; cmp_len -= len; @@ -501,6 +504,7 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes unsigned int len; unsigned int block_size = dev->dev_attrib.block_size; unsigned int compare_len = (cmd->t_task_nolb * block_size); + unsigned int miscmp_off = 0; sense_reason_t ret = TCM_NO_SENSE; int i; @@ -532,8 +536,18 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes cmd->t_bidi_data_nents, cmd->t_data_sg, cmd->t_data_nents, - compare_len); - if (ret) + compare_len, + &miscmp_off); + if (ret == TCM_MISCOMPARE_VERIFY) { + /* + * SBC-4 r15: 5.3 COMPARE AND WRITE command + * In the sense data (see 4.18 and SPC-5) the offset from the + * start of the Data-Out Buffer to the first byte of data that + * was not equal shall be reported in the INFORMATION field. + */ + cmd->sense_info = miscmp_off; + goto out; + } else if (ret) goto out; if (sg_alloc_table(&write_tbl, cmd->t_data_nents, GFP_KERNEL) < 0) { diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index c6f45c12d564..693ed3fe4388 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -3196,6 +3196,7 @@ static const struct sense_detail sense_detail_table[] = { .key = MISCOMPARE, .asc = 0x1d, /* MISCOMPARE DURING VERIFY OPERATION */ .ascq = 0x00, + .add_sense_info = true, }, [TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED] = { .key = ABORTED_COMMAND,