Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70932935 authored by Christof Schmitt's avatar Christof Schmitt Committed by James Bottomley
Browse files

[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: default avatarMartin Petermann <martin@linux.vnet.ibm.com>
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 3869bb6e
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -671,8 +671,7 @@ void zfcp_port_dequeue(struct zfcp_port *port)
	list_del(&port->list);
	write_unlock_irq(&zfcp_data.config_lock);
	if (port->rport)
		fc_remote_port_delete(port->rport);
	port->rport = NULL;
		port->rport->dd_data = NULL;
	zfcp_adapter_put(port->adapter);
	sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
	device_unregister(&port->sysfs_device);
+4 −0
Original line number Diff line number Diff line
@@ -172,12 +172,16 @@ static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, char *id,
					 struct fsf_link_down_info *link_down)
{
	struct zfcp_adapter *adapter = req->adapter;
	unsigned long flags;

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

	atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);

	read_lock_irqsave(&zfcp_data.config_lock, flags);
	zfcp_scsi_schedule_rports_block(adapter);
	read_unlock_irqrestore(&zfcp_data.config_lock, flags);

	if (!link_down)
		goto out;
+19 −6
Original line number Diff line number Diff line
@@ -486,9 +486,11 @@ 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->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);

	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)