From patchwork Thu Jan 2 14:55:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 11315883 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 396C314BD for ; Thu, 2 Jan 2020 14:58:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0DBF920848 for ; Thu, 2 Jan 2020 14:58:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728607AbgABO6D (ORCPT ); Thu, 2 Jan 2020 09:58:03 -0500 Received: from mout.kundenserver.de ([212.227.126.133]:57085 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728544AbgABO6C (ORCPT ); Thu, 2 Jan 2020 09:58:02 -0500 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue011 [212.227.15.129]) with ESMTPA (Nemesis) id 1MLzSD-1j4yPT0dAv-00Hze6; Thu, 02 Jan 2020 15:57:46 +0100 From: Arnd Bergmann To: "James E.J. Bottomley" , "Martin K. Petersen" Cc: Arnd Bergmann , Al Viro , Douglas Gilbert , Steffen Maier , linux-scsi@vger.kernel.org, Jens Axboe , Chaitanya Kulkarni , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 03/22] compat: scsi: sg: fix v3 compat read/write interface Date: Thu, 2 Jan 2020 15:55:21 +0100 Message-Id: <20200102145552.1853992-4-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20200102145552.1853992-1-arnd@arndb.de> References: <20200102145552.1853992-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:nRc504jMOm3JteF2RHJQED6rMExyEXomIbEfWluQRtfGedaueYQ HSnicqYeOwDMEjGgqcf4j08q/sMz5sHGGLthM74HFeHngEPEkorJ45QatkmReK5HEnYGg0Q oLtQoQ+Cf1LpV37J0Pz07NhxUCOLR9IJXxJ2yqt8zUvjH6ItrQ9pvGsmV0x6jLpTq1PxO9/ ufsyhI+t4Svq5bNIPe5gg== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:BnXOhNwbfkU=:G4tQDXF/WQu5mAC+Qjokpr UzEnwTBWXbsWHaLla/qdLs2mW5qNgZFwTiUDd5DGbBe2SricT8IdiLgWGayPiowyVZtcGJO/P B6taIxfgDh2HALD87S/IQmx4wUXwYB1G2D74gIpPEfxtmCHHZ729sfiWkGsJ0hF+VTpRZwLz3 brfDXU+c7fPpl5WV8D/9dt1WEGMraFDU1geUYc+AtvT4hrluVjuHlrkKNgZzbOc+0+p0WNL+z K0l2aGuYpsEjy13CBPGhTjb3csc88TfTvTBoUANZ4/fXBArGyxir/jD59hg2kjLX6t7hLuaw8 qZi5DT3kG1FVW4VsbQa1noXXXr4pgEd/iVqU4lFSOeqfLhbZOnjkj4+7q/toElEx5/QoG6woP AZ9Fe8xbsqoeew7RyIMyhyHVXujjooBHbqe+MzgR6kKtVt0GIyk7V8LSliYgOhlWBhzEsNI9Y FdMd/eMbUjQCyCISrCrtTZqD2lX1Bh5LDLrosiISU0xar6BJe1iQgjUnhKidcO2sqw3KOxd0b h3dXVxLFB3qm4UZ0nZRaVCQAA6rrJw76q9BMg5EeccPRRWz9zB0B/6y8V7izQJdVqmRdTnE13 aLa4tQxm3nxcjMcHlJ90A8hQBoW5YQnbBN/z23+CSluU7B9fm0RusOc4zrQvUeUmAhIhgq6Ea fLiKLXSx9zXlxZfL8xm4lkePrfln4NDwecxDAka5J9x5vgPcH7qnFZ0hSnJTz9dwmOzz3zjRa nQ42O1hnRr37jL6KnlRFoiyyYbFOQxVShu7NJ7XGnDqCaoBek9uOp3bXYRMFsjmp0216Q4A2R vHWzGQAk4Oh06U6wzVfXf+fcOV4Yy7UZkWEIUUHWrSozyHsatqTsxDaIsvOkDKre1ioI3FqbN ZTQ6UcJF3QsKHHwZgbRQ== Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org In the v5.4 merge window, a cleanup patch from Al Viro conflicted with my rework of the compat handling for sg.c read(). Linus Torvalds did a correct merge but pointed out that the resulting code is still unsatisfactory. I later noticed that the sg_new_read() function still gets the compat mode wrong, when the 'count' argument is large enough to pass a compat_sg_io_hdr object, but not a nativ sg_io_hdr. To address both of these, move the definition of compat_sg_io_hdr into a scsi/sg.h to make it visible to sg.c and rewrite the logic for reading req_pack_id as well as the size check to a simpler version that gets the expected results. Fixes: c35a5cfb4150 ("scsi: sg: sg_read(): simplify reading ->pack_id of userland sg_io_hdr_t") Fixes: 98aaaec4a150 ("compat_ioctl: reimplement SG_IO handling") Signed-off-by: Arnd Bergmann --- block/scsi_ioctl.c | 29 +---------- drivers/scsi/sg.c | 126 +++++++++++++++++++++------------------------ include/scsi/sg.h | 30 +++++++++++ 3 files changed, 90 insertions(+), 95 deletions(-) diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 650bade5ea5a..b61dbf4d8443 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -20,6 +20,7 @@ #include #include #include +#include struct blk_cmd_filter { unsigned long read_ok[BLK_SCSI_CMD_PER_LONG]; @@ -550,34 +551,6 @@ static inline int blk_send_start_stop(struct request_queue *q, return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data); } -#ifdef CONFIG_COMPAT -struct compat_sg_io_hdr { - compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */ - compat_int_t dxfer_direction; /* [i] data transfer direction */ - unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ - unsigned char mx_sb_len; /* [i] max length to write to sbp */ - unsigned short iovec_count; /* [i] 0 implies no scatter gather */ - compat_uint_t dxfer_len; /* [i] byte count of data transfer */ - compat_uint_t dxferp; /* [i], [*io] points to data transfer memory - or scatter gather list */ - compat_uptr_t cmdp; /* [i], [*i] points to command to perform */ - compat_uptr_t sbp; /* [i], [*o] points to sense_buffer memory */ - compat_uint_t timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */ - compat_uint_t flags; /* [i] 0 -> default, see SG_FLAG... */ - compat_int_t pack_id; /* [i->o] unused internally (normally) */ - compat_uptr_t usr_ptr; /* [i->o] unused internally */ - unsigned char status; /* [o] scsi status */ - unsigned char masked_status; /* [o] shifted, masked scsi status */ - unsigned char msg_status; /* [o] messaging level data (optional) */ - unsigned char sb_len_wr; /* [o] byte count actually written to sbp */ - unsigned short host_status; /* [o] errors from host adapter */ - unsigned short driver_status; /* [o] errors from software driver */ - compat_int_t resid; /* [o] dxfer_len - actual_transferred */ - compat_uint_t duration; /* [o] time taken by cmd (unit: millisec) */ - compat_uint_t info; /* [o] auxiliary information */ -}; -#endif - int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp) { #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 160748ad9c0f..eace8886d95a 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -405,6 +405,38 @@ sg_release(struct inode *inode, struct file *filp) return 0; } +static int get_sg_io_pack_id(int *pack_id, void __user *buf, size_t count) +{ + struct sg_header __user *old_hdr = buf; + int reply_len; + + if (count >= SZ_SG_HEADER) { + /* negative reply_len means v3 format, otherwise v1/v2 */ + if (get_user(reply_len, &old_hdr->reply_len)) + return -EFAULT; + + if (reply_len >= 0) + return get_user(*pack_id, &old_hdr->pack_id); + + if (in_compat_syscall() && + count >= sizeof(struct compat_sg_io_hdr)) { + struct compat_sg_io_hdr __user *hp = buf; + + return get_user(*pack_id, &hp->pack_id); + } + + if (count >= sizeof(struct sg_io_hdr)) { + struct sg_io_hdr __user *hp = buf; + + return get_user(*pack_id, &hp->pack_id); + } + } + + /* no valid header was passed, so ignore the pack_id */ + *pack_id = -1; + return 0; +} + static ssize_t sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) { @@ -413,8 +445,8 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) Sg_request *srp; int req_pack_id = -1; sg_io_hdr_t *hp; - struct sg_header *old_hdr = NULL; - int retval = 0; + struct sg_header *old_hdr; + int retval; /* * This could cause a response to be stranded. Close the associated @@ -429,79 +461,34 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp, "sg_read: count=%d\n", (int) count)); - if (sfp->force_packid && (count >= SZ_SG_HEADER)) { - old_hdr = memdup_user(buf, SZ_SG_HEADER); - if (IS_ERR(old_hdr)) - return PTR_ERR(old_hdr); - if (old_hdr->reply_len < 0) { - if (count >= SZ_SG_IO_HDR) { - /* - * This is stupid. - * - * We're copying the whole sg_io_hdr_t from user - * space just to get the 'pack_id' field. But the - * field is at different offsets for the compat - * case, so we'll use "get_sg_io_hdr()" to copy - * the whole thing and convert it. - * - * We could do something like just calculating the - * offset based of 'in_compat_syscall()', but the - * 'compat_sg_io_hdr' definition is in the wrong - * place for that. - */ - sg_io_hdr_t *new_hdr; - new_hdr = kmalloc(SZ_SG_IO_HDR, GFP_KERNEL); - if (!new_hdr) { - retval = -ENOMEM; - goto free_old_hdr; - } - retval = get_sg_io_hdr(new_hdr, buf); - req_pack_id = new_hdr->pack_id; - kfree(new_hdr); - if (retval) { - retval = -EFAULT; - goto free_old_hdr; - } - } - } else - req_pack_id = old_hdr->pack_id; - } + if (sfp->force_packid) + retval = get_sg_io_pack_id(&req_pack_id, buf, count); + if (retval) + return retval; + srp = sg_get_rq_mark(sfp, req_pack_id); if (!srp) { /* now wait on packet to arrive */ - if (atomic_read(&sdp->detaching)) { - retval = -ENODEV; - goto free_old_hdr; - } - if (filp->f_flags & O_NONBLOCK) { - retval = -EAGAIN; - goto free_old_hdr; - } + if (atomic_read(&sdp->detaching)) + return -ENODEV; + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; retval = wait_event_interruptible(sfp->read_wait, (atomic_read(&sdp->detaching) || (srp = sg_get_rq_mark(sfp, req_pack_id)))); - if (atomic_read(&sdp->detaching)) { - retval = -ENODEV; - goto free_old_hdr; - } - if (retval) { + if (atomic_read(&sdp->detaching)) + return -ENODEV; + if (retval) /* -ERESTARTSYS as signal hit process */ - goto free_old_hdr; - } - } - if (srp->header.interface_id != '\0') { - retval = sg_new_read(sfp, buf, count, srp); - goto free_old_hdr; + return retval; } + if (srp->header.interface_id != '\0') + return sg_new_read(sfp, buf, count, srp); hp = &srp->header; - if (old_hdr == NULL) { - old_hdr = kmalloc(SZ_SG_HEADER, GFP_KERNEL); - if (! old_hdr) { - retval = -ENOMEM; - goto free_old_hdr; - } - } - memset(old_hdr, 0, SZ_SG_HEADER); + old_hdr = kzalloc(SZ_SG_HEADER, GFP_KERNEL); + if (!old_hdr) + return -ENOMEM; + old_hdr->reply_len = (int) hp->timeout; old_hdr->pack_len = old_hdr->reply_len; /* old, strange behaviour */ old_hdr->pack_id = hp->pack_id; @@ -575,7 +562,12 @@ sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp) int err = 0, err2; int len; - if (count < SZ_SG_IO_HDR) { + if (in_compat_syscall()) { + if (count < sizeof(struct compat_sg_io_hdr)) { + err = -EINVAL; + goto err_out; + } + } else if (count < SZ_SG_IO_HDR) { err = -EINVAL; goto err_out; } diff --git a/include/scsi/sg.h b/include/scsi/sg.h index f91bcca604e4..29c7ad04d2e2 100644 --- a/include/scsi/sg.h +++ b/include/scsi/sg.h @@ -68,6 +68,36 @@ typedef struct sg_io_hdr unsigned int info; /* [o] auxiliary information */ } sg_io_hdr_t; /* 64 bytes long (on i386) */ +#if defined(__KERNEL__) +#include + +struct compat_sg_io_hdr { + compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */ + compat_int_t dxfer_direction; /* [i] data transfer direction */ + unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ + unsigned char mx_sb_len; /* [i] max length to write to sbp */ + unsigned short iovec_count; /* [i] 0 implies no scatter gather */ + compat_uint_t dxfer_len; /* [i] byte count of data transfer */ + compat_uint_t dxferp; /* [i], [*io] points to data transfer memory + or scatter gather list */ + compat_uptr_t cmdp; /* [i], [*i] points to command to perform */ + compat_uptr_t sbp; /* [i], [*o] points to sense_buffer memory */ + compat_uint_t timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */ + compat_uint_t flags; /* [i] 0 -> default, see SG_FLAG... */ + compat_int_t pack_id; /* [i->o] unused internally (normally) */ + compat_uptr_t usr_ptr; /* [i->o] unused internally */ + unsigned char status; /* [o] scsi status */ + unsigned char masked_status; /* [o] shifted, masked scsi status */ + unsigned char msg_status; /* [o] messaging level data (optional) */ + unsigned char sb_len_wr; /* [o] byte count actually written to sbp */ + unsigned short host_status; /* [o] errors from host adapter */ + unsigned short driver_status; /* [o] errors from software driver */ + compat_int_t resid; /* [o] dxfer_len - actual_transferred */ + compat_uint_t duration; /* [o] time taken by cmd (unit: millisec) */ + compat_uint_t info; /* [o] auxiliary information */ +}; +#endif + #define SG_INTERFACE_ID_ORIG 'S' /* Use negative values to flag difference from original sg_header structure */ From patchwork Thu Jan 2 14:55:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 11315905 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 69866138C for ; Thu, 2 Jan 2020 15:01:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 510FE20848 for ; Thu, 2 Jan 2020 15:01:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728608AbgABPBA (ORCPT ); Thu, 2 Jan 2020 10:01:00 -0500 Received: from mout.kundenserver.de ([212.227.126.133]:37957 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728571AbgABPBA (ORCPT ); Thu, 2 Jan 2020 10:01:00 -0500 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue011 [212.227.15.129]) with ESMTPA (Nemesis) id 1MrhDg-1jYVqE2Tga-00ndiR; Thu, 02 Jan 2020 16:00:06 +0100 From: Arnd Bergmann To: "James E.J. Bottomley" , "Martin K. Petersen" Cc: Arnd Bergmann , Hannes Reinecke , linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 10/22] compat_ioctl: add scsi_compat_ioctl Date: Thu, 2 Jan 2020 15:55:28 +0100 Message-Id: <20200102145552.1853992-11-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20200102145552.1853992-1-arnd@arndb.de> References: <20200102145552.1853992-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:wWyOxkPxks6ZLGDfVWfB8jnnZ3eQfd6m6seDw5PYn1G0Q10JVRK 4AMdasffkBmhIydWEoH7T9ScuaYHbmIYzx+4jUOHHbNvU0cNDRrnxCczvfO3dh3CYAaFlpf jwSe4DfQdi8xyS9uL6lg+3WOkvoA5jYpK0um+F5NMWagaJ2WEXZCg6VHdqepgTb/JwoNpVz uoLzfpEW7Jnc5jcgB+T9g== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:JasbQQ2pZHY=:C73jn5i5YVNLi2pVZJvlfn mJ55iUBUXDj6d45Xdi7PSUMvxbjyfoK2fjonVZ8uguYHWiZ8mDeKTOCtzQb+HQ4QMNjMFXKJE ziQHt3euqxU29a/3q0LitLy9Xw+yXySToZ/07WYR+jEC2teqYlc4SC7Wz0/jBfZCltDUAWAxO HG7OA1tvZDRXPaLNoiMLneiPOsGpJl9kSQIe4F4ww57owUJdVBoWJVDvAg74nPwF6WBL1RhoL BLAUPZ5v9yxADTkniNf9oL3NcPEqopVYLvV1gAd9PUEE/WXhPGPDClLJ/ISeNxc5UFyxwLlE4 jJBq/Wz6Sk0OjairsgMwVGkePt3HuaPO+QXbtkTAzYTfWvg8oZck7j1FyHq2rp2qqVxKepeGK 16R550NWjA5MsW8kNregylyT5OhymP2aMJHiIlH87SXkRVmB1rmSHD0AcdPCZiCLL7DvxnVQz sj3UIP1976nDtaq4EsYIy8o7zN3oKyB2/SUMSRRLw0RuYZeBxWkdVW1CpvniLybGmvpKYbO7T O1OKsCIxrAg1/LXl8HFTTII4dBKJUyA6VLJsa/pF79eQm88PfIzUfPoSXTsO8UTgl4JdLZir2 N88EjMm/iuHcjAIs9Sdo+wJW8lXwcGsjz9umB8dW4ZB+dXPUCULt7X9ecnCXIxM9QijyFsklx VzzAYDV1e449PTQFTWVxWZOBHvtpiO1keC47HZJucn+Ec3vzLPLgMMS3N99NmKsNeV2iKQ6w7 EacpwBCCiboM8Sy7b0IVCW3gLrr1lv12xD0zkUxfE27z4luCSOJqN0lN12X6iabUGs6jTD/2R w18vc/UUpTfk3AES8Lf1FJzzbPkkxqpNPvZM8pN8cYWryKi4+jbEdamlKtwsmggOZHKiWdRWW YkGNaEthjv6Z041GvVRQ== Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org In order to move the compat handling for SCSI ioctl commands out of fs/compat_ioctl.c into the individual drivers, we need a helper function first to match the native ioctl handler called by sd, sr, st, etc. Signed-off-by: Arnd Bergmann --- drivers/scsi/scsi_ioctl.c | 54 +++++++++++++++++++++++++++++---------- include/scsi/scsi_ioctl.h | 1 + 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 57bcd05605bf..8f3af87b6bb0 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -189,17 +189,7 @@ static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg) } -/** - * scsi_ioctl - Dispatch ioctl to scsi device - * @sdev: scsi device receiving ioctl - * @cmd: which ioctl is it - * @arg: data associated with ioctl - * - * Description: The scsi_ioctl() function differs from most ioctls in that it - * does not take a major/minor number as the dev field. Rather, it takes - * a pointer to a &struct scsi_device. - */ -int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) +static int scsi_ioctl_common(struct scsi_device *sdev, int cmd, void __user *arg) { char scsi_cmd[MAX_COMMAND_SIZE]; struct scsi_sense_hdr sense_hdr; @@ -266,14 +256,50 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) return scsi_ioctl_get_pci(sdev, arg); case SG_SCSI_RESET: return scsi_ioctl_reset(sdev, arg); - default: - if (sdev->host->hostt->ioctl) - return sdev->host->hostt->ioctl(sdev, cmd, arg); } + return -ENOIOCTLCMD; +} + +/** + * scsi_ioctl - Dispatch ioctl to scsi device + * @sdev: scsi device receiving ioctl + * @cmd: which ioctl is it + * @arg: data associated with ioctl + * + * Description: The scsi_ioctl() function differs from most ioctls in that it + * does not take a major/minor number as the dev field. Rather, it takes + * a pointer to a &struct scsi_device. + */ +int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) +{ + int ret = scsi_ioctl_common(sdev, cmd, arg); + + if (ret != -ENOIOCTLCMD) + return ret; + + if (sdev->host->hostt->ioctl) + return sdev->host->hostt->ioctl(sdev, cmd, arg); + return -EINVAL; } EXPORT_SYMBOL(scsi_ioctl); +#ifdef CONFIG_COMPAT +int scsi_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) +{ + int ret = scsi_ioctl_common(sdev, cmd, arg); + + if (ret != -ENOIOCTLCMD) + return ret; + + if (sdev->host->hostt->compat_ioctl) + return sdev->host->hostt->compat_ioctl(sdev, cmd, arg); + + return ret; +} +EXPORT_SYMBOL(scsi_compat_ioctl); +#endif + /* * We can process a reset even when a device isn't fully operable. */ diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h index 5101e987c0ef..4fe69d863b5d 100644 --- a/include/scsi/scsi_ioctl.h +++ b/include/scsi/scsi_ioctl.h @@ -44,6 +44,7 @@ typedef struct scsi_fctargaddress { int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, int cmd, bool ndelay); extern int scsi_ioctl(struct scsi_device *, int, void __user *); +extern int scsi_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg); #endif /* __KERNEL__ */ #endif /* _SCSI_IOCTL_H */ From patchwork Thu Jan 2 14:55:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 11315903 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 448E114B4 for ; Thu, 2 Jan 2020 15:00:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2B1A420848 for ; Thu, 2 Jan 2020 15:00:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728641AbgABPAh (ORCPT ); Thu, 2 Jan 2020 10:00:37 -0500 Received: from mout.kundenserver.de ([212.227.126.131]:60753 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728571AbgABPAh (ORCPT ); Thu, 2 Jan 2020 10:00:37 -0500 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue011 [212.227.15.129]) with ESMTPA (Nemesis) id 1MF3Y8-1iy5eq3Xmi-00FPMR; Thu, 02 Jan 2020 16:00:16 +0100 From: Arnd Bergmann To: "James E.J. Bottomley" , "Martin K. Petersen" Cc: Arnd Bergmann , FUJITA Tomonori , Jens Axboe , Chaitanya Kulkarni , Benjamin Block , linux-scsi@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 11/22] compat_ioctl: bsg: add handler Date: Thu, 2 Jan 2020 15:55:29 +0100 Message-Id: <20200102145552.1853992-12-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20200102145552.1853992-1-arnd@arndb.de> References: <20200102145552.1853992-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:/v9BoeMw07nWpYw7u0vnyk6+iF7B9Ivx59/dmMOCA43quUma0Cb LvLgvdr6nk111g9XSXmi72uMA3v10UdDlFT1nwsCVEGt5vo6q0GP3uEay7CQEp+2Bjxbbej b5IDipv+F8eqFr46BmUUI2g8OckLtnPOxuymbLTcB38VCY3+aEVgccCWvTzb1jacfZOgcrF Bu9ksi0IpGAWcsPQAVeWA== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:iJ1ciBf4Kro=:ulm3L4FFhXfpjGZ9FP2kXX GRP7BlD+CAPrLeiwd3yqbkPYqdhqc0xp7s0sA3FbN/gmBxw+t+lTsy/SJYTXKsrrhpByqoheF XNkLZkrdKF6VahgIPO4Wlv0JyZd4JbZnebYEPEyTVylSSP44jdggR60kll84/R92BiVUaGhfP 7H3f+mUkQeJZCo2uisJ9yL3khr7rM0mTRCPX0KzL3okPkjic6cWKN+EVU1EBs9c/fFYlHlBJZ R1Ol1e6FWQ2Ka/WINrAq3xpWSapauRQhPdFu3rcc98lfbXV2KYo5W+dn3OW0c38QMnu4gLPnz WxIRqTa2QgZgW2p4PMCdxQSKKLKIXvixbeHzbz/TZ8fjZqMgZXVVqE3J7PbYyf1wNdDLdlfFl IOee34z5uqxwApJ39i9waQVotAfHaZvgSDZxqjqzfyADFiW+c45Yz76ZD/SnQsWSuI8owcjLJ Ihq3f4J5ezbpzkzR1SFk/3DDNLbZlfQLpWWbMaHkh+bIvcn331kmD3GRjQtNXf/mrMXQEgb1S GMHSGRGFBW2hwQbOU+icy4JZSEIcIgdLCNXax3Nv0oFO0mgSq5BkfRLE1V6tkKiI/2CN4zU+M 7OIwKWiL9L2dcDDGRoH1dxkGjADNbVzSiuvPF4kyrVPWzO1zRzTmcVNoi5kK9BTKHOBJmnZKW AjZhcEvjyWQhAheRoL/Njj3+miFC/SDyoPIUMJX7bBKkUPxmdAQ8G6z12cfJsnXTU46ZTYeQz i5n6UaK6gDbVwv2vV7h+A/sWUzVobF/7R9vBjZcrlv9ztJQNApCXQTJNXR0FU1jZDluas4CtG f8PUD3qzSi6YAo/UhTqUVLk2r0jUy/SuDyt7eGYrQFXd+2n3PAW01OzGuVpmqkysmw3U5Pt1R /AZ4VVxCvjfMJEIpNo4g== Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org bsg_ioctl() calls into scsi_cmd_ioctl() for a couple of generic commands and relies on fs/compat_ioctl.c to handle it correctly in compat mode. Adding a private compat_ioctl() handler avoids that round-trip and lets us get rid of the generic emulation once this is done. Note that bsg implements an SG_IO command that is different from the other drivers and does not need emulation. Signed-off-by: Arnd Bergmann --- block/bsg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/bsg.c b/block/bsg.c index 833c44b3d458..d7bae94b64d9 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -382,6 +382,7 @@ static const struct file_operations bsg_fops = { .open = bsg_open, .release = bsg_release, .unlocked_ioctl = bsg_ioctl, + .compat_ioctl = compat_ptr_ioctl, .owner = THIS_MODULE, .llseek = default_llseek, }; From patchwork Thu Jan 2 14:55:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 11315923 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2BFB217EA for ; Thu, 2 Jan 2020 15:04:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0A0332072C for ; Thu, 2 Jan 2020 15:04:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728643AbgABPEM (ORCPT ); Thu, 2 Jan 2020 10:04:12 -0500 Received: from mout.kundenserver.de ([212.227.126.130]:47589 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728571AbgABPEL (ORCPT ); Thu, 2 Jan 2020 10:04:11 -0500 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue011 [212.227.15.129]) with ESMTPA (Nemesis) id 1MnJUy-1jU5yG242e-00jFzj; Thu, 02 Jan 2020 16:01:28 +0100 From: Arnd Bergmann To: "James E.J. Bottomley" , "Martin K. Petersen" Cc: Arnd Bergmann , "Michael S. Tsirkin" , Jason Wang , Paolo Bonzini , Stefan Hajnoczi , Jens Axboe , Doug Gilbert , =?utf-8?q?Kai_M=C3=A4kisara?= , Alexander Viro , Dongli Zhang , Thomas Gleixner , Bart Van Assche , Hannes Reinecke , Damien Le Moal , John Garry , Martin Wilck , Heiko Carstens , "Gustavo A. R. Silva" , Ira Weiny , Iustin Pop , "Darrick J. Wong" , virtualization@lists.linux-foundation.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v3 13/22] compat_ioctl: scsi: move ioctl handling into drivers Date: Thu, 2 Jan 2020 15:55:31 +0100 Message-Id: <20200102145552.1853992-14-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20200102145552.1853992-1-arnd@arndb.de> References: <20200102145552.1853992-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:/e80zwdT+wTicn0NMZuh6AZ7aAB/UfmFnLijkeDZsj8gxRxFW5k N//+5PnYmCiu9NnLxiRRE0mJZsNb5V80V0Ex9rjoeqi05jIqFZUh7ziOTX1gQPinUT7BRpl jeZoob0rgUjez9ZHLn85pzbYf/4sEvUOCPWPa7vZZizKKCEb9w9+sVRqZzLRRJXjzvWZ0R9 cMqCviOyZOxSKDQ9baMYQ== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:x/Q6tmSDxu8=:OjjUVNa82AbH3RiNJYC9Xv mVO9b74kQFTgrYlXKNbSlG6Vs6Vo86LTUPlv7WUijUK9dAJWI30NUAICkIZeWWQDt4J8/G9/I rBiyU5BTmVPe9ZTaxtUKgYpGXr1BnqCVSpj7sb85DTv5pERnqhIthEtb8SjBT2U5W7k61RrOa ldAV9tfo8NkGWJnxXUe0hGwQJJwcjW/eRNwO6rXGiTGuu6RfJsdfw+p1HkjxjQjNJe+mhRrrA qQpNP4iMPELMR3BoMoZVSWDJrD4ltCbNQOHfR85DpIvWIsQW7EwwCeC/xk6fm4uXj8DX4q9U7 FMf0y/fMe7VWuVdULYRQ7qIHqiAqHxvSm0RvN/tziqyJLnu80Z/qK6/DIRDh7TwdeB3n2zpkN hQN4Tq8t/HP6CAmpo5DuqHZu+hADe0ktznB3OK/tc5TJwtET7m1UGsCiUqX3PKAj3wLv569uh o6XQjGR4upeSYjmR5idXvJ/L6/cShVxi7MsCE8AHbRiECso0UO6vgwgupC2uIajcZShqUQxQT oaTXT8hBNfNxUoqB9EgBgsFkcIcPR80Lqx73PsG/EkkDaJpyKx/6nQi6Ba5QToJIuOKfREgA8 aYWUSUEVWXR2d3EB8Soc1y8AQycGifnC+HDL3KfEHC8hq5rHSxtesh5QFjpA4GOREGY/GT/Sq nZk66EO/rPHdkPHpitzqWFE00YZE8ft9h8rGiDBM7xp+mP5g8sRWY9WUOexnpzUeEYJPx9LA5 GkFt3CagmES56AkxBD2bG69vytWcWvhj4XvwxUZ3siOohsKkXrTe5/Lf0EZjjbTDyDZytu5nr VdBBmsD+8jFaNJDY97oPQgDUR3ixrIB8ow5brQo2wbKZMST9Y76+MXU5pnKiAheYhoWYc809T ujWAXClkzLx9abc/N5Yg== Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Each driver calling scsi_ioctl() gets an equivalent compat_ioctl() handler that implements the same commands by calling scsi_compat_ioctl(). The scsi_cmd_ioctl() and scsi_cmd_blk_ioctl() functions are compatible at this point, so any driver that calls those can do so for both native and compat mode, with the argument passed through compat_ptr(). With this, we can remove the entries from fs/compat_ioctl.c. The new code is larger, but should be easier to maintain and keep updated with newly added commands. Signed-off-by: Arnd Bergmann Acked-by: Stefan Hajnoczi --- drivers/block/virtio_blk.c | 3 + drivers/scsi/ch.c | 9 ++- drivers/scsi/sd.c | 50 ++++++-------- drivers/scsi/sg.c | 44 ++++++++----- drivers/scsi/sr.c | 57 ++++++++++++++-- drivers/scsi/st.c | 51 ++++++++------ fs/compat_ioctl.c | 132 +------------------------------------ 7 files changed, 142 insertions(+), 204 deletions(-) diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 7ffd719d89de..fbbf18ac1d5d 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -405,6 +405,9 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) static const struct block_device_operations virtblk_fops = { .ioctl = virtblk_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = blkdev_compat_ptr_ioctl, +#endif .owner = THIS_MODULE, .getgeo = virtblk_getgeo, }; diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 76751d6c7f0d..ed5f4a6ae270 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -872,6 +872,10 @@ static long ch_ioctl_compat(struct file * file, unsigned int cmd, unsigned long arg) { scsi_changer *ch = file->private_data; + int retval = scsi_ioctl_block_when_processing_errors(ch->device, cmd, + file->f_flags & O_NDELAY); + if (retval) + return retval; switch (cmd) { case CHIOGPARAMS: @@ -883,7 +887,7 @@ static long ch_ioctl_compat(struct file * file, case CHIOINITELEM: case CHIOSVOLTAG: /* compatible */ - return ch_ioctl(file, cmd, arg); + return ch_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); case CHIOGSTATUS32: { struct changer_element_status32 ces32; @@ -898,8 +902,7 @@ static long ch_ioctl_compat(struct file * file, return ch_gstatus(ch, ces32.ces_type, data); } default: - // return scsi_ioctl_compat(ch->device, cmd, (void*)arg); - return -ENOIOCTLCMD; + return scsi_compat_ioctl(ch->device, cmd, compat_ptr(arg)); } } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index cea625906440..5afb0046b12a 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1465,13 +1465,12 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo) * Note: most ioctls are forward onto the block subsystem or further * down in the scsi subsystem. **/ -static int sd_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long arg) +static int sd_ioctl_common(struct block_device *bdev, fmode_t mode, + unsigned int cmd, void __user *p) { struct gendisk *disk = bdev->bd_disk; struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_device *sdp = sdkp->device; - void __user *p = (void __user *)arg; int error; SCSI_LOG_IOCTL(1, sd_printk(KERN_INFO, sdkp, "sd_ioctl: disk=%s, " @@ -1507,9 +1506,6 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, break; default: error = scsi_cmd_blk_ioctl(bdev, mode, cmd, p); - if (error != -ENOTTY) - break; - error = scsi_ioctl(sdp, cmd, p); break; } out: @@ -1691,39 +1687,31 @@ static void sd_rescan(struct device *dev) revalidate_disk(sdkp->disk); } +static int sd_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) +{ + void __user *p = (void __user *)arg; + int ret; + + ret = sd_ioctl_common(bdev, mode, cmd, p); + if (ret != -ENOTTY) + return ret; + + return scsi_ioctl(scsi_disk(bdev->bd_disk)->device, cmd, p); +} #ifdef CONFIG_COMPAT -/* - * This gets directly called from VFS. When the ioctl - * is not recognized we go back to the other translation paths. - */ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct gendisk *disk = bdev->bd_disk; - struct scsi_disk *sdkp = scsi_disk(disk); - struct scsi_device *sdev = sdkp->device; void __user *p = compat_ptr(arg); - int error; - - error = scsi_verify_blk_ioctl(bdev, cmd); - if (error < 0) - return error; + int ret; - error = scsi_ioctl_block_when_processing_errors(sdev, cmd, - (mode & FMODE_NDELAY) != 0); - if (error) - return error; + ret = sd_ioctl_common(bdev, mode, cmd, p); + if (ret != -ENOTTY) + return ret; - if (is_sed_ioctl(cmd)) - return sed_ioctl(sdkp->opal_dev, cmd, p); - - /* - * Let the static ioctl translation table take care of it. - */ - if (!sdev->host->hostt->compat_ioctl) - return -ENOIOCTLCMD; - return sdev->host->hostt->compat_ioctl(sdev, cmd, p); + return scsi_compat_ioctl(scsi_disk(bdev->bd_disk)->device, cmd, p); } #endif diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index eace8886d95a..bafeaf7b9ad8 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -911,19 +911,14 @@ static int put_compat_request_table(struct compat_sg_req_info __user *o, #endif static long -sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) +sg_ioctl_common(struct file *filp, Sg_device *sdp, Sg_fd *sfp, + unsigned int cmd_in, void __user *p) { - void __user *p = (void __user *)arg; int __user *ip = p; int result, val, read_only; - Sg_device *sdp; - Sg_fd *sfp; Sg_request *srp; unsigned long iflags; - if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) - return -ENXIO; - SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp, "sg_ioctl: cmd=0x%x\n", (int) cmd_in)); read_only = (O_RDWR != (filp->f_flags & O_ACCMODE)); @@ -1146,29 +1141,44 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) cmd_in, filp->f_flags & O_NDELAY); if (result) return result; + + return -ENOIOCTLCMD; +} + +static long +sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) +{ + void __user *p = (void __user *)arg; + Sg_device *sdp; + Sg_fd *sfp; + int ret; + + if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) + return -ENXIO; + + ret = sg_ioctl_common(filp, sdp, sfp, cmd_in, p); + if (ret != -ENOIOCTLCMD) + return ret; + return scsi_ioctl(sdp->device, cmd_in, p); } #ifdef CONFIG_COMPAT static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) { + void __user *p = compat_ptr(arg); Sg_device *sdp; Sg_fd *sfp; - struct scsi_device *sdev; + int ret; if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) return -ENXIO; - sdev = sdp->device; - if (sdev->host->hostt->compat_ioctl) { - int ret; - - ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg); - + ret = sg_ioctl_common(filp, sdp, sfp, cmd_in, p); + if (ret != -ENOIOCTLCMD) return ret; - } - - return -ENOIOCTLCMD; + + return scsi_compat_ioctl(sdp->device, cmd_in, p); } #endif diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 4664fdf75c0f..6033a886c42c 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -598,6 +599,55 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, return ret; } +#ifdef CONFIG_COMPAT +static int sr_block_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, + unsigned long arg) +{ + struct scsi_cd *cd = scsi_cd(bdev->bd_disk); + struct scsi_device *sdev = cd->device; + void __user *argp = compat_ptr(arg); + int ret; + + mutex_lock(&sr_mutex); + + ret = scsi_ioctl_block_when_processing_errors(sdev, cmd, + (mode & FMODE_NDELAY) != 0); + if (ret) + goto out; + + scsi_autopm_get_device(sdev); + + /* + * Send SCSI addressing ioctls directly to mid level, send other + * ioctls to cdrom/block level. + */ + switch (cmd) { + case SCSI_IOCTL_GET_IDLUN: + case SCSI_IOCTL_GET_BUS_NUMBER: + ret = scsi_compat_ioctl(sdev, cmd, argp); + goto put; + } + + /* + * CDROM ioctls are handled in the block layer, but + * do the scsi blk ioctls here. + */ + ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp); + if (ret != -ENOTTY) + return ret; + + ret = scsi_compat_ioctl(sdev, cmd, argp); + +put: + scsi_autopm_put_device(sdev); + +out: + mutex_unlock(&sr_mutex); + return ret; + +} +#endif + static unsigned int sr_block_check_events(struct gendisk *disk, unsigned int clearing) { @@ -641,12 +691,11 @@ static const struct block_device_operations sr_bdops = .open = sr_block_open, .release = sr_block_release, .ioctl = sr_block_ioctl, +#ifdef CONFIG_COMPAT + .ioctl = sr_block_compat_ioctl, +#endif .check_events = sr_block_check_events, .revalidate_disk = sr_block_revalidate_disk, - /* - * No compat_ioctl for now because sr_block_ioctl never - * seems to pass arbitrary ioctls down to host drivers. - */ }; static int sr_open(struct cdrom_device_info *cdi, int purpose) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 9e3fff2de83e..393f3019ccac 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3501,7 +3501,7 @@ static int partition_tape(struct scsi_tape *STp, int size) /* The ioctl command */ -static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) +static long st_ioctl_common(struct file *file, unsigned int cmd_in, void __user *p) { int i, cmd_nr, cmd_type, bt; int retval = 0; @@ -3509,7 +3509,6 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) struct scsi_tape *STp = file->private_data; struct st_modedef *STm; struct st_partstat *STps; - void __user *p = (void __user *)arg; if (mutex_lock_interruptible(&STp->lock)) return -ERESTARTSYS; @@ -3824,9 +3823,19 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) } mutex_unlock(&STp->lock); switch (cmd_in) { + case SCSI_IOCTL_STOP_UNIT: + /* unload */ + retval = scsi_ioctl(STp->device, cmd_in, p); + if (!retval) { + STp->rew_at_close = 0; + STp->ready = ST_NO_TAPE; + } + return retval; + case SCSI_IOCTL_GET_IDLUN: case SCSI_IOCTL_GET_BUS_NUMBER: break; + default: if ((cmd_in == SG_IO || cmd_in == SCSI_IOCTL_SEND_COMMAND || @@ -3840,42 +3849,46 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) return i; break; } - retval = scsi_ioctl(STp->device, cmd_in, p); - if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */ - STp->rew_at_close = 0; - STp->ready = ST_NO_TAPE; - } - return retval; + return -ENOTTY; out: mutex_unlock(&STp->lock); return retval; } +static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) +{ + void __user *p = (void __user *)arg; + struct scsi_tape *STp = file->private_data; + int ret; + + ret = st_ioctl_common(file, cmd_in, p); + if (ret != -ENOTTY) + return ret; + + return scsi_ioctl(STp->device, cmd_in, p); +} + #ifdef CONFIG_COMPAT static long st_compat_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) { void __user *p = compat_ptr(arg); struct scsi_tape *STp = file->private_data; - struct scsi_device *sdev = STp->device; - int ret = -ENOIOCTLCMD; + int ret; /* argument conversion is handled using put_user_mtpos/put_user_mtget */ switch (cmd_in) { - case MTIOCTOP: - return st_ioctl(file, MTIOCTOP, (unsigned long)p); case MTIOCPOS32: - return st_ioctl(file, MTIOCPOS, (unsigned long)p); + return st_ioctl_common(file, MTIOCPOS, p); case MTIOCGET32: - return st_ioctl(file, MTIOCGET, (unsigned long)p); + return st_ioctl_common(file, MTIOCGET, p); } - if (sdev->host->hostt->compat_ioctl) { + ret = st_ioctl_common(file, cmd_in, p); + if (ret != -ENOTTY) + return ret; - ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg); - - } - return ret; + return scsi_compat_ioctl(STp->device, cmd_in, p); } #endif diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 358ea2ecf36b..ab4471f469e6 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -36,109 +36,11 @@ #include "internal.h" -#ifdef CONFIG_BLOCK -#include -#include -#include -#include -#include -#endif - #include #include #include - -#include - -/* - * simple reversible transform to make our table more evenly - * distributed after sorting. - */ -#define XFORM(i) (((i) ^ ((i) << 27) ^ ((i) << 17)) & 0xffffffff) - -#define COMPATIBLE_IOCTL(cmd) XFORM((u32)cmd), -static unsigned int ioctl_pointer[] = { -#ifdef CONFIG_BLOCK -/* Big S */ -COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN) -COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK) -COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK) -COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY) -COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER) -COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND) -COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST) -COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI) -#endif -#ifdef CONFIG_BLOCK -/* SG stuff */ -COMPATIBLE_IOCTL(SG_IO) -COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE) -COMPATIBLE_IOCTL(SG_SET_TIMEOUT) -COMPATIBLE_IOCTL(SG_GET_TIMEOUT) -COMPATIBLE_IOCTL(SG_EMULATED_HOST) -COMPATIBLE_IOCTL(SG_GET_TRANSFORM) -COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE) -COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE) -COMPATIBLE_IOCTL(SG_GET_SCSI_ID) -COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA) -COMPATIBLE_IOCTL(SG_GET_LOW_DMA) -COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID) -COMPATIBLE_IOCTL(SG_GET_PACK_ID) -COMPATIBLE_IOCTL(SG_GET_NUM_WAITING) -COMPATIBLE_IOCTL(SG_SET_DEBUG) -COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE) -COMPATIBLE_IOCTL(SG_GET_COMMAND_Q) -COMPATIBLE_IOCTL(SG_SET_COMMAND_Q) -COMPATIBLE_IOCTL(SG_GET_VERSION_NUM) -COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN) -COMPATIBLE_IOCTL(SG_SCSI_RESET) -COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE) -COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN) -COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN) -#endif -}; - -/* - * Convert common ioctl arguments based on their command number - * - * Please do not add any code in here. Instead, implement - * a compat_ioctl operation in the place that handleѕ the - * ioctl for the native case. - */ -static long do_ioctl_trans(unsigned int cmd, - unsigned long arg, struct file *file) -{ - return -ENOIOCTLCMD; -} - -static int compat_ioctl_check_table(unsigned int xcmd) -{ -#ifdef CONFIG_BLOCK - int i; - const int max = ARRAY_SIZE(ioctl_pointer) - 1; - - BUILD_BUG_ON(max >= (1 << 16)); - - /* guess initial offset into table, assuming a - normalized distribution */ - i = ((xcmd >> 16) * max) >> 16; - - /* do linear search up first, until greater or equal */ - while (ioctl_pointer[i] < xcmd && i < max) - i++; - - /* then do linear search down */ - while (ioctl_pointer[i] > xcmd && i > 0) - i--; - - return ioctl_pointer[i] == xcmd; -#else - return 0; -#endif -} - COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, compat_ulong_t, arg32) { @@ -216,19 +118,9 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, goto out_fput; } - if (!f.file->f_op->unlocked_ioctl) - goto do_ioctl; - break; - } - - if (compat_ioctl_check_table(XFORM(cmd))) - goto found_handler; - - error = do_ioctl_trans(cmd, arg, f.file); - if (error == -ENOIOCTLCMD) error = -ENOTTY; - - goto out_fput; + goto out_fput; + } found_handler: arg = (unsigned long)compat_ptr(arg); @@ -239,23 +131,3 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, out: return error; } - -static int __init init_sys32_ioctl_cmp(const void *p, const void *q) -{ - unsigned int a, b; - a = *(unsigned int *)p; - b = *(unsigned int *)q; - if (a > b) - return 1; - if (a < b) - return -1; - return 0; -} - -static int __init init_sys32_ioctl(void) -{ - sort(ioctl_pointer, ARRAY_SIZE(ioctl_pointer), sizeof(*ioctl_pointer), - init_sys32_ioctl_cmp, NULL); - return 0; -} -__initcall(init_sys32_ioctl); From patchwork Thu Jan 2 14:55:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 11315915 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 35EF1138C for ; Thu, 2 Jan 2020 15:02:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1DA7A20848 for ; Thu, 2 Jan 2020 15:02:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728619AbgABPCZ (ORCPT ); Thu, 2 Jan 2020 10:02:25 -0500 Received: from mout.kundenserver.de ([212.227.126.131]:55343 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728595AbgABPCY (ORCPT ); Thu, 2 Jan 2020 10:02:24 -0500 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue011 [212.227.15.129]) with ESMTPA (Nemesis) id 1MfHQp-1jOJja3KQN-00gnxw; Thu, 02 Jan 2020 16:01:49 +0100 From: Arnd Bergmann To: "James E.J. Bottomley" , "Martin K. Petersen" Cc: Arnd Bergmann , Jens Axboe , Alexander Viro , Martin Wilck , David Howells , "Darrick J. Wong" , "Theodore Ts'o" , Gao Xiang , Phillip Potter , linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v3 14/22] compat_ioctl: move sys_compat_ioctl() to ioctl.c Date: Thu, 2 Jan 2020 15:55:32 +0100 Message-Id: <20200102145552.1853992-15-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20200102145552.1853992-1-arnd@arndb.de> References: <20200102145552.1853992-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:QHW26qoZu7BFOLY294SQCDAdYS+0LermWcmWpuZcCs1uu3ygnuv o7yXMPGUgodpJydzENgx8LxWBx25o6BxiYCvPny319dmjTgRx3wYYT08P3JX6GkwJPdF9Fv uTGqxsO8Oi2yjHAK0GmswsnVYNnaJTVnLlycdPQvfZBCOsHny1TQi6zBU/4Nm/gN4adJEcM QfsIzZQzDJpkVSQ8QcANA== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:o4Y9FEc7lmM=:FQzkxK5zPiq0iQsTxqM13f Zbrvxtvh6EyBo2ubdbPy+9B0cTbLhK4uRVtQaXlx0OSds661k1ptv1bN4I/FttEvINcwSqVmC U4RtO1HnQUnMdYaPoO5emXKtb329TqemuRcKxqr2X6Sq9gHsaVgxycAcr8+bvqeDC+OPnaOvw AWT5t08j27I1pahKYrts7dafLHbA2MlalQmUW/EgQnoccEs5lN4DFbgpAh/bjTwiQOrYgl4dz e37F0L1cmLiUXWkxzmplJUX9pLfuE279NlzQoaAs3JD1MCnk1I/mVc5X1isLVU4ZT3bv4i8AG T3xwBpDaexQCASS43vdn+GRqhtGaAOuR5EqmAoaCNsBz5J4xj8SC9smxVp/PwPRYcItIRV7LB vIqQsyCRT7EUky08cPguYbYajeKnLoTBgc/QwZlZUPuQsj9+8OuOS7Lp7UcRSVImgAGi+h9j2 /dKWFJRjPBjRWAc+uaX8Ftjq4fC8fOd+He6LIe8L9/aPCCviqTAuuZjf8Udm7RUV0pU2byQtF 5rS9pvbxf67gbNWnIsnxUdQRjut/dfDcOl06yWIO45vwu0aZwV9Lgew0CjwuXGdPBMlXjqSEc L94ufpzZ4op6UvW3e3fyzyJFE9ExIzyu6LTUMxIMh2oHMxfTCmp2RI4VOdRVjv736etSXyctU fORl2tWlEytlTlW7xDPBSGF/FQxCE8tti0cRPQviQXkk9l1J6d359h/jgDkXWjTLk5i0vG5c9 I2lRlUatZW8fRkrKPe/Gxb+uPtSm3k43mICXElFl1t68SC6Z3tJzP/nYcoIbRgPy23f60/g+E a4E7wOx7+hTyEqg/fnkZs8nhC08/GNEILnz4SPSleIXlOEbUJ+3KJepIDkANsNqFPRODSP6jG p06GILZr5NMNAyTKHejQ== Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org The rest of the fs/compat_ioctl.c file is no longer useful now, so move the actual syscall as planned. Signed-off-by: Arnd Bergmann --- drivers/scsi/sr.c | 2 +- fs/Makefile | 2 +- fs/compat_ioctl.c | 133 ---------------------------------------------- fs/ioctl.c | 90 +++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 135 deletions(-) delete mode 100644 fs/compat_ioctl.c diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 6033a886c42c..f1e7aab00ce3 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -634,7 +634,7 @@ static int sr_block_compat_ioctl(struct block_device *bdev, fmode_t mode, unsign */ ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp); if (ret != -ENOTTY) - return ret; + goto put; ret = scsi_compat_ioctl(sdev, cmd, argp); diff --git a/fs/Makefile b/fs/Makefile index 1148c555c4d3..98be354fdb61 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -37,7 +37,7 @@ obj-$(CONFIG_FS_DAX) += dax.o obj-$(CONFIG_FS_ENCRYPTION) += crypto/ obj-$(CONFIG_FS_VERITY) += verity/ obj-$(CONFIG_FILE_LOCKING) += locks.o -obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o +obj-$(CONFIG_COMPAT) += compat.o obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c deleted file mode 100644 index ab4471f469e6..000000000000 --- a/fs/compat_ioctl.c +++ /dev/null @@ -1,133 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * ioctl32.c: Conversion between 32bit and 64bit native ioctls. - * - * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) - * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) - * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs - * Copyright (C) 2003 Pavel Machek (pavel@ucw.cz) - * - * These routines maintain argument size conversion between 32bit and 64bit - * ioctls. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "internal.h" - -#include -#include - -#include - -COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, - compat_ulong_t, arg32) -{ - unsigned long arg = arg32; - struct fd f = fdget(fd); - int error = -EBADF; - if (!f.file) - goto out; - - /* RED-PEN how should LSM module know it's handling 32bit? */ - error = security_file_ioctl(f.file, cmd, arg); - if (error) - goto out_fput; - - switch (cmd) { - /* these are never seen by ->ioctl(), no argument or int argument */ - case FIOCLEX: - case FIONCLEX: - case FIFREEZE: - case FITHAW: - case FICLONE: - goto do_ioctl; - /* these are never seen by ->ioctl(), pointer argument */ - case FIONBIO: - case FIOASYNC: - case FIOQSIZE: - case FS_IOC_FIEMAP: - case FIGETBSZ: - case FICLONERANGE: - case FIDEDUPERANGE: - goto found_handler; - /* - * The next group is the stuff handled inside file_ioctl(). - * For regular files these never reach ->ioctl(); for - * devices, sockets, etc. they do and one (FIONREAD) is - * even accepted in some cases. In all those cases - * argument has the same type, so we can handle these - * here, shunting them towards do_vfs_ioctl(). - * ->compat_ioctl() will never see any of those. - */ - /* pointer argument, never actually handled by ->ioctl() */ - case FIBMAP: - goto found_handler; - /* handled by some ->ioctl(); always a pointer to int */ - case FIONREAD: - goto found_handler; - /* these get messy on amd64 due to alignment differences */ -#if defined(CONFIG_X86_64) - case FS_IOC_RESVSP_32: - case FS_IOC_RESVSP64_32: - error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg)); - goto out_fput; - case FS_IOC_UNRESVSP_32: - case FS_IOC_UNRESVSP64_32: - error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE, - compat_ptr(arg)); - goto out_fput; - case FS_IOC_ZERO_RANGE_32: - error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE, - compat_ptr(arg)); - goto out_fput; -#else - case FS_IOC_RESVSP: - case FS_IOC_RESVSP64: - case FS_IOC_UNRESVSP: - case FS_IOC_UNRESVSP64: - case FS_IOC_ZERO_RANGE: - goto found_handler; -#endif - - default: - if (f.file->f_op->compat_ioctl) { - error = f.file->f_op->compat_ioctl(f.file, cmd, arg); - if (error != -ENOIOCTLCMD) - goto out_fput; - } - - error = -ENOTTY; - goto out_fput; - } - - found_handler: - arg = (unsigned long)compat_ptr(arg); - do_ioctl: - error = do_vfs_ioctl(f.file, fd, cmd, arg); - out_fput: - fdput(f); - out: - return error; -} diff --git a/fs/ioctl.c b/fs/ioctl.c index 2f5e4e5b97e1..8f22f7817edb 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -788,4 +788,94 @@ long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); } EXPORT_SYMBOL(compat_ptr_ioctl); + +COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, + compat_ulong_t, arg32) +{ + unsigned long arg = arg32; + struct fd f = fdget(fd); + int error = -EBADF; + if (!f.file) + goto out; + + /* RED-PEN how should LSM module know it's handling 32bit? */ + error = security_file_ioctl(f.file, cmd, arg); + if (error) + goto out_fput; + + switch (cmd) { + /* these are never seen by ->ioctl(), no argument or int argument */ + case FIOCLEX: + case FIONCLEX: + case FIFREEZE: + case FITHAW: + case FICLONE: + goto do_ioctl; + /* these are never seen by ->ioctl(), pointer argument */ + case FIONBIO: + case FIOASYNC: + case FIOQSIZE: + case FS_IOC_FIEMAP: + case FIGETBSZ: + case FICLONERANGE: + case FIDEDUPERANGE: + goto found_handler; + /* + * The next group is the stuff handled inside file_ioctl(). + * For regular files these never reach ->ioctl(); for + * devices, sockets, etc. they do and one (FIONREAD) is + * even accepted in some cases. In all those cases + * argument has the same type, so we can handle these + * here, shunting them towards do_vfs_ioctl(). + * ->compat_ioctl() will never see any of those. + */ + /* pointer argument, never actually handled by ->ioctl() */ + case FIBMAP: + goto found_handler; + /* handled by some ->ioctl(); always a pointer to int */ + case FIONREAD: + goto found_handler; + /* these get messy on amd64 due to alignment differences */ +#if defined(CONFIG_X86_64) + case FS_IOC_RESVSP_32: + case FS_IOC_RESVSP64_32: + error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg)); + goto out_fput; + case FS_IOC_UNRESVSP_32: + case FS_IOC_UNRESVSP64_32: + error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE, + compat_ptr(arg)); + goto out_fput; + case FS_IOC_ZERO_RANGE_32: + error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE, + compat_ptr(arg)); + goto out_fput; +#else + case FS_IOC_RESVSP: + case FS_IOC_RESVSP64: + case FS_IOC_UNRESVSP: + case FS_IOC_UNRESVSP64: + case FS_IOC_ZERO_RANGE: + goto found_handler; +#endif + + default: + if (f.file->f_op->compat_ioctl) { + error = f.file->f_op->compat_ioctl(f.file, cmd, arg); + if (error != -ENOIOCTLCMD) + goto out_fput; + } + error = -ENOTTY; + goto out_fput; + } + + found_handler: + arg = (unsigned long)compat_ptr(arg); + do_ioctl: + error = do_vfs_ioctl(f.file, fd, cmd, arg); + out_fput: + fdput(f); + out: + return error; +} #endif From patchwork Thu Jan 2 14:55:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 11315919 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E9EBE138C for ; Thu, 2 Jan 2020 15:03:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C8AC920848 for ; Thu, 2 Jan 2020 15:03:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728718AbgABPDY (ORCPT ); Thu, 2 Jan 2020 10:03:24 -0500 Received: from mout.kundenserver.de ([212.227.126.187]:38279 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728571AbgABPDY (ORCPT ); Thu, 2 Jan 2020 10:03:24 -0500 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue011 [212.227.15.129]) with ESMTPA (Nemesis) id 1MJVY8-1j2VY31jlw-00Jvad; Thu, 02 Jan 2020 16:02:43 +0100 From: Arnd Bergmann To: "James E.J. Bottomley" , "Martin K. Petersen" Cc: Arnd Bergmann , Jens Axboe , Tim Waugh , Borislav Petkov , "David S. Miller" , Damien Le Moal , zhengbin , Hannes Reinecke , YueHaibing , Martin Wilck , Sergey Senozhatsky , Kefeng Wang , Mauro Carvalho Chehab , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org Subject: [PATCH v3 16/22] compat_ioctl: move cdrom commands into cdrom.c Date: Thu, 2 Jan 2020 15:55:34 +0100 Message-Id: <20200102145552.1853992-17-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20200102145552.1853992-1-arnd@arndb.de> References: <20200102145552.1853992-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:7HaNj+kg58AHuRufCpul7Uhfs08N+yeTpHJHjVcGayfYtYbvyK/ gPTfC9V0RX3Kh4qb5P9bESSKsqBmuS0QZeYKIFmBoCnu4tTgTjLk3R7+WbBhFt6kV0hxyY1 Jjso1mB8Kaykxnvjsdrvi8LSF+OW82GA9NtdSACP+37KgJ7QT2UD809QOiI7czN3j4kP3HW XNp6J1m4r7jDQV/3WWS8A== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:RE0c2PHyQfE=:ClFbXwEaGJkU0KS/r5Q+A/ eIyf/Q6YAnGOp2uglCpr1u8m4djz9Ezo7M8lfXZ1Kg3xgQPQzOJhpGFnt9P0YCX3nT9qrX4W8 tlXHEFsPDv2DsL+cOG4sAMD967fnicQYTji5yMEaK6LumDsyY+xMYC2a3B6kutmnkNKPiRzCM zaPzRGn7e7HrMwnK3BMGsWVwL8lzRHASVgNR5XKek8F20wSy0eQTxjSj20yBeMJgXGsh+OU5x aq7mYPxjrfQ34xawfAu3KHqlUebDGTX+fynFCRevnt5qFTIRMwC+48R50tKww1X9mAQabEaDs E6ka36s8cMLPWxcR7pgkL2aQSx9oGtRu0hwypIGVG93TG1KkrbJV4E5z+KwG6lTm/zOfoh9aF +2OxEW9FBlYephcGDutuk/+GR7ayUQ1/56jNOEGWiG94c9P2QnP5Q8uk1mdaXVFT3ovqoQNms eXsj1Cfm1HNZ4tQqYAXv/GcJa5LeDDNkbhJ6ESY+EyhvQClTB9DWGvLD04PlBwU/trVTFCOzP LGvljnJCQ8F8r0NKAe+QbqqFTD+AiwkJdcSbYSBefw04iyfZDNCO/3+XzmEXmbLXBCO7AUEwE hI6VWJXUwiMbWU6FPx/Xjf+khPFgqfnzcgLz1HnIL9BQAGcRfvpk0Zw6ljhQ+kceZSE6qDBxd BOhpcRRhweV57XZuxM9hfBINBXLSoMbDx1GSc55/4u520SxrvdqUbua79ZkZbzxlCnFMdlgDg d9zBaW7QINy13zc3lQbL6gW+FWUx8ZRHcJ3jTzQ3dOzpGh+U0JSbR16iXJsXfitJse6nvi2i1 QE6YyBQ0OOHbYPxKe315VC8j5h7TkmQYHNDJkxgMKjCbIDRJBbL1bxRFwVbiRjbuTXZOFJuTw N8FS7F4VdCsxqBkQwDWA== Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org There is no need for the special cases for the cdrom ioctls any more now, so make sure that each cdrom driver has a .compat_ioctl() callback and calls cdrom_compat_ioctl() directly there. Signed-off-by: Arnd Bergmann --- block/compat_ioctl.c | 45 -------------------------------------- drivers/block/paride/pcd.c | 3 +++ drivers/cdrom/gdrom.c | 3 +++ drivers/ide/ide-cd.c | 37 +++++++++++++++++++++++++++++++ drivers/scsi/sr.c | 8 ++----- 5 files changed, 45 insertions(+), 51 deletions(-) diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index 91a5dcf6e36c..e1c5d07b09e5 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c @@ -160,42 +160,6 @@ static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, case HDIO_DRIVE_CMD: /* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */ case 0x330: - /* CDROM stuff */ - case CDROMPAUSE: - case CDROMRESUME: - case CDROMPLAYMSF: - case CDROMPLAYTRKIND: - case CDROMREADTOCHDR: - case CDROMREADTOCENTRY: - case CDROMSTOP: - case CDROMSTART: - case CDROMEJECT: - case CDROMVOLCTRL: - case CDROMSUBCHNL: - case CDROMMULTISESSION: - case CDROM_GET_MCN: - case CDROMRESET: - case CDROMVOLREAD: - case CDROMSEEK: - case CDROMPLAYBLK: - case CDROMCLOSETRAY: - case CDROM_DISC_STATUS: - case CDROM_CHANGER_NSLOTS: - case CDROM_GET_CAPABILITY: - case CDROM_SEND_PACKET: - /* Ignore cdrom.h about these next 5 ioctls, they absolutely do - * not take a struct cdrom_read, instead they take a struct cdrom_msf - * which is compatible. - */ - case CDROMREADMODE2: - case CDROMREADMODE1: - case CDROMREADRAW: - case CDROMREADCOOKED: - case CDROMREADALL: - /* DVD ioctls */ - case DVD_READ_STRUCT: - case DVD_WRITE_STRUCT: - case DVD_AUTH: arg = (unsigned long)compat_ptr(arg); /* These intepret arg as an unsigned long, not as a pointer, * so we must not do compat_ptr() conversion. */ @@ -211,15 +175,6 @@ static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, case HDIO_SET_ACOUSTIC: case HDIO_SET_BUSSTATE: case HDIO_SET_ADDRESS: - case CDROMEJECT_SW: - case CDROM_SET_OPTIONS: - case CDROM_CLEAR_OPTIONS: - case CDROM_SELECT_SPEED: - case CDROM_SELECT_DISC: - case CDROM_MEDIA_CHANGED: - case CDROM_DRIVE_STATUS: - case CDROM_LOCKDOOR: - case CDROM_DEBUG: break; default: /* unknown ioctl number */ diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 636bfea2de6f..117cfc8cd05a 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -275,6 +275,9 @@ static const struct block_device_operations pcd_bdops = { .open = pcd_block_open, .release = pcd_block_release, .ioctl = pcd_block_ioctl, +#ifdef CONFIG_COMPAT + .ioctl = blkdev_compat_ptr_ioctl, +#endif .check_events = pcd_block_check_events, }; diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 5b21dc421c94..886b2638c730 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -518,6 +518,9 @@ static const struct block_device_operations gdrom_bdops = { .release = gdrom_bdops_release, .check_events = gdrom_bdops_check_events, .ioctl = gdrom_bdops_ioctl, +#ifdef CONFIG_COMPAT + .ioctl = blkdev_compat_ptr_ioctl, +#endif }; static irqreturn_t gdrom_command_interrupt(int irq, void *dev_id) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 9d117936bee1..e09b949a7c46 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -25,6 +25,7 @@ #define IDECD_VERSION "5.00" +#include #include #include #include @@ -1710,6 +1711,39 @@ static int idecd_ioctl(struct block_device *bdev, fmode_t mode, return ret; } +#ifdef CONFIG_COMPAT +static int idecd_locked_compat_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) +{ + struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); + void __user *argp = compat_ptr(arg); + int err; + + switch (cmd) { + case CDROMSETSPINDOWN: + return idecd_set_spindown(&info->devinfo, (unsigned long)argp); + case CDROMGETSPINDOWN: + return idecd_get_spindown(&info->devinfo, (unsigned long)argp); + default: + break; + } + + return cdrom_ioctl(&info->devinfo, bdev, mode, cmd, + (unsigned long)argp); +} + +static int idecd_compat_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) +{ + int ret; + + mutex_lock(&ide_cd_mutex); + ret = idecd_locked_compat_ioctl(bdev, mode, cmd, arg); + mutex_unlock(&ide_cd_mutex); + + return ret; +} +#endif static unsigned int idecd_check_events(struct gendisk *disk, unsigned int clearing) @@ -1732,6 +1766,9 @@ static const struct block_device_operations idecd_ops = { .open = idecd_open, .release = idecd_release, .ioctl = idecd_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = idecd_compat_ioctl, +#endif .check_events = idecd_check_events, .revalidate_disk = idecd_revalidate_disk }; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index f1e7aab00ce3..0fbb8fe6e521 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -628,12 +628,8 @@ static int sr_block_compat_ioctl(struct block_device *bdev, fmode_t mode, unsign goto put; } - /* - * CDROM ioctls are handled in the block layer, but - * do the scsi blk ioctls here. - */ - ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp); - if (ret != -ENOTTY) + ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, (unsigned long)argp); + if (ret != -ENOSYS) goto put; ret = scsi_compat_ioctl(sdev, cmd, argp); From patchwork Thu Jan 2 14:55:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 11315937 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 22127138C for ; Thu, 2 Jan 2020 15:05:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EAD6022525 for ; Thu, 2 Jan 2020 15:05:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728773AbgABPE6 (ORCPT ); Thu, 2 Jan 2020 10:04:58 -0500 Received: from mout.kundenserver.de ([212.227.126.131]:60419 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728728AbgABPE6 (ORCPT ); Thu, 2 Jan 2020 10:04:58 -0500 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue011 [212.227.15.129]) with ESMTPA (Nemesis) id 1MfYgC-1jOap53wS0-00fykl; Thu, 02 Jan 2020 16:03:36 +0100 From: Arnd Bergmann To: "James E.J. Bottomley" , "Martin K. Petersen" Cc: Arnd Bergmann , Jens Axboe , John Garry , Brian King , Intel SCU Linux support , Artur Paszkiewicz , Jack Wang , Kees Cook , Thomas Gleixner , Mika Westerberg , James Bottomley , Greg Kroah-Hartman , Hannes Reinecke , Xiang Chen , Luo Jiaxing , zhengbin , Xiaofei Tan , Bart Van Assche , Bradley Grove , Ming Lei , Logan Gunthorpe , Jeff Moyer , Richard Fontana , Deepak Ukey , Viswas G , peter chang , Colin Ian King , Saurav Girepunje , Vikram Auradkar , Denis Efremov , Jiri Slaby , Jilayne Lovejoy , linux-ide@vger.kernel.org, linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org Subject: [PATCH v3 17/22] compat_ioctl: scsi: handle HDIO commands from drivers Date: Thu, 2 Jan 2020 15:55:35 +0100 Message-Id: <20200102145552.1853992-18-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20200102145552.1853992-1-arnd@arndb.de> References: <20200102145552.1853992-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:em1wWyRE/wRIZrTiJ9/rnuBjFpeAztfbhyJDPp+3XtIg+XgBc+3 APBCDum0e0xHmDyO6SOJG8c/m8HxTWbZHz79sdQp9UtoN1QisJLvNXVD4KsNiZSbcU4y8ww NNZYlaPFj7atoo1KHIrT0yMRBv4OySaB3AddPM3m3nu6lXBIR2KlbZjEdUwN4buiMn35dow /+G7Cbrkeaj1wa2kZz2DA== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:iY6OqM8KHtc=:qnZ0ggQTqr83IgrTxCpzQs lm+D91PC0Nv6VGxw1LN4N1iVTBKqBRTL0S7MRvNtXKDjdzbJvV9o01Uq7cySxK86N99p6BQrp 9PShqiD4iSub6MiJDRFLbpMMwJz5K2x+ReWM4O2dDe/nao1pG8IcYxmJt73uSo039PJ9EUtiA dJipMBc2x320mGDkdEFjc3pdIj79CkS5ULPCjvbyXumFoYau9G8MvpQHQzwem/COhHB5arWWz gKaHtQJGKePJphRNoqdUSITRutzSiqAacmOnRuytgwBaNwFwydNu0PFh8uP3QpTgt2JKWNJan nxmFMxCRe12PUm+FHKMgoBMM/Hu6R+dCIRKGO1SuC6rEBw5hw1YxWjgDrLqHqXvghyKKIqcNM chLW/0Qp+MCWmhsY1+KSiuEadORkGxUXcsgAbz2ttY15QEtJcvc06hu2EZKcL1vj855Lf5KaU XE3SPNlWocl8SV61BSe/yuMcqCzwFJuHCa8hMGYms9RKvqkGtzPhc6UIC1yZICDLWzHwXGr58 ZV4mKZOza8RhO8iLIxGg4VO8dDitCCrgw+yB3dZmShSNVmXNx4RG+KboK7C1dMYppcitsFAOz pBqRalYDYXwUTVYdnLUiSKyxpUwYDV2CLh26b+IhoscimG/10pUqhMZFT+5Qeb0s7K/18VZ5m 1vvIYo61kUZdiFfmCpAORPSO348xJjEuSE7x6datFh1gUFIgYOUW/0jZk1/kuNmY36CbFqK54 vZBFMHehcpuqaGILsyCzJ5PwLbuYrzz4UnIGFK0MufvfBjFx1GPM1qVZsUN6MWxI3QjJnOhjL u+B4dPaRCyvqmFMEQlPNtvC9iUGd1nS1SNRmxX21y6ApKBZteeBT7yKEFJrkF6Pi8hnopWSXR K/SA20cxfj0T+yNrUIBA== Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org The ata_sas_scsi_ioctl() function implements a number of HDIO_* commands for SCSI devices, it is used by all libata drivers as well as a few drivers that support SAS attached SATA drives. The only command that is not safe for compat ioctls here is HDIO_GET_32BIT. Change the implementation to check for in_compat_syscall() in order to do both cases correctly, and change all callers to use it as both native and compat callback pointers, including the indirect callers through sas_ioctl and ata_scsi_ioctl. Signed-off-by: Arnd Bergmann --- drivers/ata/libata-scsi.c | 9 +++++++++ drivers/scsi/aic94xx/aic94xx_init.c | 3 +++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 3 +++ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 3 +++ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +++ drivers/scsi/ipr.c | 3 +++ drivers/scsi/isci/init.c | 3 +++ drivers/scsi/mvsas/mv_init.c | 3 +++ drivers/scsi/pm8001/pm8001_init.c | 3 +++ include/linux/libata.h | 6 ++++++ 10 files changed, 39 insertions(+) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 58e09ffe8b9c..eb2eb599e602 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -17,6 +17,7 @@ * - http://www.t13.org/ */ +#include #include #include #include @@ -761,6 +762,10 @@ static int ata_ioc32(struct ata_port *ap) return 0; } +/* + * This handles both native and compat commands, so anything added + * here must have a compatible argument, or check in_compat_syscall() + */ int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev, unsigned int cmd, void __user *arg) { @@ -773,6 +778,10 @@ int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev, spin_lock_irqsave(ap->lock, flags); val = ata_ioc32(ap); spin_unlock_irqrestore(ap->lock, flags); +#ifdef CONFIG_COMPAT + if (in_compat_syscall()) + return put_user(val, (compat_ulong_t __user *)arg); +#endif return put_user(val, (unsigned long __user *)arg); case HDIO_SET_32BIT: diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index f5781e31f57c..d022407e5645 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -54,6 +54,9 @@ static struct scsi_host_template aic94xx_sht = { .eh_target_reset_handler = sas_eh_target_reset_handler, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = sas_ioctl, +#endif .track_queue_depth = 1, }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 3af53cc42bd6..fa25766502a2 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1772,6 +1772,9 @@ static struct scsi_host_template sht_v1_hw = { .eh_target_reset_handler = sas_eh_target_reset_handler, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = sas_ioctl, +#endif .shost_attrs = host_attrs_v1_hw, .host_reset = hisi_sas_host_reset, }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 61b1e2693b08..545eaff5f3ee 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -3551,6 +3551,9 @@ static struct scsi_host_template sht_v2_hw = { .eh_target_reset_handler = sas_eh_target_reset_handler, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = sas_ioctl, +#endif .shost_attrs = host_attrs_v2_hw, .host_reset = hisi_sas_host_reset, }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index bf5d5f138437..fa05e612d85a 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -3075,6 +3075,9 @@ static struct scsi_host_template sht_v3_hw = { .eh_target_reset_handler = sas_eh_target_reset_handler, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = sas_ioctl, +#endif .shost_attrs = host_attrs_v3_hw, .tag_alloc_policy = BLK_TAG_ALLOC_RR, .host_reset = hisi_sas_host_reset, diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 079c04bc448a..ae45cbe98ae2 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6727,6 +6727,9 @@ static struct scsi_host_template driver_template = { .name = "IPR", .info = ipr_ioa_info, .ioctl = ipr_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ipr_ioctl, +#endif .queuecommand = ipr_queuecommand, .eh_abort_handler = ipr_eh_abort, .eh_device_reset_handler = ipr_eh_dev_reset, diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index 1727d0c71b12..b48aac8dfcb8 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -168,6 +168,9 @@ static struct scsi_host_template isci_sht = { .eh_target_reset_handler = sas_eh_target_reset_handler, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = sas_ioctl, +#endif .shost_attrs = isci_host_attrs, .track_queue_depth = 1, }; diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index da719b0694dc..7af9173c4925 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -47,6 +47,9 @@ static struct scsi_host_template mvs_sht = { .eh_target_reset_handler = sas_eh_target_reset_handler, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = sas_ioctl, +#endif .shost_attrs = mvst_host_attrs, .track_queue_depth = 1, }; diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index ff618ad80ebd..3c6076e4c6d2 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -101,6 +101,9 @@ static struct scsi_host_template pm8001_sht = { .eh_target_reset_handler = sas_eh_target_reset_handler, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = sas_ioctl, +#endif .shost_attrs = pm8001_host_attrs, .track_queue_depth = 1, }; diff --git a/include/linux/libata.h b/include/linux/libata.h index 2dbde119721d..a36bdcb8d9e9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1109,6 +1109,11 @@ extern void ata_host_init(struct ata_host *, struct device *, struct ata_port_op extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_ioctl(struct scsi_device *dev, unsigned int cmd, void __user *arg); +#ifdef CONFIG_COMPAT +#define ATA_SCSI_COMPAT_IOCTL .compat_ioctl = ata_scsi_ioctl, +#else +#define ATA_SCSI_COMPAT_IOCTL /* empty */ +#endif extern int ata_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd); extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev, unsigned int cmd, void __user *arg); @@ -1341,6 +1346,7 @@ extern struct device_attribute *ata_common_sdev_attrs[]; .module = THIS_MODULE, \ .name = drv_name, \ .ioctl = ata_scsi_ioctl, \ + ATA_SCSI_COMPAT_IOCTL \ .queuecommand = ata_scsi_queuecmd, \ .can_queue = ATA_DEF_QUEUE, \ .tag_alloc_policy = BLK_TAG_ALLOC_RR, \