Skip to content

Commit 7093293

Browse files
Christof SchmittJames Bottomley
Christof Schmitt
authored and
James Bottomley
committed
[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>
1 parent 3869bb6 commit 7093293

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

drivers/s390/scsi/zfcp_aux.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,7 @@ void zfcp_port_dequeue(struct zfcp_port *port)
671671
list_del(&port->list);
672672
write_unlock_irq(&zfcp_data.config_lock);
673673
if (port->rport)
674-
fc_remote_port_delete(port->rport);
675-
port->rport = NULL;
674+
port->rport->dd_data = NULL;
676675
zfcp_adapter_put(port->adapter);
677676
sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
678677
device_unregister(&port->sysfs_device);

drivers/s390/scsi/zfcp_fsf.c

+4
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,16 @@ static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, char *id,
172172
struct fsf_link_down_info *link_down)
173173
{
174174
struct zfcp_adapter *adapter = req->adapter;
175+
unsigned long flags;
175176

176177
if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED)
177178
return;
178179

179180
atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
181+
182+
read_lock_irqsave(&zfcp_data.config_lock, flags);
180183
zfcp_scsi_schedule_rports_block(adapter);
184+
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
181185

182186
if (!link_down)
183187
goto out;

drivers/s390/scsi/zfcp_scsi.c

+19-6
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,12 @@ static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
486486
*/
487487
static void zfcp_scsi_dev_loss_tmo_callbk(struct fc_rport *rport)
488488
{
489-
struct zfcp_port *port = rport->dd_data;
489+
struct zfcp_port *port;
490490

491491
write_lock_irq(&zfcp_data.config_lock);
492-
port->rport = NULL;
492+
port = rport->dd_data;
493+
if (port)
494+
port->rport = NULL;
493495
write_unlock_irq(&zfcp_data.config_lock);
494496
}
495497

@@ -503,9 +505,18 @@ static void zfcp_scsi_dev_loss_tmo_callbk(struct fc_rport *rport)
503505
*/
504506
static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
505507
{
506-
struct zfcp_port *port = rport->dd_data;
508+
struct zfcp_port *port;
509+
510+
write_lock_irq(&zfcp_data.config_lock);
511+
port = rport->dd_data;
512+
if (port)
513+
zfcp_port_get(port);
514+
write_unlock_irq(&zfcp_data.config_lock);
507515

508-
zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
516+
if (port) {
517+
zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
518+
zfcp_port_put(port);
519+
}
509520
}
510521

511522
static void zfcp_scsi_rport_register(struct zfcp_port *port)
@@ -534,8 +545,10 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port)
534545

535546
static void zfcp_scsi_rport_block(struct zfcp_port *port)
536547
{
537-
if (port->rport)
538-
fc_remote_port_delete(port->rport);
548+
struct fc_rport *rport = port->rport;
549+
550+
if (rport)
551+
fc_remote_port_delete(rport);
539552
}
540553

541554
void zfcp_scsi_schedule_rport_register(struct zfcp_port *port)

0 commit comments

Comments
 (0)