diff options
author | Arnd Bergmann <arnd@arndb.de> | 2019-11-28 15:48:10 +0100 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2020-01-03 09:32:59 +0100 |
commit | ee6a129dffe10ae30b45b5a744e7c0a056291d13 (patch) | |
tree | 6a78fcfc9f06e0eff4265bedddcf42543a0923c8 /block | |
parent | 78ed001d9e7106171e0ee761cd854137dd731302 (diff) | |
download | linux-ee6a129dffe10ae30b45b5a744e7c0a056291d13.tar.bz2 |
compat_ioctl: block: add blkdev_compat_ptr_ioctl
A lot of block drivers need only a trivial .compat_ioctl callback.
Add a helper function that can be set as the callback pointer
to only convert the argument using the compat_ptr() conversion
and otherwise assume all input and output data is compatible,
or handled using in_compat_syscall() checks.
This mirrors the compat_ptr_ioctl() helper function used in
character devices.
Reviewed-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'block')
-rw-r--r-- | block/ioctl.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/block/ioctl.c b/block/ioctl.c index 5de98b97af2a..e728331d1a5b 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/capability.h> +#include <linux/compat.h> #include <linux/blkdev.h> #include <linux/export.h> #include <linux/gfp.h> @@ -285,6 +286,26 @@ int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, */ EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl); +#ifdef CONFIG_COMPAT +/* + * This is the equivalent of compat_ptr_ioctl(), to be used by block + * drivers that implement only commands that are completely compatible + * between 32-bit and 64-bit user space + */ +int blkdev_compat_ptr_ioctl(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg) +{ + struct gendisk *disk = bdev->bd_disk; + + if (disk->fops->ioctl) + return disk->fops->ioctl(bdev, mode, cmd, + (unsigned long)compat_ptr(arg)); + + return -ENOIOCTLCMD; +} +EXPORT_SYMBOL(blkdev_compat_ptr_ioctl); +#endif + static int blkdev_pr_register(struct block_device *bdev, struct pr_registration __user *arg) { |