From patchwork Wed Dec 12 07:41:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 10725609 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 68A1B6C5 for ; Wed, 12 Dec 2018 07:41:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 58CD82A87B for ; Wed, 12 Dec 2018 07:41:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4C0AB2AA85; Wed, 12 Dec 2018 07:41:36 +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.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,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 738BD2A87B for ; Wed, 12 Dec 2018 07:41:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726472AbeLLHlf (ORCPT ); Wed, 12 Dec 2018 02:41:35 -0500 Received: from bombadil.infradead.org ([198.137.202.133]:33072 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726242AbeLLHlf (ORCPT ); Wed, 12 Dec 2018 02:41:35 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From :Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=rTTMHd4ZQy1k8yxaf1TAHeeLFVTP827l/ppc7Std8w0=; b=PiPpVbXlfh57gxwrOpDeTRfAbE qZG5VDfeFz7VEMk4MLBabhOEWkjzLooctI9bAWg8fhijuvZv5p7OLIBhEvkGlxgOlnms/WbpOgtit +kdVVDvc1AbPrEEdERx7t5TYQDaxlZkZL1CGGVUv0Yr1eLm+j6m9rT8WtQZLR1Az6TcKv5W6WVHSG VubMsvNv0bZtFhxmpkLaAezqUvvAhRD5pUrSklJpZjJY5p/jhl2za66gawPRRpj7XqN1crHrlXVj/ rbv5xoBIM7KtTnfsxJ3LYCejRumpzO1mBgxFejFPop9rLakQCnwdoymsVfLM3VqGtZuVYm1gYjjRI qWM/wCGA==; Received: from 089144198147.atnat0007.highway.a1.net ([89.144.198.147] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.90_1 #2 (Red Hat Linux)) id 1gWz9C-0000wC-8Q; Wed, 12 Dec 2018 07:41:34 +0000 From: Christoph Hellwig To: linux-scsi@vger.kernel.org Cc: Finn Thain Subject: [PATCH 01/10] gdth: refactor ioc_general Date: Wed, 12 Dec 2018 08:41:18 +0100 Message-Id: <20181212074127.1886-2-hch@lst.de> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181212074127.1886-1-hch@lst.de> References: <20181212074127.1886-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html 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 This function is a huge mess with duplicated error handling. Split out a few useful helpers and use goto labels to untangle the error handling and no-data ioctl handling. Signed-off-by: Christoph Hellwig --- drivers/scsi/gdth.c | 250 +++++++++++++++++++++++--------------------- 1 file changed, 132 insertions(+), 118 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 16709735b546..f721af157556 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -4155,131 +4155,145 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) return 0; } -static int ioc_general(void __user *arg, char *cmnd) +static void gdth_ioc_cacheservice(gdth_ha_str *ha, gdth_ioctl_general *gen, + u64 paddr) { - gdth_ioctl_general gen; - char *buf = NULL; - u64 paddr; - gdth_ha_str *ha; - int rval; + if (ha->cache_feat & GDT_64BIT) { + /* copy elements from 32-bit IOCTL structure */ + gen->command.u.cache64.BlockCnt = gen->command.u.cache.BlockCnt; + gen->command.u.cache64.BlockNo = gen->command.u.cache.BlockNo; + gen->command.u.cache64.DeviceNo = gen->command.u.cache.DeviceNo; + + if (ha->cache_feat & SCATTER_GATHER) { + gen->command.u.cache64.DestAddr = (u64)-1; + gen->command.u.cache64.sg_canz = 1; + gen->command.u.cache64.sg_lst[0].sg_ptr = paddr; + gen->command.u.cache64.sg_lst[0].sg_len = gen->data_len; + gen->command.u.cache64.sg_lst[1].sg_len = 0; + } else { + gen->command.u.cache64.DestAddr = paddr; + gen->command.u.cache64.sg_canz = 0; + } + } else { + if (ha->cache_feat & SCATTER_GATHER) { + gen->command.u.cache.DestAddr = 0xffffffff; + gen->command.u.cache.sg_canz = 1; + gen->command.u.cache.sg_lst[0].sg_ptr = (u32)paddr; + gen->command.u.cache.sg_lst[0].sg_len = gen->data_len; + gen->command.u.cache.sg_lst[1].sg_len = 0; + } else { + gen->command.u.cache.DestAddr = paddr; + gen->command.u.cache.sg_canz = 0; + } + } +} - if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general))) - return -EFAULT; - ha = gdth_find_ha(gen.ionode); - if (!ha) - return -EFAULT; +static void gdth_ioc_scsiraw(gdth_ha_str *ha, gdth_ioctl_general *gen, + u64 paddr) +{ + if (ha->raw_feat & GDT_64BIT) { + /* copy elements from 32-bit IOCTL structure */ + char cmd[16]; + + gen->command.u.raw64.sense_len = gen->command.u.raw.sense_len; + gen->command.u.raw64.bus = gen->command.u.raw.bus; + gen->command.u.raw64.lun = gen->command.u.raw.lun; + gen->command.u.raw64.target = gen->command.u.raw.target; + memcpy(cmd, gen->command.u.raw.cmd, 16); + memcpy(gen->command.u.raw64.cmd, cmd, 16); + gen->command.u.raw64.clen = gen->command.u.raw.clen; + gen->command.u.raw64.sdlen = gen->command.u.raw.sdlen; + gen->command.u.raw64.direction = gen->command.u.raw.direction; + + /* addresses */ + if (ha->raw_feat & SCATTER_GATHER) { + gen->command.u.raw64.sdata = (u64)-1; + gen->command.u.raw64.sg_ranz = 1; + gen->command.u.raw64.sg_lst[0].sg_ptr = paddr; + gen->command.u.raw64.sg_lst[0].sg_len = gen->data_len; + gen->command.u.raw64.sg_lst[1].sg_len = 0; + } else { + gen->command.u.raw64.sdata = paddr; + gen->command.u.raw64.sg_ranz = 0; + } - if (gen.data_len > INT_MAX) - return -EINVAL; - if (gen.sense_len > INT_MAX) - return -EINVAL; - if (gen.data_len + gen.sense_len > INT_MAX) - return -EINVAL; + gen->command.u.raw64.sense_data = paddr + gen->data_len; + } else { + if (ha->raw_feat & SCATTER_GATHER) { + gen->command.u.raw.sdata = 0xffffffff; + gen->command.u.raw.sg_ranz = 1; + gen->command.u.raw.sg_lst[0].sg_ptr = (u32)paddr; + gen->command.u.raw.sg_lst[0].sg_len = gen->data_len; + gen->command.u.raw.sg_lst[1].sg_len = 0; + } else { + gen->command.u.raw.sdata = paddr; + gen->command.u.raw.sg_ranz = 0; + } - if (gen.data_len + gen.sense_len != 0) { - if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, - FALSE, &paddr))) - return -EFAULT; - if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general), - gen.data_len + gen.sense_len)) { - gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); - return -EFAULT; - } + gen->command.u.raw.sense_data = (u32)paddr + gen->data_len; + } +} - if (gen.command.OpCode == GDT_IOCTL) { - gen.command.u.ioctl.p_param = paddr; - } else if (gen.command.Service == CACHESERVICE) { - if (ha->cache_feat & GDT_64BIT) { - /* copy elements from 32-bit IOCTL structure */ - gen.command.u.cache64.BlockCnt = gen.command.u.cache.BlockCnt; - gen.command.u.cache64.BlockNo = gen.command.u.cache.BlockNo; - gen.command.u.cache64.DeviceNo = gen.command.u.cache.DeviceNo; - /* addresses */ - if (ha->cache_feat & SCATTER_GATHER) { - gen.command.u.cache64.DestAddr = (u64)-1; - gen.command.u.cache64.sg_canz = 1; - gen.command.u.cache64.sg_lst[0].sg_ptr = paddr; - gen.command.u.cache64.sg_lst[0].sg_len = gen.data_len; - gen.command.u.cache64.sg_lst[1].sg_len = 0; - } else { - gen.command.u.cache64.DestAddr = paddr; - gen.command.u.cache64.sg_canz = 0; - } - } else { - if (ha->cache_feat & SCATTER_GATHER) { - gen.command.u.cache.DestAddr = 0xffffffff; - gen.command.u.cache.sg_canz = 1; - gen.command.u.cache.sg_lst[0].sg_ptr = (u32)paddr; - gen.command.u.cache.sg_lst[0].sg_len = gen.data_len; - gen.command.u.cache.sg_lst[1].sg_len = 0; - } else { - gen.command.u.cache.DestAddr = paddr; - gen.command.u.cache.sg_canz = 0; - } - } - } else if (gen.command.Service == SCSIRAWSERVICE) { - if (ha->raw_feat & GDT_64BIT) { - /* copy elements from 32-bit IOCTL structure */ - char cmd[16]; - gen.command.u.raw64.sense_len = gen.command.u.raw.sense_len; - gen.command.u.raw64.bus = gen.command.u.raw.bus; - gen.command.u.raw64.lun = gen.command.u.raw.lun; - gen.command.u.raw64.target = gen.command.u.raw.target; - memcpy(cmd, gen.command.u.raw.cmd, 16); - memcpy(gen.command.u.raw64.cmd, cmd, 16); - gen.command.u.raw64.clen = gen.command.u.raw.clen; - gen.command.u.raw64.sdlen = gen.command.u.raw.sdlen; - gen.command.u.raw64.direction = gen.command.u.raw.direction; - /* addresses */ - if (ha->raw_feat & SCATTER_GATHER) { - gen.command.u.raw64.sdata = (u64)-1; - gen.command.u.raw64.sg_ranz = 1; - gen.command.u.raw64.sg_lst[0].sg_ptr = paddr; - gen.command.u.raw64.sg_lst[0].sg_len = gen.data_len; - gen.command.u.raw64.sg_lst[1].sg_len = 0; - } else { - gen.command.u.raw64.sdata = paddr; - gen.command.u.raw64.sg_ranz = 0; - } - gen.command.u.raw64.sense_data = paddr + gen.data_len; - } else { - if (ha->raw_feat & SCATTER_GATHER) { - gen.command.u.raw.sdata = 0xffffffff; - gen.command.u.raw.sg_ranz = 1; - gen.command.u.raw.sg_lst[0].sg_ptr = (u32)paddr; - gen.command.u.raw.sg_lst[0].sg_len = gen.data_len; - gen.command.u.raw.sg_lst[1].sg_len = 0; - } else { - gen.command.u.raw.sdata = paddr; - gen.command.u.raw.sg_ranz = 0; - } - gen.command.u.raw.sense_data = (u32)paddr + gen.data_len; - } - } else { - gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); - return -EFAULT; - } - } +static int ioc_general(void __user *arg, char *cmnd) +{ + gdth_ioctl_general gen; + gdth_ha_str *ha; + char *buf = NULL; + u64 paddr; + int rval; + + if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general))) + return -EFAULT; + ha = gdth_find_ha(gen.ionode); + if (!ha) + return -EFAULT; + + if (gen.data_len > INT_MAX) + return -EINVAL; + if (gen.sense_len > INT_MAX) + return -EINVAL; + if (gen.data_len + gen.sense_len > INT_MAX) + return -EINVAL; + + if (gen.data_len + gen.sense_len > 0) { + buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, FALSE, + &paddr); + if (!buf) + return -EFAULT; + + rval = -EFAULT; + if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general), + gen.data_len + gen.sense_len)) + goto out_free_buf; + + if (gen.command.OpCode == GDT_IOCTL) + gen.command.u.ioctl.p_param = paddr; + else if (gen.command.Service == CACHESERVICE) + gdth_ioc_cacheservice(ha, &gen, paddr); + else if (gen.command.Service == SCSIRAWSERVICE) + gdth_ioc_scsiraw(ha, &gen, paddr); + else + goto out_free_buf; + } - rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout, &gen.info); - if (rval < 0) { + rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout, + &gen.info); + if (rval < 0) + goto out_free_buf; + gen.status = rval; + + rval = -EFAULT; + if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, + gen.data_len + gen.sense_len)) + goto out_free_buf; + if (copy_to_user(arg, &gen, + sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) + goto out_free_buf; + + rval = 0; +out_free_buf: gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); - return rval; - } - gen.status = rval; - - if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, - gen.data_len + gen.sense_len)) { - gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); - return -EFAULT; - } - if (copy_to_user(arg, &gen, - sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) { - gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); - return -EFAULT; - } - gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); - return 0; + return rval; } static int ioc_hdrlist(void __user *arg, char *cmnd)