diff options
author | Steffen Maier <maier@linux.vnet.ibm.com> | 2017-07-25 16:14:24 +0200 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-08-07 14:04:02 -0400 |
commit | 67b465250e045446ad6fc59ab3e02beb40435878 (patch) | |
tree | e6e9a24800a7b9f8849380ead98880e96a4d8233 | |
parent | 49b3d5f67c1e5d661b64b77ec37bd9f57cbf720d (diff) |
scsi: fc: start decoupling fc_block_scsi_eh from scsi_cmnd
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>
-rw-r--r-- | drivers/scsi/scsi_transport_fc.c | 31 | ||||
-rw-r--r-- | include/scsi/scsi_transport_fc.h | 1 |
2 files changed, 27 insertions, 5 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 892fbd9800d9..1118aa5f88cd 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -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); /** diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index e308cd59e556..e8644eea9fe5 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -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); |