scsi: fc: start decoupling fc_block_scsi_eh from scsi_cmnd
authorSteffen Maier <maier@linux.vnet.ibm.com>
Tue, 25 Jul 2017 14:14:24 +0000 (16:14 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 7 Aug 2017 18:04:02 +0000 (14:04 -0400)
Scsi_cmnd is an unsuitable argument for eh_device_reset_handler(),
eh_target_reset_handler(), and eh_host_reset_handler() which do not have
the scope of one single SCSI command.  These callbacks tend to use
fc_block_scsi_eh() requiring scsi_cmnd.  In order to start decoupling
above eh callbacks from scsi_cmnd, introduce a new variant of the
function called fc_block_rport() taking an fc_rport as argument.
Refactor the old fc_block_scsi_eh() to simply delegate to
fc_block_rport().

Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi_transport_fc.c
include/scsi/scsi_transport_fc.h

index 892fbd9800d986a8dba22efac7ac4803be2c5f17..1118aa5f88cd8bd2432862f1d0e6f2b3d754a427 100644 (file)
@@ -3276,8 +3276,8 @@ fc_scsi_scan_rport(struct work_struct *work)
 }
 
 /**
- * fc_block_scsi_eh - Block SCSI eh thread for blocked fc_rport
- * @cmnd: SCSI command that scsi_eh is trying to recover
+ * fc_block_rport() - Block SCSI eh thread for blocked fc_rport.
+ * @rport: Remote port that scsi_eh is trying to recover.
  *
  * This routine can be called from a FC LLD scsi_eh callback. It
  * blocks the scsi_eh thread until the fc_rport leaves the
@@ -3289,10 +3289,9 @@ fc_scsi_scan_rport(struct work_struct *work)
  *         FAST_IO_FAIL if the fast_io_fail_tmo fired, this should be
  *         passed back to scsi_eh.
  */
-int fc_block_scsi_eh(struct scsi_cmnd *cmnd)
+int fc_block_rport(struct fc_rport *rport)
 {
-       struct Scsi_Host *shost = cmnd->device->host;
-       struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+       struct Scsi_Host *shost = rport_to_shost(rport);
        unsigned long flags;
 
        spin_lock_irqsave(shost->host_lock, flags);
@@ -3309,6 +3308,28 @@ int fc_block_scsi_eh(struct scsi_cmnd *cmnd)
 
        return 0;
 }
+EXPORT_SYMBOL(fc_block_rport);
+
+/**
+ * fc_block_scsi_eh - Block SCSI eh thread for blocked fc_rport
+ * @cmnd: SCSI command that scsi_eh is trying to recover
+ *
+ * This routine can be called from a FC LLD scsi_eh callback. It
+ * blocks the scsi_eh thread until the fc_rport leaves the
+ * FC_PORTSTATE_BLOCKED, or the fast_io_fail_tmo fires. This is
+ * necessary to avoid the scsi_eh failing recovery actions for blocked
+ * rports which would lead to offlined SCSI devices.
+ *
+ * Returns: 0 if the fc_rport left the state FC_PORTSTATE_BLOCKED.
+ *         FAST_IO_FAIL if the fast_io_fail_tmo fired, this should be
+ *         passed back to scsi_eh.
+ */
+int fc_block_scsi_eh(struct scsi_cmnd *cmnd)
+{
+       struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+
+       return fc_block_rport(rport);
+}
 EXPORT_SYMBOL(fc_block_scsi_eh);
 
 /**
index e308cd59e5561944ed12b9f5a94b90957377b285..e8644eea9fe56441d16ba78a8ea50f5b35d86f07 100644 (file)
@@ -804,6 +804,7 @@ void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
 struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
                struct fc_vport_identifiers *);
 int fc_vport_terminate(struct fc_vport *vport);
+int fc_block_rport(struct fc_rport *rport);
 int fc_block_scsi_eh(struct scsi_cmnd *cmnd);
 enum blk_eh_timer_return fc_eh_timed_out(struct scsi_cmnd *scmd);