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:
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user