diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-03 16:18:51 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-03 16:18:51 -0800 |
commit | a0a28644c1cf191e514dd64bf438e69c178b8440 (patch) | |
tree | 4a5140d2f13692f91ca012d0eab146e9f366ce95 | |
parent | a49e6f584e29785f9e5eb8dd31435746818dd5c4 (diff) | |
parent | 6f3e71c0c3f2479e05682e2e563b75decab36591 (diff) | |
download | linux-a0a28644c1cf191e514dd64bf438e69c178b8440.tar.gz linux-a0a28644c1cf191e514dd64bf438e69c178b8440.tar.bz2 linux-a0a28644c1cf191e514dd64bf438e69c178b8440.zip |
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fix from James Bottomley:
"A single fix this time: a fix for a virtqueue removal bug which only
appears to affect S390, but which results in the queue hanging forever
thus causing the machine to fail shutdown"
* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: virtio_scsi: Reject commands when virtqueue is broken
-rw-r--r-- | drivers/scsi/virtio_scsi.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index ec91bd07f00a..c680d7641311 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -534,7 +534,9 @@ static int virtscsi_queuecommand(struct virtio_scsi *vscsi, { struct Scsi_Host *shost = virtio_scsi_host(vscsi->vdev); struct virtio_scsi_cmd *cmd = scsi_cmd_priv(sc); + unsigned long flags; int req_size; + int ret; BUG_ON(scsi_sg_count(sc) > shost->sg_tablesize); @@ -562,8 +564,15 @@ static int virtscsi_queuecommand(struct virtio_scsi *vscsi, req_size = sizeof(cmd->req.cmd); } - if (virtscsi_kick_cmd(req_vq, cmd, req_size, sizeof(cmd->resp.cmd)) != 0) + ret = virtscsi_kick_cmd(req_vq, cmd, req_size, sizeof(cmd->resp.cmd)); + if (ret == -EIO) { + cmd->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET; + spin_lock_irqsave(&req_vq->vq_lock, flags); + virtscsi_complete_cmd(vscsi, cmd); + spin_unlock_irqrestore(&req_vq->vq_lock, flags); + } else if (ret != 0) { return SCSI_MLQUEUE_HOST_BUSY; + } return 0; } |