libfc: Update rport reference counting

Originally libfc would just be initializing the refcount to '1', and
using the disc_mutex to synchronize if and when the final put should be
happening.  This has a race condition as the mutex might be delayed,
causing other threads to access an invalid structure.  This patch
updates the rport reference counting to increase the reference every
time 'rport_lookup' is called, and decreases the reference
correspondingly.  This removes the need to hold 'disc_mutex' when
removing the structure, and avoids the above race condition.

Signed-off-by: Hannes Reinecke <hare@suse.com>
Acked-by: Vasu Dev <vasu.dev@intel.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Цей коміт міститься в:
Hannes Reinecke
2016-05-24 08:11:58 +02:00
зафіксовано Martin K. Petersen
джерело 7e1ee4412c
коміт baa6719f90
3 змінених файлів з 38 додано та 37 видалено

Переглянути файл

@@ -2090,7 +2090,7 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
struct fc_rport *rport;
struct fc_rport_priv *rdata;
int rc = -EINVAL;
u32 did;
u32 did, tov;
job->reply->reply_payload_rcv_len = 0;
if (rsp)
@@ -2121,15 +2121,20 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
case FC_BSG_HST_CT:
did = ntoh24(job->request->rqst_data.h_ct.port_id);
if (did == FC_FID_DIR_SERV)
if (did == FC_FID_DIR_SERV) {
rdata = lport->dns_rdata;
else
if (!rdata)
break;
tov = rdata->e_d_tov;
} else {
rdata = lport->tt.rport_lookup(lport, did);
if (!rdata)
break;
tov = rdata->e_d_tov;
kref_put(&rdata->kref, lport->tt.rport_destroy);
}
if (!rdata)
break;
rc = fc_lport_ct_request(job, lport, did, rdata->e_d_tov);
rc = fc_lport_ct_request(job, lport, did, tov);
break;
case FC_BSG_HST_ELS_NOLOGIN: