aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_scsi.c
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2009-04-17 15:08:15 +0200
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-04-27 10:07:37 -0500
commit70932935b61ee3dcc5a419ec4c367feb2ff808e4 (patch)
tree67e0925b8a44b3e163e4da36ecff299ba9e842bf /drivers/s390/scsi/zfcp_scsi.c
parent3869bb6e73f5f55ce16b13025726b0bfdf1f4aae (diff)
downloadkernel_samsung_smdk4412-70932935b61ee3dcc5a419ec4c367feb2ff808e4.zip
kernel_samsung_smdk4412-70932935b61ee3dcc5a419ec4c367feb2ff808e4.tar.gz
kernel_samsung_smdk4412-70932935b61ee3dcc5a419ec4c367feb2ff808e4.tar.bz2
[SCSI] zfcp: Fix oops when port disappears
The zfcp_port might have been removed, while the FC fast_io_fail timer is still running and could trigger the terminate_rport_io callback. Set the pointer to the zfcp_port to NULL and check accordingly before using it. Reviewed-by: Martin Petermann <martin@linux.vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_scsi.c')
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index e7d0652..e8fbeae 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -486,10 +486,12 @@ static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
*/
static void zfcp_scsi_dev_loss_tmo_callbk(struct fc_rport *rport)
{
- struct zfcp_port *port = rport->dd_data;
+ struct zfcp_port *port;
write_lock_irq(&zfcp_data.config_lock);
- port->rport = NULL;
+ port = rport->dd_data;
+ if (port)
+ port->rport = NULL;
write_unlock_irq(&zfcp_data.config_lock);
}
@@ -503,9 +505,18 @@ static void zfcp_scsi_dev_loss_tmo_callbk(struct fc_rport *rport)
*/
static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
{
- struct zfcp_port *port = rport->dd_data;
+ struct zfcp_port *port;
+
+ write_lock_irq(&zfcp_data.config_lock);
+ port = rport->dd_data;
+ if (port)
+ zfcp_port_get(port);
+ write_unlock_irq(&zfcp_data.config_lock);
- zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
+ if (port) {
+ zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
+ zfcp_port_put(port);
+ }
}
static void zfcp_scsi_rport_register(struct zfcp_port *port)
@@ -534,8 +545,10 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port)
static void zfcp_scsi_rport_block(struct zfcp_port *port)
{
- if (port->rport)
- fc_remote_port_delete(port->rport);
+ struct fc_rport *rport = port->rport;
+
+ if (rport)
+ fc_remote_port_delete(rport);
}
void zfcp_scsi_schedule_rport_register(struct zfcp_port *port)