From 5c5669296319e757e6e9879f796e4edd78878122 Mon Sep 17 00:00:00 2001 From: Hoegeun Kwon Date: Wed, 9 Nov 2022 15:02:38 +0900 Subject: [PATCH] Revert "block: don't call into the driver for BLKROSET" Revert that commit for use with the blkdev_flushbuf ioctl. This reverts commit 732e12d805a77f74c907c0a28ece271ef1e81e01. Change-Id: Ic0f44db39cc4bfd68a69a677949c3913763f2b88 Signed-off-by: Hoegeun Kwon --- block/ioctl.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/block/ioctl.c b/block/ioctl.c index 44c3ce1..c43a732 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -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) { -- 2.7.4