Commit d27418aa authored by David Jeffery's avatar David Jeffery Committed by Martin K. Petersen
Browse files

scsi: st: Skip buffer flush for information ioctls



With commit 9604eea5 ("scsi: st: Add third party poweron reset
handling") some customer tape applications fail from being unable to
complete ioctls to verify ID information for the device when there has
been any type of reset event to their tape devices.

The st driver currently will fail all standard SCSI ioctls if a call to
flush_buffer() fails in st_ioctl(). This causes ioctls which otherwise
have no effect on tape state to succeed or fail based on events
unrelated to the requested ioctl.

This makes SCSI information ioctls unreliable after a reset even if no
buffering is in use. With a reset setting the pos_unknown field,
flush_buffer() will report failure and fail all ioctls. So any
application expecting to use ioctls to check the identify the device
will be unable to do so in such a state.

For SCSI information ioctls, avoid the need for a buffer flush and allow
the ioctls to execute regardless of buffer state.

Signed-off-by: default avatarDavid Jeffery <djeffery@redhat.com>
Tested-by: default avatarLaurence Oberman <loberman@redhat.com>
Acked-by: default avatarKai Mäkisara <kai.makisara@kolumbus.fi>
Reviewed-by: default avatarJohn Meneghini <jmeneghi@redhat.com>
Tested-by: default avatarJohn Meneghini <jmeneghi@redhat.com>
Link: https://patch.msgid.link/20251104154709.6436-2-djeffery@redhat.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent b37d70c0
Loading
Loading
Loading
Loading
+22 −18
Original line number Diff line number Diff line
@@ -3542,6 +3542,20 @@ static long st_common_ioctl(struct scsi_tape *STp, struct st_modedef *STm,
		goto out;
	}

	switch (cmd_in) {
	case SCSI_IOCTL_GET_IDLUN:
	case SCSI_IOCTL_GET_BUS_NUMBER:
	case SCSI_IOCTL_GET_PCI:
		break;
	case SG_IO:
	case SCSI_IOCTL_SEND_COMMAND:
	case CDROM_SEND_PACKET:
		if (!capable(CAP_SYS_RAWIO)) {
			retval = -EPERM;
			goto out;
		}
		fallthrough;
	default:
		if ((i = flush_buffer(STp, 0)) < 0) {
			retval = i;
			goto out;
@@ -3554,18 +3568,8 @@ static long st_common_ioctl(struct scsi_tape *STp, struct st_modedef *STm,
				}
			}
		}
	mutex_unlock(&STp->lock);

	switch (cmd_in) {
	case SG_IO:
	case SCSI_IOCTL_SEND_COMMAND:
	case CDROM_SEND_PACKET:
		if (!capable(CAP_SYS_RAWIO))
			return -EPERM;
		break;
	default:
		break;
	}
	mutex_unlock(&STp->lock);

	retval = scsi_ioctl(STp->device, file->f_mode & FMODE_WRITE,
			    cmd_in, (void __user *)arg);