[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 11/24] compat_ioctl: block: handle cdrom compat ioctl in non-cdrom drivers



Various block drivers implement the CDROMMULTISESSION,
CDROM_GET_CAPABILITY, and CDROMEJECT ioctl commands, relying on the
block layer to handle compat_ioctl mode for them.

Move this into the drivers directly as a preparation for simplifying
the block layer later.

Since some of these commands need a compat_ptr() conversion,
introduce a blkdev_compat_ptr_ioctl() helper function that
can be used as the .compat_ioctl callback for those drivers
that only support compatible commands.

The actual CD-ROM drivers that call cdrom_ioctl() are
converted in a separate patch.

Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx>
---
 block/ioctl.c                | 21 +++++++++++++++++++++
 drivers/block/floppy.c       |  3 +++
 drivers/block/paride/pd.c    |  1 +
 drivers/block/paride/pf.c    |  1 +
 drivers/block/sunvdc.c       |  1 +
 drivers/block/xen-blkfront.c |  1 +
 include/linux/blkdev.h       |  7 +++++++
 7 files changed, 35 insertions(+)

diff --git a/block/ioctl.c b/block/ioctl.c
index 5de98b97af2a..e728331d1a5b 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/capability.h>
+#include <linux/compat.h>
 #include <linux/blkdev.h>
 #include <linux/export.h>
 #include <linux/gfp.h>
@@ -285,6 +286,26 @@ int __blkdev_driver_ioctl(struct block_device *bdev, 
fmode_t mode,
  */
 EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl);
 
+#ifdef CONFIG_COMPAT
+/*
+ * This is the equivalent of compat_ptr_ioctl(), to be used by block
+ * drivers that implement only commands that are completely compatible
+ * between 32-bit and 64-bit user space
+ */
+int blkdev_compat_ptr_ioctl(struct block_device *bdev, fmode_t mode,
+                       unsigned cmd, unsigned long arg)
+{
+       struct gendisk *disk = bdev->bd_disk;
+
+       if (disk->fops->ioctl)
+               return disk->fops->ioctl(bdev, mode, cmd,
+                                        (unsigned long)compat_ptr(arg));
+
+       return -ENOIOCTLCMD;
+}
+EXPORT_SYMBOL(blkdev_compat_ptr_ioctl);
+#endif
+
 static int blkdev_pr_register(struct block_device *bdev,
                struct pr_registration __user *arg)
 {
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 485865fd0412..cd3612e4e2e1 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3879,6 +3879,9 @@ static int fd_compat_ioctl(struct block_device *bdev, 
fmode_t mode, unsigned int
 {
        int drive = (long)bdev->bd_disk->private_data;
        switch (cmd) {
+       case CDROMEJECT: /* CD-ROM eject */
+       case 0x6470:     /* SunOS floppy eject */
+
        case FDMSGON:
        case FDMSGOFF:
        case FDSETEMSGTRESH:
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 6f9ad3fc716f..c0967507d085 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -874,6 +874,7 @@ static const struct block_device_operations pd_fops = {
        .open           = pd_open,
        .release        = pd_release,
        .ioctl          = pd_ioctl,
+       .compat_ioctl   = pd_ioctl,
        .getgeo         = pd_getgeo,
        .check_events   = pd_check_events,
        .revalidate_disk= pd_revalidate
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index 6b7d4cab3687..bb09f21ce21a 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -276,6 +276,7 @@ static const struct block_device_operations pf_fops = {
        .open           = pf_open,
        .release        = pf_release,
        .ioctl          = pf_ioctl,
+       .compat_ioctl   = pf_ioctl,
        .getgeo         = pf_getgeo,
        .check_events   = pf_check_events,
 };
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 571612e233fe..39aeebc6837d 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -171,6 +171,7 @@ static const struct block_device_operations vdc_fops = {
        .owner          = THIS_MODULE,
        .getgeo         = vdc_getgeo,
        .ioctl          = vdc_ioctl,
+       .compat_ioctl   = blkdev_compat_ptr_ioctl,
 };
 
 static void vdc_blk_queue_start(struct vdc_port *port)
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index a74d03913822..23c86350a5ab 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -2632,6 +2632,7 @@ static const struct block_device_operations 
xlvbd_block_fops =
        .release = blkif_release,
        .getgeo = blkif_getgeo,
        .ioctl = blkif_ioctl,
+       .compat_ioctl = blkdev_compat_ptr_ioctl,
 };
 
 
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 47eb22a3b7f9..3e0408618da7 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1711,6 +1711,13 @@ struct block_device_operations {
        const struct pr_ops *pr_ops;
 };
 
+#ifdef CONFIG_COMPAT
+extern int blkdev_compat_ptr_ioctl(struct block_device *, fmode_t,
+                                     unsigned int, unsigned long);
+#else
+#define blkdev_compat_ptr_ioctl NULL
+#endif
+
 extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
                                 unsigned long);
 extern int bdev_read_page(struct block_device *, sector_t, struct page *);
-- 
2.20.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.