mirror of
https://github.com/torvalds/linux.git
synced 2024-11-01 01:31:44 +00:00
[SCSI] ibmvfc: Target refcounting fixes
Fix up some refcounting on the ibmvfc drivers internal target struct when accessed through some sysfs attributes. Signed-off-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
0ae808e02e
commit
b3c10489cb
@ -854,39 +854,41 @@ static void ibmvfc_retry_host_init(struct ibmvfc_host *vhost)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __ibmvfc_find_target - Find the specified scsi_target (no locking)
|
* __ibmvfc_get_target - Find the specified scsi_target (no locking)
|
||||||
* @starget: scsi target struct
|
* @starget: scsi target struct
|
||||||
*
|
*
|
||||||
* Return value:
|
* Return value:
|
||||||
* ibmvfc_target struct / NULL if not found
|
* ibmvfc_target struct / NULL if not found
|
||||||
**/
|
**/
|
||||||
static struct ibmvfc_target *__ibmvfc_find_target(struct scsi_target *starget)
|
static struct ibmvfc_target *__ibmvfc_get_target(struct scsi_target *starget)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||||
struct ibmvfc_host *vhost = shost_priv(shost);
|
struct ibmvfc_host *vhost = shost_priv(shost);
|
||||||
struct ibmvfc_target *tgt;
|
struct ibmvfc_target *tgt;
|
||||||
|
|
||||||
list_for_each_entry(tgt, &vhost->targets, queue)
|
list_for_each_entry(tgt, &vhost->targets, queue)
|
||||||
if (tgt->target_id == starget->id)
|
if (tgt->target_id == starget->id) {
|
||||||
|
kref_get(&tgt->kref);
|
||||||
return tgt;
|
return tgt;
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ibmvfc_find_target - Find the specified scsi_target
|
* ibmvfc_get_target - Find the specified scsi_target
|
||||||
* @starget: scsi target struct
|
* @starget: scsi target struct
|
||||||
*
|
*
|
||||||
* Return value:
|
* Return value:
|
||||||
* ibmvfc_target struct / NULL if not found
|
* ibmvfc_target struct / NULL if not found
|
||||||
**/
|
**/
|
||||||
static struct ibmvfc_target *ibmvfc_find_target(struct scsi_target *starget)
|
static struct ibmvfc_target *ibmvfc_get_target(struct scsi_target *starget)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||||
struct ibmvfc_target *tgt;
|
struct ibmvfc_target *tgt;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(shost->host_lock, flags);
|
spin_lock_irqsave(shost->host_lock, flags);
|
||||||
tgt = __ibmvfc_find_target(starget);
|
tgt = __ibmvfc_get_target(starget);
|
||||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||||
return tgt;
|
return tgt;
|
||||||
}
|
}
|
||||||
@ -990,6 +992,17 @@ static void ibmvfc_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
|
|||||||
rport->dev_loss_tmo = 1;
|
rport->dev_loss_tmo = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ibmvfc_release_tgt - Free memory allocated for a target
|
||||||
|
* @kref: kref struct
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
static void ibmvfc_release_tgt(struct kref *kref)
|
||||||
|
{
|
||||||
|
struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref);
|
||||||
|
kfree(tgt);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ibmvfc_get_starget_node_name - Get SCSI target's node name
|
* ibmvfc_get_starget_node_name - Get SCSI target's node name
|
||||||
* @starget: scsi target struct
|
* @starget: scsi target struct
|
||||||
@ -999,8 +1012,10 @@ static void ibmvfc_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
|
|||||||
**/
|
**/
|
||||||
static void ibmvfc_get_starget_node_name(struct scsi_target *starget)
|
static void ibmvfc_get_starget_node_name(struct scsi_target *starget)
|
||||||
{
|
{
|
||||||
struct ibmvfc_target *tgt = ibmvfc_find_target(starget);
|
struct ibmvfc_target *tgt = ibmvfc_get_target(starget);
|
||||||
fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0;
|
fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0;
|
||||||
|
if (tgt)
|
||||||
|
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1012,8 +1027,10 @@ static void ibmvfc_get_starget_node_name(struct scsi_target *starget)
|
|||||||
**/
|
**/
|
||||||
static void ibmvfc_get_starget_port_name(struct scsi_target *starget)
|
static void ibmvfc_get_starget_port_name(struct scsi_target *starget)
|
||||||
{
|
{
|
||||||
struct ibmvfc_target *tgt = ibmvfc_find_target(starget);
|
struct ibmvfc_target *tgt = ibmvfc_get_target(starget);
|
||||||
fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0;
|
fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0;
|
||||||
|
if (tgt)
|
||||||
|
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1025,8 +1042,10 @@ static void ibmvfc_get_starget_port_name(struct scsi_target *starget)
|
|||||||
**/
|
**/
|
||||||
static void ibmvfc_get_starget_port_id(struct scsi_target *starget)
|
static void ibmvfc_get_starget_port_id(struct scsi_target *starget)
|
||||||
{
|
{
|
||||||
struct ibmvfc_target *tgt = ibmvfc_find_target(starget);
|
struct ibmvfc_target *tgt = ibmvfc_get_target(starget);
|
||||||
fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1;
|
fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1;
|
||||||
|
if (tgt)
|
||||||
|
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2650,17 +2669,6 @@ static void ibmvfc_retry_tgt_init(struct ibmvfc_target *tgt,
|
|||||||
ibmvfc_init_tgt(tgt, job_step);
|
ibmvfc_init_tgt(tgt, job_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ibmvfc_release_tgt - Free memory allocated for a target
|
|
||||||
* @kref: kref struct
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
static void ibmvfc_release_tgt(struct kref *kref)
|
|
||||||
{
|
|
||||||
struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref);
|
|
||||||
kfree(tgt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ibmvfc_tgt_prli_done - Completion handler for Process Login
|
* ibmvfc_tgt_prli_done - Completion handler for Process Login
|
||||||
* @evt: ibmvfc event struct
|
* @evt: ibmvfc event struct
|
||||||
|
Loading…
Reference in New Issue
Block a user