From 2f2ac4a0df8c4beee6e4057a69fa973b6040a573 Mon Sep 17 00:00:00 2001 From: Joe Eykholt Date: Fri, 12 Mar 2010 16:07:46 -0800 Subject: [PATCH] [SCSI] libfc: fix oops in point-to-point mode In point-to-point mode, if the PLOGI to the remote port times out, it can get deleted by the remote port module. Since there's no reference by the local port, lport->ptp_data points to a freed rport, and when the local port is reset and tries to logout again, an oops occurs in mutex_lock_nested(). Hold a reference count on the point-to-point rdata. Signed-off-by: Joe Eykholt Signed-off-by: Robert Love Signed-off-by: James Bottomley --- drivers/scsi/libfc/fc_lport.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index d126ecfff704..fe8700f4326a 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -228,9 +228,12 @@ static void fc_lport_ptp_setup(struct fc_lport *lport, u64 remote_wwnn) { mutex_lock(&lport->disc.disc_mutex); - if (lport->ptp_rdata) + if (lport->ptp_rdata) { lport->tt.rport_logoff(lport->ptp_rdata); + kref_put(&lport->ptp_rdata->kref, lport->tt.rport_destroy); + } lport->ptp_rdata = lport->tt.rport_create(lport, remote_fid); + kref_get(&lport->ptp_rdata->kref); lport->ptp_rdata->ids.port_name = remote_wwpn; lport->ptp_rdata->ids.node_name = remote_wwnn; mutex_unlock(&lport->disc.disc_mutex); @@ -947,7 +950,11 @@ static void fc_lport_reset_locked(struct fc_lport *lport) if (lport->dns_rdata) lport->tt.rport_logoff(lport->dns_rdata); - lport->ptp_rdata = NULL; + if (lport->ptp_rdata) { + lport->tt.rport_logoff(lport->ptp_rdata); + kref_put(&lport->ptp_rdata->kref, lport->tt.rport_destroy); + lport->ptp_rdata = NULL; + } lport->tt.disc_stop(lport);