summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Wilck <mwilck@suse.com>2021-01-11 15:25:41 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-02-07 14:48:37 +0100
commit2b27b3f8e555379117d4d4f047017d33972907b6 (patch)
treed8b1da0d9bce88e951cbed58105413833aab7dc9
parent3b9aacf27e06fee5f7b2ea3c2e0e9702767576e9 (diff)
downloadlinux-stable-2b27b3f8e555379117d4d4f047017d33972907b6.tar.gz
linux-stable-2b27b3f8e555379117d4d4f047017d33972907b6.tar.bz2
linux-stable-2b27b3f8e555379117d4d4f047017d33972907b6.zip
scsi: scsi_transport_srp: Don't block target in failfast state
[ Upstream commit 72eeb7c7151302ef007f1acd018cbf6f30e50321 ] If the port is in SRP_RPORT_FAIL_FAST state when srp_reconnect_rport() is entered, a transition to SDEV_BLOCK would be illegal, and a kernel WARNING would be triggered. Skip scsi_target_block() in this case. Link: https://lore.kernel.org/r/20210111142541.21534-1-mwilck@suse.com Reviewed-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Martin Wilck <mwilck@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/scsi/scsi_transport_srp.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c
index 4e46fdb2d7c9..2aaf1b710398 100644
--- a/drivers/scsi/scsi_transport_srp.c
+++ b/drivers/scsi/scsi_transport_srp.c
@@ -555,7 +555,14 @@ int srp_reconnect_rport(struct srp_rport *rport)
res = mutex_lock_interruptible(&rport->mutex);
if (res)
goto out;
- scsi_target_block(&shost->shost_gendev);
+ if (rport->state != SRP_RPORT_FAIL_FAST)
+ /*
+ * sdev state must be SDEV_TRANSPORT_OFFLINE, transition
+ * to SDEV_BLOCK is illegal. Calling scsi_target_unblock()
+ * later is ok though, scsi_internal_device_unblock_nowait()
+ * treats SDEV_TRANSPORT_OFFLINE like SDEV_BLOCK.
+ */
+ scsi_target_block(&shost->shost_gendev);
res = rport->state != SRP_RPORT_LOST ? i->f->reconnect(rport) : -ENODEV;
pr_debug("%s (state %d): transport.reconnect() returned %d\n",
dev_name(&shost->shost_gendev), rport->state, res);