Skip to content

Commit 5a1b215

Browse files
author
CKI KWF Bot
committed
Merge: scsi: st: Skip buffer flush for information ioctls
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1762 JIRA: https://issues.redhat.com/browse/RHEL-115965 Upstream Status: git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git Depends: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1677 With commit 9604eea ("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: John Meneghini <jmeneghi@redhat.com> Approved-by: bgurney <bgurney@redhat.com> Approved-by: Ewan D. Milne <emilne@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents 833f9a7 + d362be9 commit 5a1b215

File tree

1 file changed

+66
-23
lines changed

1 file changed

+66
-23
lines changed

drivers/scsi/st.c

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3526,8 +3526,64 @@ static int partition_tape(struct scsi_tape *STp, int size)
35263526
out:
35273527
return result;
35283528
}
3529-
35303529

3530+
/*
3531+
* Handles any extra state needed for ioctls which are not st-specific.
3532+
* Called with the scsi_tape lock held, released before return
3533+
*/
3534+
static long st_common_ioctl(struct scsi_tape *STp, struct st_modedef *STm,
3535+
struct file *file, unsigned int cmd_in,
3536+
unsigned long arg)
3537+
{
3538+
int i, retval = 0;
3539+
3540+
if (!STm->defined) {
3541+
retval = -ENXIO;
3542+
goto out;
3543+
}
3544+
3545+
switch (cmd_in) {
3546+
case SCSI_IOCTL_GET_IDLUN:
3547+
case SCSI_IOCTL_GET_BUS_NUMBER:
3548+
case SCSI_IOCTL_GET_PCI:
3549+
break;
3550+
case SG_IO:
3551+
case SCSI_IOCTL_SEND_COMMAND:
3552+
case CDROM_SEND_PACKET:
3553+
if (!capable(CAP_SYS_RAWIO)) {
3554+
retval = -EPERM;
3555+
goto out;
3556+
}
3557+
fallthrough;
3558+
default:
3559+
if ((i = flush_buffer(STp, 0)) < 0) {
3560+
retval = i;
3561+
goto out;
3562+
} else { /* flush_buffer succeeds */
3563+
if (STp->can_partitions) {
3564+
i = switch_partition(STp);
3565+
if (i < 0) {
3566+
retval = i;
3567+
goto out;
3568+
}
3569+
}
3570+
}
3571+
}
3572+
mutex_unlock(&STp->lock);
3573+
3574+
retval = scsi_ioctl(STp->device, file->f_mode & FMODE_WRITE,
3575+
cmd_in, (void __user *)arg);
3576+
if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) {
3577+
/* unload */
3578+
STp->rew_at_close = 0;
3579+
STp->ready = ST_NO_TAPE;
3580+
}
3581+
3582+
return retval;
3583+
out:
3584+
mutex_unlock(&STp->lock);
3585+
return retval;
3586+
}
35313587

35323588
/* The ioctl command */
35333589
static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
@@ -3565,6 +3621,15 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
35653621
if (retval)
35663622
goto out;
35673623

3624+
switch (cmd_in) {
3625+
case MTIOCPOS:
3626+
case MTIOCGET:
3627+
case MTIOCTOP:
3628+
break;
3629+
default:
3630+
return st_common_ioctl(STp, STm, file, cmd_in, arg);
3631+
}
3632+
35683633
cmd_type = _IOC_TYPE(cmd_in);
35693634
cmd_nr = _IOC_NR(cmd_in);
35703635

@@ -3876,29 +3941,7 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
38763941
}
38773942
mt_pos.mt_blkno = blk;
38783943
retval = put_user_mtpos(p, &mt_pos);
3879-
goto out;
3880-
}
3881-
mutex_unlock(&STp->lock);
3882-
3883-
switch (cmd_in) {
3884-
case SG_IO:
3885-
case SCSI_IOCTL_SEND_COMMAND:
3886-
case CDROM_SEND_PACKET:
3887-
if (!capable(CAP_SYS_RAWIO))
3888-
return -EPERM;
3889-
break;
3890-
default:
3891-
break;
38923944
}
3893-
3894-
retval = scsi_ioctl(STp->device, file->f_mode & FMODE_WRITE, cmd_in, p);
3895-
if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) {
3896-
/* unload */
3897-
STp->rew_at_close = 0;
3898-
STp->ready = ST_NO_TAPE;
3899-
}
3900-
return retval;
3901-
39023945
out:
39033946
mutex_unlock(&STp->lock);
39043947
return retval;

0 commit comments

Comments
 (0)