diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-11-18 05:59:47 +0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 23:37:47 +0400 |
commit | 735f7d2fedf57380214221be7bed7f62d729e262 (patch) | |
tree | 067db49c22dcbdf695a6517a6c8664b6bb2c2d32 /drivers/scsi/libsas/sas_expander.c | |
parent | 6f4e75a49fd07d707995865493b9f452302ae36b (diff) | |
download | linux-735f7d2fedf57380214221be7bed7f62d729e262.tar.xz |
[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>
Diffstat (limited to 'drivers/scsi/libsas/sas_expander.c')
-rw-r--r-- | drivers/scsi/libsas/sas_expander.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 1b831c55ec6e..15d2239a378b 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -657,10 +657,11 @@ static struct domain_device *sas_ex_discover_end_dev( if (phy->attached_sata_host || phy->attached_sata_ps) return NULL; - child = kzalloc(sizeof(*child), GFP_KERNEL); + child = sas_alloc_device(); if (!child) return NULL; + kref_get(&parent->kref); child->parent = parent; child->port = parent->port; child->iproto = phy->attached_iproto; @@ -762,7 +763,7 @@ static struct domain_device *sas_ex_discover_end_dev( sas_port_delete(phy->port); out_err: phy->port = NULL; - kfree(child); + sas_put_device(child); return NULL; } @@ -809,7 +810,7 @@ static struct domain_device *sas_ex_discover_expander( phy->attached_phy_id); return NULL; } - child = kzalloc(sizeof(*child), GFP_KERNEL); + child = sas_alloc_device(); if (!child) return NULL; @@ -835,6 +836,7 @@ static struct domain_device *sas_ex_discover_expander( child->rphy = rphy; edev = rphy_to_expander_device(rphy); child->dev_type = phy->attached_dev_type; + kref_get(&parent->kref); child->parent = parent; child->port = port; child->iproto = phy->attached_iproto; @@ -858,7 +860,7 @@ static struct domain_device *sas_ex_discover_expander( spin_lock_irq(&parent->port->dev_list_lock); list_del(&child->dev_list_node); spin_unlock_irq(&parent->port->dev_list_lock); - kfree(child); + sas_put_device(child); return NULL; } list_add_tail(&child->siblings, &parent->ex_dev.children); |