summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHiral Shah2014-11-10 21:54:34 +0100
committerChristoph Hellwig2014-11-20 09:10:39 +0100
commit35061e21a1d29dc37ab28a50e82bfcf6de81b65d (patch)
tree2a8507354cd0ffb595aac6bd118b76fda9980ca3
parentFnic: Memcopy only mimumum of data or trace buffer (diff)
downloadkernel-qcow2-linux-35061e21a1d29dc37ab28a50e82bfcf6de81b65d.tar.gz
kernel-qcow2-linux-35061e21a1d29dc37ab28a50e82bfcf6de81b65d.tar.xz
kernel-qcow2-linux-35061e21a1d29dc37ab28a50e82bfcf6de81b65d.zip
Fnic: Improper resue of exchange Ids
IOs belonging to an rport are aborted with Internal terminate option when rport goes offline. Any new IO issued to the rport during this time can reuse the terminated exchange which will cause inconsistent state of the exchange between local port and remote port. fc_rport_priv is set to RPORT_ST_DELETE before exchanges are aborted by libfc. Not issuing amy more I/O requests when RPORT_ST_DELETE is set, will avoid inconsistent state of the exchange between local port and remote port. - Increment fnic version from 1.6.0.13 to 1.6.0.14 Signed-off-by: Hiral Shah <hishah@cisco.com> Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com> Signed-off-by: Anil Chintalapati <achintal@cisco.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/scsi/fnic/fnic.h2
-rw-r--r--drivers/scsi/fnic/fnic_scsi.c11
2 files changed, 12 insertions, 1 deletions
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index dbc69ad2d1c4..5336e8d21704 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -39,7 +39,7 @@
#define DRV_NAME "fnic"
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
-#define DRV_VERSION "1.6.0.13"
+#define DRV_VERSION "1.6.0.14"
#define PFX DRV_NAME ": "
#define DFX DRV_NAME "%d: "
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 10d5c6bbc9e7..29d23a3c0686 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -423,6 +423,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
int sg_count = 0;
unsigned long flags;
unsigned long ptr;
+ struct fc_rport_priv *rdata;
if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_IO_BLOCKED)))
return SCSI_MLQUEUE_HOST_BUSY;
@@ -436,6 +437,16 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
return 0;
}
+ rdata = lp->tt.rport_lookup(lp, rport->port_id);
+ if (!rdata || (rdata->rp_state == RPORT_ST_DELETE)) {
+ FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
+ "returning IO as rport is removed\n");
+ atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
+ sc->result = DID_NO_CONNECT;
+ done(sc);
+ return 0;
+ }
+
if (lp->state != LPORT_ST_READY || !(lp->link_up))
return SCSI_MLQUEUE_HOST_BUSY;