• Steffen Maier's avatar
    scsi: zfcp: decouple TMFs from scsi_cmnd by using fc_block_rport · 42afc652
    Steffen Maier authored
    Intentionally retrieve the rport by walking SCSI common code objects
    rather than zfcp_sdev->port->rport.
    
    The latter is used for pairing the calls to fc_remote_port_add() and
    fc_remote_port_delete(). [see v2.6.31 commit 379d6bf6 ("[SCSI] zfcp:
    Add port only once to FC transport class")]
    
    zfcp_scsi_rport_register() sets zfcp_port.rport to what
    fc_remote_port_add() returned.
    zfcp_scsi_rport_block() sets zfcp_port.rport = NULL after having called
    fc_remote_port_delete().
    
    Hence, while an rport is blocked (or in any subsequent state due to
    scsi_transport_fc timeouts such as fast_io_fail_tmo or dev_loss_tmo),
    zfcp_port.rport is NULL and cannot serve as argument to fc_block_rport().
    
    During zfcp recovery, a just recovered zfcp_port can have the UNBLOCKED
    status flag, but an async rport unblocking has only started via
    zfcp_scsi_schedule_rport_register() in zfcp_erp_try_rport_unblock()
    [see v4.10 commit 6f2ce1c6 ("scsi: zfcp: fix rport unblock race with
    LUN recovery")] in zfcp_erp_action_cleanup(). Now zfcp_erp_wait() can
    return. This would be sufficient to successfully send a TMF.
    But the rport can still be blocked and zfcp_port.rport can still be NULL
    until zfcp_port.rport_work was scheduled and has actually called
    fc_remote_port_add() and assigned its return value to zfcp_port.rport.
    We need an unblocked rport for a successful scsi_eh TUR.
    
    Similarly, for a zfcp_port which has just lost its UNBLOCKED status flag,
    the return of zfcp_erp_wait() can race with zfcp_port.rport_work queued
    by zfcp_scsi_schedule_rport_block(). Therefore we cannot reliably access
    zfcp_port.rport. However, we'd like to get fc_rport_block()'s opinion on
    when fast_io_fail_tmo triggered. While we might use
    flush_work(&port->rport_work) to sync with the work item, we can simply use
    the other way to get an rport pointer.
    Signed-off-by: default avatarSteffen Maier <maier@linux.ibm.com>
    Reviewed-by: default avatarBenjamin Block <bblock@linux.ibm.com>
    Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
    42afc652
zfcp_scsi.c 22.8 KB