Commit 2e27f576 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Martin K. Petersen
Browse files

scsi: scsi_ioctl: Call scsi_cmd_ioctl() from scsi_ioctl()

Ensure SCSI ULD only has to call a single ioctl helper.  This also adds a
bunch of missing ioctls to the ch driver, and removes the need for a
duplicate implementation of SCSI_IOCTL_SEND_COMMAND command.

Link: https://lore.kernel.org/r/20210724072033.1284840-12-hch@lst.de


Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 4f07bfc5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -877,7 +877,7 @@ static long ch_ioctl(struct file *file,
	}

	default:
		return scsi_ioctl(ch->device, cmd, argp);
		return scsi_ioctl(ch->device, NULL, file->f_mode, cmd, argp);

	}
}
+12 −5
Original line number Diff line number Diff line
@@ -192,6 +192,8 @@ static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg)
/**
 * scsi_ioctl - Dispatch ioctl to scsi device
 * @sdev: scsi device receiving ioctl
 * @disk: disk receiving the ioctl
 * @mode: mode the block/char device is opened with
 * @cmd: which ioctl is it
 * @arg: data associated with ioctl
 *
@@ -199,10 +201,13 @@ static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg)
 * does not take a major/minor number as the dev field.  Rather, it takes
 * a pointer to a &struct scsi_device.
 */
int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode,
		int cmd, void __user *arg)
{
	struct request_queue *q = sdev->request_queue;
	char scsi_cmd[MAX_COMMAND_SIZE];
	struct scsi_sense_hdr sense_hdr;
	int error;

	/* Check for deprecated ioctls ... all the ioctls which don't
	 * follow the new unique numbering scheme are deprecated */
@@ -220,6 +225,12 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
		break;
	}

	if (cmd != SCSI_IOCTL_GET_IDLUN && cmd != SCSI_IOCTL_GET_BUS_NUMBER) {
		error = scsi_cmd_ioctl(q, disk, mode, cmd, arg);
		if (error != -ENOTTY)
			return error;
	}

	switch (cmd) {
	case SCSI_IOCTL_GET_IDLUN: {
		struct scsi_idlun v = {
@@ -237,10 +248,6 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
		return put_user(sdev->host->host_no, (int __user *)arg);
	case SCSI_IOCTL_PROBE_HOST:
		return ioctl_probe(sdev->host, arg);
	case SCSI_IOCTL_SEND_COMMAND:
		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
			return -EACCES;
		return sg_scsi_ioctl(sdev->request_queue, NULL, 0, arg);
	case SCSI_IOCTL_DOORLOCK:
		return scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
	case SCSI_IOCTL_DOORUNLOCK:
+1 −17
Original line number Diff line number Diff line
@@ -1571,23 +1571,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,

	if (is_sed_ioctl(cmd))
		return sed_ioctl(sdkp->opal_dev, cmd, p);

	/*
	 * Send SCSI addressing ioctls directly to mid level, send other
	 * ioctls to block level and then onto mid level if they can't be
	 * resolved.
	 */
	switch (cmd) {
	case SCSI_IOCTL_GET_IDLUN:
	case SCSI_IOCTL_GET_BUS_NUMBER:
		break;
	default:
		error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p);
		if (error != -ENOTTY)
			return error;
	}

	return scsi_ioctl(sdp, cmd, p);
	return scsi_ioctl(sdp, disk, mode, cmd, p);
}

static void set_media_not_present(struct scsi_disk *sdkp)
+1 −1
Original line number Diff line number Diff line
@@ -1165,7 +1165,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
	ret = sg_ioctl_common(filp, sdp, sfp, cmd_in, p);
	if (ret != -ENOIOCTLCMD)
		return ret;
	return scsi_ioctl(sdp->device, cmd_in, p);
	return scsi_ioctl(sdp->device, NULL, filp->f_mode, cmd_in, p);
}

static __poll_t
+2 −14
Original line number Diff line number Diff line
@@ -574,24 +574,12 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,

	scsi_autopm_get_device(sdev);

	/*
	 * Send SCSI addressing ioctls directly to mid level, send other
	 * ioctls to cdrom/block level.
	 */
	switch (cmd) {
	case SCSI_IOCTL_GET_IDLUN:
	case SCSI_IOCTL_GET_BUS_NUMBER:
		break;
	default:
		ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
		if (ret != -ENOTTY)
			goto put;
	if (ret != CDROMCLOSETRAY && ret != CDROMEJECT) {
		ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg);
		if (ret != -ENOSYS)
			goto put;
	}

	ret = scsi_ioctl(sdev, cmd, argp);
	ret = scsi_ioctl(sdev, disk, mode, cmd, argp);

put:
	scsi_autopm_put_device(sdev);
Loading