From patchwork Wed May 9 20:59:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Duncan X-Patchwork-Id: 10390835 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 5945060236 for ; Wed, 9 May 2018 20:59:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 48BF52843B for ; Wed, 9 May 2018 20:59:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3D80B283D1; Wed, 9 May 2018 20:59: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=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, 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 987CA283D1 for ; Wed, 9 May 2018 20:59:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964829AbeEIU7m (ORCPT ); Wed, 9 May 2018 16:59:42 -0400 Received: from mx2.suse.de ([195.135.220.15]:38286 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935200AbeEIU7m (ORCPT ); Wed, 9 May 2018 16:59:42 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 7697FABCC; Wed, 9 May 2018 20:59:40 +0000 (UTC) From: Lee Duncan To: target-devel@vger.kernel.org Cc: nab@linux-iscsi.org, hare@suse.de, linux-scsi@vger.kernel.org, hch@infradead.org, Lee Duncan Subject: [PATCH v2] target: transport should allow st ILI reads Date: Wed, 9 May 2018 13:59:21 -0700 Message-Id: <20180509205921.12348-1-lduncan@suse.com> X-Mailer: git-send-email 2.13.6 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 When a tape drive is exported via LIO using the pscsi module, a read that requests more bytes per block than the tape can supply returns an empty buffer. This is because the pscsi pass-through target module sees the "ILI" illegal length bit set and thinks there is no reason to return the data. This is a long-standing transport issue, since it assume that no data need be returned under a check condition, which isn't always the case for tape. Add in a check for tape reads with the the ILI, EOM, or FM bits set, with a sense code of NO_SENSE, treating such cases as if there is no sense data and the read succeeded. The layered tape driver then "does the right thing" when it gets such a response. Changes from RFC: - Moved ugly code from transport to pscsi module - Added checking EOM and FM bits, as well as ILI - fixed malformed patch - Clarified description a bit Signed-off-by: Lee Duncan --- drivers/target/target_core_pscsi.c | 22 +++++++++++++++++++++- drivers/target/target_core_transport.c | 6 ++++++ include/target/target_core_base.h | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 0d99b242e82e..b237104af81c 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -689,8 +689,28 @@ static void pscsi_complete_cmd(struct se_cmd *cmd, u8 scsi_status, } after_mode_select: - if (scsi_status == SAM_STAT_CHECK_CONDITION) + if (scsi_status == SAM_STAT_CHECK_CONDITION) { transport_copy_sense_to_cmd(cmd, req_sense); + + /* + * hack to check for TAPE device reads with + * FM/EOM/ILI set, so that we can get data + * back despite framework assumption that a + * check condition means there is no data + */ + if ((sd->type == TYPE_TAPE) && + (cmd->data_direction == DMA_FROM_DEVICE)) { + /* + * is sense data valid, fixed format, + * and have FM, EOM, or ILI set? + */ + if ((req_sense[0] == 0xf0) && /* valid, fixed format */ + (req_sense[2] & 0xe0) && /* FM, EOM, or ILI */ + ((req_sense[2] & 0xf) == 0)) { /* key==NO_SENSE */ + cmd->se_cmd_flags |= SCF_TREAT_READ_AS_NORMAL; + } + } + } } enum { diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 74b646f165d4..56661a824266 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2192,6 +2192,11 @@ static void target_complete_ok_work(struct work_struct *work) if (atomic_read(&cmd->se_dev->dev_qf_count) != 0) schedule_work(&cmd->se_dev->qf_work_queue); + if (cmd->se_cmd_flags & SCF_TREAT_READ_AS_NORMAL) { + pr_debug("Tape FM/EOM/ILI status detected. Treating as OK\n"); + goto treat_as_normal_read; + } + /* * Check if we need to send a sense buffer from * the struct se_cmd in question. @@ -2241,6 +2246,7 @@ static void target_complete_ok_work(struct work_struct *work) if (cmd->scsi_status) goto queue_status; +treat_as_normal_read: atomic_long_add(cmd->data_length, &cmd->se_lun->lun_stats.tx_data_octets); /* diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 9f9f5902af38..922a39f45abc 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -143,6 +143,7 @@ enum se_cmd_flags_table { SCF_ACK_KREF = 0x00400000, SCF_USE_CPUID = 0x00800000, SCF_TASK_ATTR_SET = 0x01000000, + SCF_TREAT_READ_AS_NORMAL = 0x02000000, }; /*