]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - block/ioctl.c
vfs: fix up ENOIOCTLCMD error handling
[mirror_ubuntu-artful-kernel.git] / block / ioctl.c
index ca939fc1030f29489f8a5f2c5a142c4e6a6f2264..d510c2a4eff8d42eb02c2da4f0a814c0ad3f6bec 100644 (file)
@@ -179,6 +179,26 @@ int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
  */
 EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl);
 
+/*
+ * Is it an unrecognized ioctl? The correct returns are either
+ * ENOTTY (final) or ENOIOCTLCMD ("I don't know this one, try a
+ * fallback"). ENOIOCTLCMD gets turned into ENOTTY by the ioctl
+ * code before returning.
+ *
+ * Confused drivers sometimes return EINVAL, which is wrong. It
+ * means "I understood the ioctl command, but the parameters to
+ * it were wrong".
+ *
+ * We should aim to just fix the broken drivers, the EINVAL case
+ * should go away.
+ */
+static inline int is_unrecognized_ioctl(int ret)
+{
+       return  ret == -EINVAL ||
+               ret == -ENOTTY ||
+               ret == -ENOIOCTLCMD;
+}
+
 /*
  * always keep this in sync with compat_blkdev_ioctl()
  */
@@ -196,8 +216,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
                        return -EACCES;
 
                ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
-               /* -EINVAL to handle old uncorrected drivers */
-               if (ret != -EINVAL && ret != -ENOTTY)
+               if (!is_unrecognized_ioctl(ret))
                        return ret;
 
                fsync_bdev(bdev);
@@ -206,8 +225,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 
        case BLKROSET:
                ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
-               /* -EINVAL to handle old uncorrected drivers */
-               if (ret != -EINVAL && ret != -ENOTTY)
+               if (!is_unrecognized_ioctl(ret))
                        return ret;
                if (!capable(CAP_SYS_ADMIN))
                        return -EACCES;