scsi: ch: Consolidate compat ioctl handling
authorChristoph Hellwig <hch@lst.de>
Sat, 24 Jul 2021 07:20:13 +0000 (09:20 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 29 Jul 2021 02:24:24 +0000 (22:24 -0400)
Merge the native and compat ioctl handlers into a single one using
in_compat_syscall().

Link: https://lore.kernel.org/r/20210724072033.1284840-5-hch@lst.de
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/ch.c

index fc7197a..cf51738 100644 (file)
@@ -618,6 +618,12 @@ ch_checkrange(scsi_changer *ch, unsigned int type, unsigned int unit)
        return 0;
 }
 
+struct changer_element_status32 {
+       int             ces_type;
+       compat_uptr_t   ces_data;
+};
+#define CHIOGSTATUS32  _IOW('c', 8, struct changer_element_status32)
+
 static long ch_ioctl(struct file *file,
                    unsigned int cmd, unsigned long arg)
 {
@@ -748,7 +754,20 @@ static long ch_ioctl(struct file *file,
 
                return ch_gstatus(ch, ces.ces_type, ces.ces_data);
        }
+#ifdef CONFIG_COMPAT
+       case CHIOGSTATUS32:
+       {
+               struct changer_element_status32 ces32;
 
+               if (copy_from_user(&ces32, argp, sizeof(ces32)))
+                       return -EFAULT;
+               if (ces32.ces_type < 0 || ces32.ces_type >= CH_TYPES)
+                       return -EINVAL;
+
+               return ch_gstatus(ch, ces32.ces_type,
+                                 compat_ptr(ces32.ces_data));
+       }
+#endif
        case CHIOGELEM:
        {
                struct changer_get_element cge;
@@ -858,59 +877,13 @@ static long ch_ioctl(struct file *file,
        }
 
        default:
+               if (in_compat_syscall())
+                       return scsi_compat_ioctl(ch->device, cmd, argp);
                return scsi_ioctl(ch->device, cmd, argp);
 
        }
 }
 
-#ifdef CONFIG_COMPAT
-
-struct changer_element_status32 {
-       int             ces_type;
-       compat_uptr_t   ces_data;
-};
-#define CHIOGSTATUS32  _IOW('c', 8,struct changer_element_status32)
-
-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:
-       case CHIOGVPARAMS:
-       case CHIOPOSITION:
-       case CHIOMOVE:
-       case CHIOEXCHANGE:
-       case CHIOGELEM:
-       case CHIOINITELEM:
-       case CHIOSVOLTAG:
-               /* compatible */
-               return ch_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
-       case CHIOGSTATUS32:
-       {
-               struct changer_element_status32 ces32;
-               unsigned char __user *data;
-
-               if (copy_from_user(&ces32, (void __user *)arg, sizeof (ces32)))
-                       return -EFAULT;
-               if (ces32.ces_type < 0 || ces32.ces_type >= CH_TYPES)
-                       return -EINVAL;
-
-               data = compat_ptr(ces32.ces_data);
-               return ch_gstatus(ch, ces32.ces_type, data);
-       }
-       default:
-               return scsi_compat_ioctl(ch->device, cmd, compat_ptr(arg));
-
-       }
-}
-#endif
-
 /* ------------------------------------------------------------------------ */
 
 static int ch_probe(struct device *dev)
@@ -1015,9 +988,7 @@ static const struct file_operations changer_fops = {
        .open           = ch_open,
        .release        = ch_release,
        .unlocked_ioctl = ch_ioctl,
-#ifdef CONFIG_COMPAT
-       .compat_ioctl   = ch_ioctl_compat,
-#endif
+       .compat_ioctl   = compat_ptr_ioctl,
        .llseek         = noop_llseek,
 };