compat_ioctl: scsi: move ioctl handling into drivers

Each driver calling scsi_ioctl() gets an equivalent compat_ioctl()
handler that implements the same commands by calling scsi_compat_ioctl().

The scsi_cmd_ioctl() and scsi_cmd_blk_ioctl() functions are compatible
at this point, so any driver that calls those can do so for both native
and compat mode, with the argument passed through compat_ptr().

With this, we can remove the entries from fs/compat_ioctl.c.  The new
code is larger, but should be easier to maintain and keep updated with
newly added commands.

Reviewed-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann
2019-03-15 17:39:44 +01:00
부모 c103d6ee69
커밋 d320a9551e
7개의 변경된 파일142개의 추가작업 그리고 204개의 파일을 삭제

파일 보기

@@ -3501,7 +3501,7 @@ out:
/* The ioctl command */
static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
static long st_ioctl_common(struct file *file, unsigned int cmd_in, void __user *p)
{
int i, cmd_nr, cmd_type, bt;
int retval = 0;
@@ -3509,7 +3509,6 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
struct scsi_tape *STp = file->private_data;
struct st_modedef *STm;
struct st_partstat *STps;
void __user *p = (void __user *)arg;
if (mutex_lock_interruptible(&STp->lock))
return -ERESTARTSYS;
@@ -3824,9 +3823,19 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
}
mutex_unlock(&STp->lock);
switch (cmd_in) {
case SCSI_IOCTL_STOP_UNIT:
/* unload */
retval = scsi_ioctl(STp->device, cmd_in, p);
if (!retval) {
STp->rew_at_close = 0;
STp->ready = ST_NO_TAPE;
}
return retval;
case SCSI_IOCTL_GET_IDLUN:
case SCSI_IOCTL_GET_BUS_NUMBER:
break;
default:
if ((cmd_in == SG_IO ||
cmd_in == SCSI_IOCTL_SEND_COMMAND ||
@@ -3840,42 +3849,46 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
return i;
break;
}
retval = scsi_ioctl(STp->device, cmd_in, p);
if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
STp->rew_at_close = 0;
STp->ready = ST_NO_TAPE;
}
return retval;
return -ENOTTY;
out:
mutex_unlock(&STp->lock);
return retval;
}
static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
{
void __user *p = (void __user *)arg;
struct scsi_tape *STp = file->private_data;
int ret;
ret = st_ioctl_common(file, cmd_in, p);
if (ret != -ENOTTY)
return ret;
return scsi_ioctl(STp->device, cmd_in, p);
}
#ifdef CONFIG_COMPAT
static long st_compat_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
{
void __user *p = compat_ptr(arg);
struct scsi_tape *STp = file->private_data;
struct scsi_device *sdev = STp->device;
int ret = -ENOIOCTLCMD;
int ret;
/* argument conversion is handled using put_user_mtpos/put_user_mtget */
switch (cmd_in) {
case MTIOCTOP:
return st_ioctl(file, MTIOCTOP, (unsigned long)p);
case MTIOCPOS32:
return st_ioctl(file, MTIOCPOS, (unsigned long)p);
return st_ioctl_common(file, MTIOCPOS, p);
case MTIOCGET32:
return st_ioctl(file, MTIOCGET, (unsigned long)p);
return st_ioctl_common(file, MTIOCGET, p);
}
if (sdev->host->hostt->compat_ioctl) {
ret = st_ioctl_common(file, cmd_in, p);
if (ret != -ENOTTY)
return ret;
ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
}
return ret;
return scsi_compat_ioctl(STp->device, cmd_in, p);
}
#endif