[SCSI] libsas: fix domain_device leak

Arrange for the deallocation of a struct domain_device object when it no
longer has:
1/ any children
2/ references by any scsi_targets
3/ references by a lldd

The comment about domain_device lifetime in
Documentation/scsi/libsas.txt is stale as it appears mainline never had
a version of a struct domain_device that was registered as a kobject.
We now manage domain_device reference counts on behalf of external
agents.

Reviewed-by: Jack Wang <jack_wang@usish.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
Dan Williams
2011-11-17 17:59:47 -08:00
committed by James Bottomley
parent 6f4e75a49f
commit 735f7d2fed
6 changed files with 56 additions and 41 deletions

View File

@@ -737,16 +737,10 @@ struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy)
return found_dev;
}
static inline struct domain_device *sas_find_target(struct scsi_target *starget)
{
struct sas_rphy *rphy = dev_to_rphy(starget->dev.parent);
return sas_find_dev_by_rphy(rphy);
}
int sas_target_alloc(struct scsi_target *starget)
{
struct domain_device *found_dev = sas_find_target(starget);
struct sas_rphy *rphy = dev_to_rphy(starget->dev.parent);
struct domain_device *found_dev = sas_find_dev_by_rphy(rphy);
int res;
if (!found_dev)
@@ -758,6 +752,7 @@ int sas_target_alloc(struct scsi_target *starget)
return res;
}
kref_get(&found_dev->kref);
starget->hostdata = found_dev;
return 0;
}
@@ -1047,7 +1042,7 @@ int sas_slave_alloc(struct scsi_device *scsi_dev)
void sas_target_destroy(struct scsi_target *starget)
{
struct domain_device *found_dev = sas_find_target(starget);
struct domain_device *found_dev = starget->hostdata;
if (!found_dev)
return;
@@ -1055,7 +1050,8 @@ void sas_target_destroy(struct scsi_target *starget)
if (dev_is_sata(found_dev))
ata_sas_port_destroy(found_dev->sata_dev.ap);
return;
starget->hostdata = NULL;
sas_put_device(found_dev);
}
static void sas_parse_addr(u8 *sas_addr, const char *p)