From patchwork Wed Jul 29 09:23:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 6891321 Return-Path: X-Original-To: patchwork-ceph-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 1B617C05AC for ; Wed, 29 Jul 2015 09:24:15 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2E0FB207B1 for ; Wed, 29 Jul 2015 09:24:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2BD9D2079C for ; Wed, 29 Jul 2015 09:24:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752624AbbG2JYI (ORCPT ); Wed, 29 Jul 2015 05:24:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56559 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752515AbbG2JYF (ORCPT ); Wed, 29 Jul 2015 05:24:05 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id B25239C0A6; Wed, 29 Jul 2015 09:24:05 +0000 (UTC) Received: from rh2.redhat.com (vpn-60-109.rdu2.redhat.com [10.10.60.109]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t6T9Ntmq011149; Wed, 29 Jul 2015 05:24:05 -0400 From: mchristi@redhat.com To: ceph-devel@vger.kernel.org, target-devel@vger.kernel.org Subject: [PATCH 13/18] target: add COMPARE_AND_WRITE sg creation helper Date: Wed, 29 Jul 2015 04:23:50 -0500 Message-Id: <1438161835-27960-13-git-send-email-mchristi@redhat.com> In-Reply-To: <1438161835-27960-1-git-send-email-mchristi@redhat.com> References: <1438161835-27960-1-git-send-email-mchristi@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Mike Christie bc core and the rbd backend driver want seperate scatterlists for the write phase of COMPARE_AND_WRITE. This moves the sbc code to a helper function. Signed-off-by: Mike Christie --- drivers/target/target_core_sbc.c | 73 ++++++++++++++++++++++++------------ include/target/target_core_backend.h | 1 + 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 9a001e6..f803068 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -428,12 +428,58 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success) return TCM_NO_SENSE; } +/** + * sbc_create_compare_and_write_sg - alloc and prep a sg for the write phase + * @cmd: se_cmd to copy scatterlist from. + * + * Takes the cmd's scatterlist and creates a new sg with only the write + * portion. +*/ +struct scatterlist *sbc_create_compare_and_write_sg(struct se_cmd *cmd) +{ + struct se_device *dev = cmd->se_dev; + unsigned int block_size = dev->dev_attrib.block_size; + unsigned int len = cmd->t_task_nolb * block_size; + struct scatterlist *write_sg; + struct sg_mapping_iter m; + int i = 0; + + write_sg = kmalloc(sizeof(struct scatterlist) * cmd->t_data_nents, + GFP_KERNEL); + if (!write_sg) { + pr_err("Unable to allocate compare_and_write sg\n"); + return NULL; + } + sg_init_table(write_sg, cmd->t_data_nents); + + sg_miter_start(&m, cmd->t_data_sg, cmd->t_data_nents, SG_MITER_TO_SG); + /* + * Currently assumes NoLB=1 and SGLs are PAGE_SIZE.. + */ + while (len) { + sg_miter_next(&m); + + if (block_size < PAGE_SIZE) { + sg_set_page(&write_sg[i], m.page, block_size, + block_size); + } else { + sg_miter_next(&m); + sg_set_page(&write_sg[i], m.page, block_size, 0); + } + len -= block_size; + i++; + } + sg_miter_stop(&m); + + return write_sg; +} +EXPORT_SYMBOL(sbc_create_compare_and_write_sg); + static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool success) { struct se_device *dev = cmd->se_dev; struct scatterlist *write_sg = NULL, *sg; unsigned char *buf = NULL, *addr; - struct sg_mapping_iter m; unsigned int offset = 0, len; unsigned int nlbas = cmd->t_task_nolb; unsigned int block_size = dev->dev_attrib.block_size; @@ -469,14 +515,12 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes goto out; } - write_sg = kmalloc(sizeof(struct scatterlist) * cmd->t_data_nents, - GFP_KERNEL); + write_sg = sbc_create_compare_and_write_sg(cmd); if (!write_sg) { pr_err("Unable to allocate compare_and_write sg\n"); ret = TCM_OUT_OF_RESOURCES; goto out; } - sg_init_table(write_sg, cmd->t_data_nents); /* * Setup verify and write data payloads from total NumberLBAs. */ @@ -513,27 +557,6 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes break; } - i = 0; - len = cmd->t_task_nolb * block_size; - sg_miter_start(&m, cmd->t_data_sg, cmd->t_data_nents, SG_MITER_TO_SG); - /* - * Currently assumes NoLB=1 and SGLs are PAGE_SIZE.. - */ - while (len) { - sg_miter_next(&m); - - if (block_size < PAGE_SIZE) { - sg_set_page(&write_sg[i], m.page, block_size, - block_size); - } else { - sg_miter_next(&m); - sg_set_page(&write_sg[i], m.page, block_size, - 0); - } - len -= block_size; - i++; - } - sg_miter_stop(&m); /* * Save the original SGL + nents values before updating to new * assignments, to be released in transport_free_pages() -> diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index c98f6e6..d8895e2 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -61,6 +61,7 @@ void target_complete_cmd(struct se_cmd *, u8); void target_complete_cmd_with_sense(struct se_cmd *, sense_reason_t); void target_complete_cmd_with_length(struct se_cmd *, u8, int); +struct scatterlist *sbc_create_compare_and_write_sg(struct se_cmd *); sense_reason_t spc_parse_cdb(struct se_cmd *cmd, unsigned int *size); sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd); sense_reason_t spc_emulate_inquiry_std(struct se_cmd *, unsigned char *);