Fnic: Improper resue of exchange Ids
authorHiral Shah <hishah@cisco.com>
Mon, 10 Nov 2014 20:54:34 +0000 (12:54 -0800)
committerChristoph Hellwig <hch@lst.de>
Thu, 20 Nov 2014 08:10:39 +0000 (09:10 +0100)
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>
drivers/scsi/fnic/fnic.h
drivers/scsi/fnic/fnic_scsi.c

index dbc69ad2d1c49bbcfeccd34f39d0468f2b1edd75..5336e8d21704fd8aac15d364297086741c1d7ade 100644 (file)
@@ -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: "
 
index 10d5c6bbc9e77c5cbf3e577c92bb42fa7994d312..29d23a3c068679aaf7a61188c9e4e3a818f7da00 100644 (file)
@@ -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;