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>
This commit is contained in:
parent
78ed001d9e
commit
ee6a129dff
@ -1,5 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
#include <linux/capability.h>
|
#include <linux/capability.h>
|
||||||
|
#include <linux/compat.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/gfp.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);
|
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,
|
static int blkdev_pr_register(struct block_device *bdev,
|
||||||
struct pr_registration __user *arg)
|
struct pr_registration __user *arg)
|
||||||
{
|
{
|
||||||
|
@ -1711,6 +1711,13 @@ struct block_device_operations {
|
|||||||
const struct pr_ops *pr_ops;
|
const struct pr_ops *pr_ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
extern int blkdev_compat_ptr_ioctl(struct block_device *, fmode_t,
|
||||||
|
unsigned int, unsigned long);
|
||||||
|
#else
|
||||||
|
#define blkdev_compat_ptr_ioctl NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
|
extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
|
||||||
unsigned long);
|
unsigned long);
|
||||||
extern int bdev_read_page(struct block_device *, sector_t, struct page *);
|
extern int bdev_read_page(struct block_device *, sector_t, struct page *);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user