summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2019-11-28 15:48:10 +0100
committerArnd Bergmann <arnd@arndb.de>2020-01-03 09:32:59 +0100
commitee6a129dffe10ae30b45b5a744e7c0a056291d13 (patch)
tree6a78fcfc9f06e0eff4265bedddcf42543a0923c8 /block
parent78ed001d9e7106171e0ee761cd854137dd731302 (diff)
downloadlinux-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.c21
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)
{