Received: by 2002:ac0:8c9a:0:0:0:0:0 with SMTP id r26csp103940ima; Thu, 31 Jan 2019 23:57:00 -0800 (PST) X-Google-Smtp-Source: ALg8bN5Gw52weSagMAfKdMoRCeM1hRBUNFXv1oyFN8/dlQ6O48IcKfROHs32xDObr4nQuyafBdtv X-Received: by 2002:a17:902:ab92:: with SMTP id f18mr36881045plr.221.1549007820853; Thu, 31 Jan 2019 23:57:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549007820; cv=none; d=google.com; s=arc-20160816; b=zfEVdG6KSTJRzOWp55h3dIXyJi0saHsyB4e5M234hVf9MFSA7tnYyO2nkebz8wGxov Cu+uuY+IFh92BGCDa6tV62MnxDI+twhqVvqH24aaJ/bWfc1QCXJ0+sILAFB+NsbcF6yG 12eH7K4wwVe+b0qQCLw2iYD94GjM9RjLfV28Xc5J41p/i3Q7g/CnRaT0F4H5gGlVK3vW PRyEasKCsM73Csuk5I4N1PLKCJY37bkJJggC7trAlPqcMHLF+pb/kkLavtlQc6Clzsor fJEeAF+fVNlJkAglceuxsj1R3Mo9A6IDIW7cekgQZzSk5BeRgAG0U0Vwm0nm+hjtQEQJ MxAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=nHfwlcHmoxRFtQ76i+nsMJQiGCw1RgNUHm664wxU9fs=; b=Nk1dmNTbmJvsXfDf7+EnUOV93Of0vCiEXmHrDOuu9Excb2F5yAqz9MF7RMz7Ni4LoW YoGryQ4azZ0HG16sr1RDYE+NmJgLqktJmsNdNioOP5iKZkzzXDCEPikzoLPRuAKnqVlO 13H9Ee8Z/JqBV47qVSz8VbHCmvYTJ/HK1LZlA/Q0J+r601TdXUHB5tYI3sjQQSgE1ofX s2jEaDD61MPA+B4AMD6o7jtzgaIxTIkGfZV7oeacv3F7OUKoG4humRX3VJ3XfPJ+RFaR 3IMclmCCLkNiztUxOY47z2lNTlRwQAT9F2HX/icBAu7VKaqDh6s43pMRGEiTgiITNeX7 ps5A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=ZfQfrY5k; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d2si4566563pfe.159.2019.01.31.23.56.45; Thu, 31 Jan 2019 23:57:00 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=ZfQfrY5k; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728297AbfBAH4K (ORCPT + 99 others); Fri, 1 Feb 2019 02:56:10 -0500 Received: from bombadil.infradead.org ([198.137.202.133]:33990 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725837AbfBAH4I (ORCPT ); Fri, 1 Feb 2019 02:56:08 -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=nHfwlcHmoxRFtQ76i+nsMJQiGCw1RgNUHm664wxU9fs=; b=ZfQfrY5krmGNOE54OHAvq6t35L ZC3oYR/ACaxQlP0pWoVJPa80anCiQFlMELYytUHa9LCbO67jVyUXbTfgSG5Fl3ALBpIwP2+Sc8DW3 Iwsf8J6GaOChmklBqIxtuhQ7afDno9d6QSNgy4wua6xBAAyBbDpiMXuYfV6aJDLhicrtvDNHmlrvI VJx0SawqTkgBxHkOtjOhlQyBtJasv0sdMf56oEsFXfgnYTqOj3UHAXUisP6Yh9t/05woD6DBu4Qh0 sPulZyRsV0aUx+LFtYqGBm2YXbnwSUIKN1IvCwQVVkaKavBWcJB+bWXXVIM1bqdv5Fr3ZEZAe0JTA IUTiRHww==; Received: from 089144212163.atnat0021.highway.a1.net ([89.144.212.163] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.90_1 #2 (Red Hat Linux)) id 1gpTgB-0005f9-Ie; Fri, 01 Feb 2019 07:56:04 +0000 From: Christoph Hellwig To: axboe@kernel.dk, martin.petersen@oracle.com, ooo@electrozaur.com Cc: Johannes Thumshirn , Benjamin Block , linux-scsi@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Block , Avri Altman Subject: [PATCH 1/8] bsg: refactor bsg_ioctl Date: Fri, 1 Feb 2019 08:55:50 +0100 Message-Id: <20190201075557.9249-2-hch@lst.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190201075557.9249-1-hch@lst.de> References: <20190201075557.9249-1-hch@lst.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Move all actual functionality into helpers, just leaving the dispatch in this function. Signed-off-by: Christoph Hellwig Reviewed-by: Benjamin Block Tested-by: Benjamin Block Tested-by: Avri Altman --- block/bsg.c | 158 ++++++++++++++++++++++++---------------------------- 1 file changed, 72 insertions(+), 86 deletions(-) diff --git a/block/bsg.c b/block/bsg.c index 50e5f8f666f2..a799b0ace55c 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -138,32 +138,35 @@ static const struct bsg_ops bsg_scsi_ops = { .free_rq = bsg_scsi_free_rq, }; -static struct request * -bsg_map_hdr(struct request_queue *q, struct sg_io_v4 *hdr, fmode_t mode) +static int bsg_sg_io(struct request_queue *q, fmode_t mode, void __user *uarg) { struct request *rq, *next_rq = NULL; + struct bio *bio, *bidi_bio = NULL; + struct sg_io_v4 hdr; int ret; - if (!q->bsg_dev.class_dev) - return ERR_PTR(-ENXIO); + if (copy_from_user(&hdr, uarg, sizeof(hdr))) + return -EFAULT; - if (hdr->guard != 'Q') - return ERR_PTR(-EINVAL); + if (!q->bsg_dev.class_dev) + return -ENXIO; - ret = q->bsg_dev.ops->check_proto(hdr); + if (hdr.guard != 'Q') + return -EINVAL; + ret = q->bsg_dev.ops->check_proto(&hdr); if (ret) - return ERR_PTR(ret); + return ret; - rq = blk_get_request(q, hdr->dout_xfer_len ? + rq = blk_get_request(q, hdr.dout_xfer_len ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0); if (IS_ERR(rq)) - return rq; + return PTR_ERR(rq); - ret = q->bsg_dev.ops->fill_hdr(rq, hdr, mode); + ret = q->bsg_dev.ops->fill_hdr(rq, &hdr, mode); if (ret) goto out; - rq->timeout = msecs_to_jiffies(hdr->timeout); + rq->timeout = msecs_to_jiffies(hdr.timeout); if (!rq->timeout) rq->timeout = q->sg_timeout; if (!rq->timeout) @@ -171,7 +174,7 @@ bsg_map_hdr(struct request_queue *q, struct sg_io_v4 *hdr, fmode_t mode) if (rq->timeout < BLK_MIN_SG_TIMEOUT) rq->timeout = BLK_MIN_SG_TIMEOUT; - if (hdr->dout_xfer_len && hdr->din_xfer_len) { + if (hdr.dout_xfer_len && hdr.din_xfer_len) { if (!test_bit(QUEUE_FLAG_BIDI, &q->queue_flags)) { ret = -EOPNOTSUPP; goto out; @@ -188,42 +191,29 @@ bsg_map_hdr(struct request_queue *q, struct sg_io_v4 *hdr, fmode_t mode) } rq->next_rq = next_rq; - ret = blk_rq_map_user(q, next_rq, NULL, uptr64(hdr->din_xferp), - hdr->din_xfer_len, GFP_KERNEL); + ret = blk_rq_map_user(q, next_rq, NULL, uptr64(hdr.din_xferp), + hdr.din_xfer_len, GFP_KERNEL); if (ret) goto out_free_nextrq; } - if (hdr->dout_xfer_len) { - ret = blk_rq_map_user(q, rq, NULL, uptr64(hdr->dout_xferp), - hdr->dout_xfer_len, GFP_KERNEL); - } else if (hdr->din_xfer_len) { - ret = blk_rq_map_user(q, rq, NULL, uptr64(hdr->din_xferp), - hdr->din_xfer_len, GFP_KERNEL); + if (hdr.dout_xfer_len) { + ret = blk_rq_map_user(q, rq, NULL, uptr64(hdr.dout_xferp), + hdr.dout_xfer_len, GFP_KERNEL); + } else if (hdr.din_xfer_len) { + ret = blk_rq_map_user(q, rq, NULL, uptr64(hdr.din_xferp), + hdr.din_xfer_len, GFP_KERNEL); } if (ret) goto out_unmap_nextrq; - return rq; -out_unmap_nextrq: + bio = rq->bio; if (rq->next_rq) - blk_rq_unmap_user(rq->next_rq->bio); -out_free_nextrq: - if (rq->next_rq) - blk_put_request(rq->next_rq); -out: - q->bsg_dev.ops->free_rq(rq); - blk_put_request(rq); - return ERR_PTR(ret); -} - -static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, - struct bio *bio, struct bio *bidi_bio) -{ - int ret; + bidi_bio = rq->next_rq->bio; - ret = rq->q->bsg_dev.ops->complete_rq(rq, hdr); + blk_execute_rq(q, NULL, rq, !(hdr.flags & BSG_FLAG_Q_AT_TAIL)); + ret = rq->q->bsg_dev.ops->complete_rq(rq, &hdr); if (rq->next_rq) { blk_rq_unmap_user(bidi_bio); @@ -233,6 +223,20 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, blk_rq_unmap_user(bio); rq->q->bsg_dev.ops->free_rq(rq); blk_put_request(rq); + + if (copy_to_user(uarg, &hdr, sizeof(hdr))) + return -EFAULT; + return ret; + +out_unmap_nextrq: + if (rq->next_rq) + blk_rq_unmap_user(rq->next_rq->bio); +out_free_nextrq: + if (rq->next_rq) + blk_put_request(rq->next_rq); +out: + q->bsg_dev.ops->free_rq(rq); + blk_put_request(rq); return ret; } @@ -367,31 +371,39 @@ static int bsg_release(struct inode *inode, struct file *file) return bsg_put_device(bd); } +static int bsg_get_command_q(struct bsg_device *bd, int __user *uarg) +{ + return put_user(bd->max_queue, uarg); +} + +static int bsg_set_command_q(struct bsg_device *bd, int __user *uarg) +{ + int queue; + + if (get_user(queue, uarg)) + return -EFAULT; + if (queue < 1) + return -EINVAL; + + spin_lock_irq(&bd->lock); + bd->max_queue = queue; + spin_unlock_irq(&bd->lock); + return 0; +} + static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct bsg_device *bd = file->private_data; - int __user *uarg = (int __user *) arg; - int ret; + void __user *uarg = (void __user *) arg; switch (cmd) { - /* - * our own ioctls - */ + /* + * Our own ioctls + */ case SG_GET_COMMAND_Q: - return put_user(bd->max_queue, uarg); - case SG_SET_COMMAND_Q: { - int queue; - - if (get_user(queue, uarg)) - return -EFAULT; - if (queue < 1) - return -EINVAL; - - spin_lock_irq(&bd->lock); - bd->max_queue = queue; - spin_unlock_irq(&bd->lock); - return 0; - } + return bsg_get_command_q(bd, uarg); + case SG_SET_COMMAND_Q: + return bsg_set_command_q(bd, uarg); /* * SCSI/sg ioctls @@ -404,36 +416,10 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case SG_GET_RESERVED_SIZE: case SG_SET_RESERVED_SIZE: case SG_EMULATED_HOST: - case SCSI_IOCTL_SEND_COMMAND: { - void __user *uarg = (void __user *) arg; + case SCSI_IOCTL_SEND_COMMAND: return scsi_cmd_ioctl(bd->queue, NULL, file->f_mode, cmd, uarg); - } - case SG_IO: { - struct request *rq; - struct bio *bio, *bidi_bio = NULL; - struct sg_io_v4 hdr; - int at_head; - - if (copy_from_user(&hdr, uarg, sizeof(hdr))) - return -EFAULT; - - rq = bsg_map_hdr(bd->queue, &hdr, file->f_mode); - if (IS_ERR(rq)) - return PTR_ERR(rq); - - bio = rq->bio; - if (rq->next_rq) - bidi_bio = rq->next_rq->bio; - - at_head = (0 == (hdr.flags & BSG_FLAG_Q_AT_TAIL)); - blk_execute_rq(bd->queue, NULL, rq, at_head); - ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio); - - if (copy_to_user(uarg, &hdr, sizeof(hdr))) - return -EFAULT; - - return ret; - } + case SG_IO: + return bsg_sg_io(bd->queue, file->f_mode, uarg); default: return -ENOTTY; } -- 2.20.1