From patchwork Tue May 8 15:44:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bodo Stroesser X-Patchwork-Id: 10386435 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 94A6C60236 for ; Tue, 8 May 2018 15:44:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8275D28F35 for ; Tue, 8 May 2018 15:44:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 74EAA28F39; Tue, 8 May 2018 15:44:39 +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 84F2828F3C for ; Tue, 8 May 2018 15:44:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755110AbeEHPoh (ORCPT ); Tue, 8 May 2018 11:44:37 -0400 Received: from mail1.bemta5.messagelabs.com ([195.245.231.152]:21293 "EHLO mail1.bemta5.messagelabs.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754622AbeEHPof (ORCPT ); Tue, 8 May 2018 11:44:35 -0400 Received: from [85.158.136.83] (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256 bits)) by server-16.bemta-5.messagelabs.com id BF/C2-21081-1E5C1FA5; Tue, 08 May 2018 15:44:33 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpjkeJIrShJLcpLzFFi42Kxs+GYovvw6Mc ogz/z1Sxal75lcmD0+LxJLoAxijUzLym/IoE1o+XkY5aCc0YVj26eZG5g3K/ZxcjFISRwjFFi 763fTBBOB6PE7dNX2LsYOTlYBFQl/m5czQZiswnoS7SumQ9miwgoSGz9fI4FxGYW8JG4OvcWW L2wgKnE4w8HweK8Ao4SU5r3gtWLCqhJPD6+mwkiLihxcuYTqF4tiRv/XjJB2PIS29/OYZ7AyD MLSdksJGWzkJQtYGRexahRnFpUllqka2Skl1SUmZ5RkpuYmaNraGCql5taXJyYnpqTmFSsl5y fu4kRGD71DAyMOxj3tPsdYpTkYFIS5ZVc9TFKiC8pP6UyI7E4I76oNCe1+BCjDAeHkgTvniNA OcGi1PTUirTMHGAgw6QlOHiURHgvgKR5iwsSc4sz0yFSpxgVpcR5F4IkBEASGaV5cG2w6LnEK CslzMvIwMAgxFOQWpSbWYIq/4pRnINRSZj3GMgUnsy8Erjpr4AWMwEtFnzwHmRxSSJCSqqBUe Kc7nLP6JdTW7nk5n4xzTCIYz/Mf27WBxYVs6KUThF5xbjPYZc4njtGHbjW2CrHdsD2t1Nh2ny zrVnnYj/tfHm+/7vbjb3Pda8LhEU8sC21Pfp25hO+kIyJs9u+zmV6Ixzz1T1y9W0hm64zJw89 nDV1Q37LsSLm0H1iyTyH+vfvbnv31OD3AiWW4oxEQy3mouJEADuoshaZAgAA X-Env-Sender: bstroesser@ts.fujitsu.com X-Msg-Ref: server-11.tower-36.messagelabs.com!1525794264!109038147!1 X-Originating-IP: [62.60.8.148] X-SYMC-ESS-Client-Auth: outbound-route-from=pass X-StarScan-Received: X-StarScan-Version: 9.9.15; banners=-,-,- X-VirusChecked: Checked Received: (qmail 15133 invoked from network); 8 May 2018 15:44:24 -0000 Received: from unknown (HELO mailhost1.uk.fujitsu.com) (62.60.8.148) by server-11.tower-36.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 8 May 2018 15:44:24 -0000 Received: from abgdgate60u.abg.fsc.net ([172.25.138.90]) by mailhost1.uk.fujitsu.com (8.14.5/8.14.5) with ESMTP id w48FiODm003508 for ; Tue, 8 May 2018 16:44:24 +0100 Received: from unknown (HELO BodoDevel.test.fsc.net) ([172.17.80.59]) by abgdgate60u.abg.fsc.net with SMTP; 08 May 2018 17:44:24 +0200 Date: Tue, 08 May 2018 17:44:23 +0200 From: Bodo Stroesser To: target-devel@vger.kernel.org Cc: lduncan@suse.com, hare@suse.de, mchristi@redhat.com, nab@linux-iscsi.org Subject: [PATCH RFC] TCMUser: add read length support Message-ID: <5af1c5d7.GFiV296jLjRKRJI0%bstroesser@ts.fujitsu.com> User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 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 Hi, We are going to use TCMUser for an emulation of tape devices and media chargers. Generally target core and TCMUser seem to work fine for this purpose. But there is at least one situation, where TCMUser as well as the target core currently are not able to support sequential access device emulation correctly. The situation is when an initiator sends a SCSI READ CDB with a length that is greater than the length of the tape block to read. We can distinguish two subcases: A) The initiator sent the READ CDB without the SILI bit being set. In this case the sequential access device has to transfer the data from the tape block (only the length of the tape block) and transmit a good status. The current interface between TCMUser and the userspace does not support reduction of the read data size by the userspace program. The patch/RFC below fixes this subcase by allowing the userspace program to specify a reduced data size in read direction. B) The initiator sent the READ CDB with the SILI bit not being set. In this case the sequential access device has to transfer the data from the tape block as in A), but additionally has to transmit CHECK CONDITION with the ILI bit set and NO SENSE in the sensebytes. The information field in the sensebytes must contain the residual count. With the below patch/RFC a user space program can specify the real read data length and appropriate sensebytes. But AFAICS, up to now the target core is not prepared to transfer datas _and_ sensebytes for a single SCSI command. Therefore only the status and sensebytes are transferred, but no data. I fear, fixing this would result in more invasive patches. Suggestions how to fix would be welcome. This patch was created for kernel 4.15.9. Best regards, Bodo --- include/uapi/linux/target_core_user.h | 4 ++- drivers/target/target_core_user.c | 40 +++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 9 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- a/include/uapi/linux/target_core_user.h +++ b/include/uapi/linux/target_core_user.h @@ -43,6 +43,7 @@ #define TCMU_MAILBOX_VERSION 2 #define ALIGN_SIZE 64 /* Should be enough for most CPUs */ #define TCMU_MAILBOX_FLAG_CAP_OOOC (1 << 0) /* Out-of-order completions */ +#define TCMU_MAILBOX_FLAG_CAP_READ_LEN (1 << 1) /* Read data length */ struct tcmu_mailbox { __u16 version; @@ -70,6 +71,7 @@ struct tcmu_cmd_entry_hdr { __u16 cmd_id; __u8 kflags; #define TCMU_UFLAG_UNKNOWN_OP 0x1 +#define TCMU_UFLAG_READ_LEN 0x2 __u8 uflags; } __packed; @@ -118,7 +120,7 @@ struct tcmu_cmd_entry { __u8 scsi_status; __u8 __pad1; __u16 __pad2; - __u32 __pad3; + __u32 read_len; char sense_buffer[TCMU_SENSE_BUFFERSIZE]; } rsp; }; --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -576,7 +576,7 @@ static int scatter_data_area(struct tcmu } static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd, - bool bidi) + bool bidi, uint32_t *read_len) { struct se_cmd *se_cmd = cmd->se_cmd; int i, dbi; @@ -587,6 +587,7 @@ static void gather_data_area(struct tcmu struct page *page; unsigned int data_nents; uint32_t count = 0; + uint32_t len_remaining = *read_len; if (!bidi) { data_sg = se_cmd->t_data_sg; @@ -609,7 +610,7 @@ static void gather_data_area(struct tcmu for_each_sg(data_sg, sg, data_nents, i) { int sg_remaining = sg->length; to = kmap_atomic(sg_page(sg)) + sg->offset; - while (sg_remaining > 0) { + while (sg_remaining > 0 && len_remaining > 0) { if (block_remaining == 0) { if (from) kunmap_atomic(from); @@ -621,6 +622,7 @@ static void gather_data_area(struct tcmu } copy_bytes = min_t(size_t, sg_remaining, block_remaining); + copy_bytes = min_t(size_t, copy_bytes, len_remaining); offset = DATA_BLOCK_SIZE - block_remaining; tcmu_flush_dcache_range(from, copy_bytes); memcpy(to + sg->length - sg_remaining, from + offset, @@ -628,11 +630,15 @@ static void gather_data_area(struct tcmu sg_remaining -= copy_bytes; block_remaining -= copy_bytes; + len_remaining -= copy_bytes; } kunmap_atomic(to - sg->offset); + if (len_remaining == 0) + break; } if (from) kunmap_atomic(from); + *read_len -= len_remaining; } static inline size_t spc_bitmap_free(unsigned long *bitmap, uint32_t thresh) @@ -947,6 +953,8 @@ static void tcmu_handle_completion(struc { struct se_cmd *se_cmd = cmd->se_cmd; struct tcmu_dev *udev = cmd->tcmu_dev; + bool read_len_valid = 0; + uint32_t read_len = 0xffffffff; /* * cmd has been completed already from timeout, just reclaim @@ -961,21 +969,37 @@ static void tcmu_handle_completion(struc pr_warn("TCMU: Userspace set UNKNOWN_OP flag on se_cmd %p\n", cmd->se_cmd); entry->rsp.scsi_status = SAM_STAT_CHECK_CONDITION; - } else if (entry->rsp.scsi_status == SAM_STAT_CHECK_CONDITION) { + goto done; + } + + read_len_valid = entry->hdr.uflags & TCMU_UFLAG_READ_LEN; + if (read_len_valid) + read_len = entry->rsp.read_len; + + if (entry->rsp.scsi_status == SAM_STAT_CHECK_CONDITION) { transport_copy_sense_to_cmd(se_cmd, entry->rsp.sense_buffer); - } else if (se_cmd->se_cmd_flags & SCF_BIDI) { + if (!read_len_valid ) + goto done; + } + if (se_cmd->se_cmd_flags & SCF_BIDI) { /* Get Data-In buffer before clean up */ - gather_data_area(udev, cmd, true); + gather_data_area(udev, cmd, true, &read_len); } else if (se_cmd->data_direction == DMA_FROM_DEVICE) { - gather_data_area(udev, cmd, false); + gather_data_area(udev, cmd, false, &read_len); } else if (se_cmd->data_direction == DMA_TO_DEVICE) { + read_len_valid = false; /* TODO: */ } else if (se_cmd->data_direction != DMA_NONE) { pr_warn("TCMU: data direction was %d!\n", se_cmd->data_direction); } - target_complete_cmd(cmd->se_cmd, entry->rsp.scsi_status); +done: + if (read_len_valid) + target_complete_cmd_with_length(cmd->se_cmd, + entry->rsp.scsi_status, read_len); + else + target_complete_cmd(cmd->se_cmd, entry->rsp.scsi_status); out: cmd->se_cmd = NULL; @@ -1532,7 +1556,7 @@ static int tcmu_configure_device(struct /* Initialise the mailbox of the ring buffer */ mb = udev->mb_addr; mb->version = TCMU_MAILBOX_VERSION; - mb->flags = TCMU_MAILBOX_FLAG_CAP_OOOC; + mb->flags = TCMU_MAILBOX_FLAG_CAP_OOOC | TCMU_MAILBOX_FLAG_CAP_READ_LEN; mb->cmdr_off = CMDR_OFF; mb->cmdr_size = udev->cmdr_size;