nvme: simplify the compat ioctl handling
authorChristoph Hellwig <hch@lst.de>
Thu, 8 Apr 2021 12:04:42 +0000 (14:04 +0200)
committerChristoph Hellwig <hch@lst.de>
Thu, 15 Apr 2021 06:12:55 +0000 (08:12 +0200)
Don't bother defining a separate compat_ioctl handler, and just handle
the NVME_IOCTL_SUBMIT_IO32 case inline.  Also only defined it for those
ABIs (currently just i386 vs x86_64) that are affected.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Javier González <javier.gonz@samsung.com>
drivers/nvme/host/core.c

index 85acb9f608cd17359de42b17ab2f581d0fd12633..cb20c5c8bbc437692f1efd22065f0484e0229b1a 100644 (file)
@@ -1783,6 +1783,24 @@ static int nvme_handle_ctrl_ioctl(struct nvme_ns *ns, unsigned int cmd,
        return ret;
 }
 
+#ifdef COMPAT_FOR_U64_ALIGNMENT
+struct nvme_user_io32 {
+       __u8    opcode;
+       __u8    flags;
+       __u16   control;
+       __u16   nblocks;
+       __u16   rsvd;
+       __u64   metadata;
+       __u64   addr;
+       __u64   slba;
+       __u32   dsmgmt;
+       __u32   reftag;
+       __u16   apptag;
+       __u16   appmask;
+} __attribute__((__packed__));
+#define NVME_IOCTL_SUBMIT_IO32 _IOW('N', 0x42, struct nvme_user_io32)
+#endif /* COMPAT_FOR_U64_ALIGNMENT */
+
 static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
                void __user *argp)
 {
@@ -1792,6 +1810,14 @@ static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
                return ns->head->ns_id;
        case NVME_IOCTL_IO_CMD:
                return nvme_user_cmd(ns->ctrl, ns, argp);
+       /*
+        * struct nvme_user_io can have different padding on some 32-bit ABIs.
+        * Just accept the compat version as all fields that are used are the
+        * same size and at the same offset.
+        */
+#ifdef COMPAT_FOR_U64_ALIGNMENT
+       case NVME_IOCTL_SUBMIT_IO32:
+#endif
        case NVME_IOCTL_SUBMIT_IO:
                return nvme_submit_io(ns, argp);
        case NVME_IOCTL_IO64_CMD:
@@ -1828,47 +1854,6 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
        return ret;
 }
 
-#ifdef CONFIG_COMPAT
-struct nvme_user_io32 {
-       __u8    opcode;
-       __u8    flags;
-       __u16   control;
-       __u16   nblocks;
-       __u16   rsvd;
-       __u64   metadata;
-       __u64   addr;
-       __u64   slba;
-       __u32   dsmgmt;
-       __u32   reftag;
-       __u16   apptag;
-       __u16   appmask;
-} __attribute__((__packed__));
-
-#define NVME_IOCTL_SUBMIT_IO32 _IOW('N', 0x42, struct nvme_user_io32)
-
-static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode,
-               unsigned int cmd, unsigned long arg)
-{
-       /*
-        * Corresponds to the difference of NVME_IOCTL_SUBMIT_IO
-        * between 32 bit programs and 64 bit kernel.
-        * The cause is that the results of sizeof(struct nvme_user_io),
-        * which is used to define NVME_IOCTL_SUBMIT_IO,
-        * are not same between 32 bit compiler and 64 bit compiler.
-        * NVME_IOCTL_SUBMIT_IO32 is for 64 bit kernel handling
-        * NVME_IOCTL_SUBMIT_IO issued from 32 bit programs.
-        * Other IOCTL numbers are same between 32 bit and 64 bit.
-        * So there is nothing to do regarding to other IOCTL numbers.
-        */
-       if (cmd == NVME_IOCTL_SUBMIT_IO32)
-               return nvme_ioctl(bdev, mode, NVME_IOCTL_SUBMIT_IO, arg);
-
-       return nvme_ioctl(bdev, mode, cmd, arg);
-}
-#else
-#define nvme_compat_ioctl      NULL
-#endif /* CONFIG_COMPAT */
-
 static int nvme_open(struct block_device *bdev, fmode_t mode)
 {
        struct nvme_ns *ns = bdev->bd_disk->private_data;
@@ -2356,7 +2341,6 @@ EXPORT_SYMBOL_GPL(nvme_sec_submit);
 static const struct block_device_operations nvme_bdev_ops = {
        .owner          = THIS_MODULE,
        .ioctl          = nvme_ioctl,
-       .compat_ioctl   = nvme_compat_ioctl,
        .open           = nvme_open,
        .release        = nvme_release,
        .getgeo         = nvme_getgeo,
@@ -2385,7 +2369,6 @@ const struct block_device_operations nvme_ns_head_ops = {
        .open           = nvme_ns_head_open,
        .release        = nvme_ns_head_release,
        .ioctl          = nvme_ioctl,
-       .compat_ioctl   = nvme_compat_ioctl,
        .getgeo         = nvme_getgeo,
        .report_zones   = nvme_report_zones,
        .pr_ops         = &nvme_pr_ops,