Revert "block: don't call into the driver for BLKROSET"
authorHoegeun Kwon <hoegeun.kwon@samsung.com>
Wed, 9 Nov 2022 06:02:38 +0000 (15:02 +0900)
committerHoegeun Kwon <hoegeun.kwon@samsung.com>
Wed, 23 Nov 2022 02:31:04 +0000 (11:31 +0900)
Revert that commit for use with the blkdev_flushbuf ioctl.

This reverts commit 732e12d805a77f74c907c0a28ece271ef1e81e01.

Change-Id: Ic0f44db39cc4bfd68a69a677949c3913763f2b88
Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
block/ioctl.c

index 44c3ce1..c43a732 100644 (file)
@@ -359,6 +359,26 @@ static int blkdev_pr_clear(struct block_device *bdev,
        return ops->pr_clear(bdev, c.key);
 }
 
+/*
+ * 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;
+}
+
 static int blkdev_flushbuf(struct block_device *bdev, fmode_t mode,
                unsigned cmd, unsigned long arg)
 {
@@ -377,6 +397,9 @@ static int blkdev_roset(struct block_device *bdev, fmode_t mode,
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
 
+       ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
+       if (!is_unrecognized_ioctl(ret))
+               return ret;
        if (get_user(n, (int __user *)arg))
                return -EFAULT;
        if (bdev->bd_disk->fops->set_read_only) {