pktcdvd: add compat_ioctl handler
authorArnd Bergmann <arnd@arndb.de>
Fri, 15 Mar 2019 16:16:36 +0000 (17:16 +0100)
committerArnd Bergmann <arnd@arndb.de>
Wed, 23 Oct 2019 15:23:47 +0000 (17:23 +0200)
pkt_ioctl() implements the generic SCSI_IOCTL_SEND_COMMAND
and some cdrom ioctls by forwarding to the underlying block
device. For compat_ioctl handling, this always takes a
roundtrip through fs/compat_ioctl.c that we should try
to avoid, at least for the compatible commands.

CDROM_SEND_PACKET is an exception here, it requires special
translation in compat_blkdev_driver_ioctl().

CDROM_LAST_WRITTEN has no compat handling at the moment.

Cc: Jens Axboe <axboe@kernel.dk>
Cc: linux-block@vger.kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
drivers/block/pktcdvd.c

index 76457003f140651665b264334c074cca64401c8f..ee67bf929fac8d57e5750c60dacf3ca58a73891d 100644 (file)
@@ -2663,6 +2663,28 @@ static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
        return ret;
 }
 
+#ifdef CONFIG_COMPAT
+static int pkt_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
+{
+       switch (cmd) {
+       /* compatible */
+       case CDROMEJECT:
+       case CDROMMULTISESSION:
+       case CDROMREADTOCENTRY:
+       case SCSI_IOCTL_SEND_COMMAND:
+               return pkt_ioctl(bdev, mode, cmd, (unsigned long)compat_ptr(arg));
+
+
+       /* FIXME: no handler so far */
+       case CDROM_LAST_WRITTEN:
+       /* handled in compat_blkdev_driver_ioctl */
+       case CDROM_SEND_PACKET:
+       default:
+               return -ENOIOCTLCMD;
+       }
+}
+#endif
+
 static unsigned int pkt_check_events(struct gendisk *disk,
                                     unsigned int clearing)
 {
@@ -2684,6 +2706,9 @@ static const struct block_device_operations pktcdvd_ops = {
        .open =                 pkt_open,
        .release =              pkt_close,
        .ioctl =                pkt_ioctl,
+#ifdef CONFIG_COMPAT
+       .ioctl =                pkt_compat_ioctl,
+#endif
        .check_events =         pkt_check_events,
 };