summaryrefslogtreecommitdiff
path: root/drivers/scsi/libsas/sas_internal.h
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-11-18 05:59:47 +0400
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 23:37:47 +0400
commit735f7d2fedf57380214221be7bed7f62d729e262 (patch)
tree067db49c22dcbdf695a6517a6c8664b6bb2c2d32 /drivers/scsi/libsas/sas_internal.h
parent6f4e75a49fd07d707995865493b9f452302ae36b (diff)
downloadlinux-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_internal.h')
-rw-r--r--drivers/scsi/libsas/sas_internal.h19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index 14e21b5fb8ba..0d43408196f9 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -76,6 +76,8 @@ struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy);
void sas_hae_reset(struct work_struct *work);
+void sas_free_device(struct kref *kref);
+
#ifdef CONFIG_SCSI_SAS_HOST_SMP
extern int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
struct request *rsp);
@@ -161,4 +163,21 @@ static inline void sas_add_parent_port(struct domain_device *dev, int phy_id)
sas_port_add_phy(ex->parent_port, ex_phy->phy);
}
+static inline struct domain_device *sas_alloc_device(void)
+{
+ struct domain_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+
+ if (dev) {
+ INIT_LIST_HEAD(&dev->siblings);
+ INIT_LIST_HEAD(&dev->dev_list_node);
+ kref_init(&dev->kref);
+ }
+ return dev;
+}
+
+static inline void sas_put_device(struct domain_device *dev)
+{
+ kref_put(&dev->kref, sas_free_device);
+}
+
#endif /* _SAS_INTERNAL_H_ */