Skip to content

Commit 7eafd13

Browse files
committed
compat_ioctl: add scsi_compat_ioctl
In order to move the compat handling for SCSI ioctl commands out of fs/compat_ioctl.c into the individual drivers, we need a helper function first to match the native ioctl handler called by sd, sr, st, etc. Reviewed-by: Ben Hutchings <[email protected]> Signed-off-by: Arnd Bergmann <[email protected]>
1 parent 9452b1a commit 7eafd13

File tree

2 files changed

+41
-14
lines changed

2 files changed

+41
-14
lines changed

drivers/scsi/scsi_ioctl.c

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -189,17 +189,7 @@ static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg)
189189
}
190190

191191

192-
/**
193-
* scsi_ioctl - Dispatch ioctl to scsi device
194-
* @sdev: scsi device receiving ioctl
195-
* @cmd: which ioctl is it
196-
* @arg: data associated with ioctl
197-
*
198-
* Description: The scsi_ioctl() function differs from most ioctls in that it
199-
* does not take a major/minor number as the dev field. Rather, it takes
200-
* a pointer to a &struct scsi_device.
201-
*/
202-
int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
192+
static int scsi_ioctl_common(struct scsi_device *sdev, int cmd, void __user *arg)
203193
{
204194
char scsi_cmd[MAX_COMMAND_SIZE];
205195
struct scsi_sense_hdr sense_hdr;
@@ -266,14 +256,50 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
266256
return scsi_ioctl_get_pci(sdev, arg);
267257
case SG_SCSI_RESET:
268258
return scsi_ioctl_reset(sdev, arg);
269-
default:
270-
if (sdev->host->hostt->ioctl)
271-
return sdev->host->hostt->ioctl(sdev, cmd, arg);
272259
}
260+
return -ENOIOCTLCMD;
261+
}
262+
263+
/**
264+
* scsi_ioctl - Dispatch ioctl to scsi device
265+
* @sdev: scsi device receiving ioctl
266+
* @cmd: which ioctl is it
267+
* @arg: data associated with ioctl
268+
*
269+
* Description: The scsi_ioctl() function differs from most ioctls in that it
270+
* does not take a major/minor number as the dev field. Rather, it takes
271+
* a pointer to a &struct scsi_device.
272+
*/
273+
int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
274+
{
275+
int ret = scsi_ioctl_common(sdev, cmd, arg);
276+
277+
if (ret != -ENOIOCTLCMD)
278+
return ret;
279+
280+
if (sdev->host->hostt->ioctl)
281+
return sdev->host->hostt->ioctl(sdev, cmd, arg);
282+
273283
return -EINVAL;
274284
}
275285
EXPORT_SYMBOL(scsi_ioctl);
276286

287+
#ifdef CONFIG_COMPAT
288+
int scsi_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
289+
{
290+
int ret = scsi_ioctl_common(sdev, cmd, arg);
291+
292+
if (ret != -ENOIOCTLCMD)
293+
return ret;
294+
295+
if (sdev->host->hostt->compat_ioctl)
296+
return sdev->host->hostt->compat_ioctl(sdev, cmd, arg);
297+
298+
return ret;
299+
}
300+
EXPORT_SYMBOL(scsi_compat_ioctl);
301+
#endif
302+
277303
/*
278304
* We can process a reset even when a device isn't fully operable.
279305
*/

include/scsi/scsi_ioctl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ typedef struct scsi_fctargaddress {
4444
int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev,
4545
int cmd, bool ndelay);
4646
extern int scsi_ioctl(struct scsi_device *, int, void __user *);
47+
extern int scsi_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg);
4748

4849
#endif /* __KERNEL__ */
4950
#endif /* _SCSI_IOCTL_H */

0 commit comments

Comments
 (0)