compat_ioctl: move tape handling into drivers
MTIOCPOS and MTIOCGET are incompatible between 32-bit and 64-bit user space, and traditionally have been translated in fs/compat_ioctl.c. To get rid of that translation handler, move a corresponding implementation into each of the four drivers implementing those commands. The interesting part of that is now in a new linux/mtio.h header that wraps the existing uapi/linux/mtio.h header and provides an abstraction to let drivers handle both cases easily. Using an in_compat_syscall() check, the caller does not have to keep track of whether this was called through .unlocked_ioctl() or .compat_ioctl(). Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: "Kai Mäkisara" <Kai.Makisara@kolumbus.fi> Cc: linux-scsi@vger.kernel.org Cc: "James E.J. Bottomley" <jejb@linux.ibm.com> Cc: "Martin K. Petersen" <martin.petersen@oracle.com> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
#define IDETAPE_VERSION "1.20"
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
@@ -1407,14 +1408,10 @@ static long do_idetape_chrdev_ioctl(struct file *file,
|
||||
if (tape->drv_write_prot)
|
||||
mtget.mt_gstat |= GMT_WR_PROT(0xffffffff);
|
||||
|
||||
if (copy_to_user(argp, &mtget, sizeof(struct mtget)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
return put_user_mtget(argp, &mtget);
|
||||
case MTIOCPOS:
|
||||
mtpos.mt_blkno = position / tape->user_bs_factor - block_offset;
|
||||
if (copy_to_user(argp, &mtpos, sizeof(struct mtpos)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
return put_user_mtpos(argp, &mtpos);
|
||||
default:
|
||||
if (tape->chrdev_dir == IDETAPE_DIR_READ)
|
||||
ide_tape_discard_merge_buffer(drive, 1);
|
||||
@@ -1432,6 +1429,22 @@ static long idetape_chrdev_ioctl(struct file *file,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long idetape_chrdev_compat_ioctl(struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
long ret;
|
||||
|
||||
if (cmd == MTIOCPOS32)
|
||||
cmd = MTIOCPOS;
|
||||
else if (cmd == MTIOCGET32)
|
||||
cmd = MTIOCGET;
|
||||
|
||||
mutex_lock(&ide_tape_mutex);
|
||||
ret = do_idetape_chrdev_ioctl(file, cmd, arg);
|
||||
mutex_unlock(&ide_tape_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a mode sense page 0 with block descriptor and if it succeeds set the tape
|
||||
* block size with the reported value.
|
||||
@@ -1886,6 +1899,8 @@ static const struct file_operations idetape_fops = {
|
||||
.read = idetape_chrdev_read,
|
||||
.write = idetape_chrdev_write,
|
||||
.unlocked_ioctl = idetape_chrdev_ioctl,
|
||||
.compat_ioctl = IS_ENABLED(CONFIG_COMPAT) ?
|
||||
idetape_chrdev_compat_ioctl : NULL,
|
||||
.open = idetape_chrdev_open,
|
||||
.release = idetape_chrdev_release,
|
||||
.llseek = noop_llseek,
|
||||
|
Reference in New Issue
Block a user