diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2011-06-24 16:11:53 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 17:43:06 -0400 |
commit | f457a46f179df41b0f6d80dee33b6e629945f276 (patch) | |
tree | acbeac8630b898610fe71295f11cbc71f956b8ba /include | |
parent | 9d04516310aaef3970c642a54531a52123001178 (diff) |
[SCSI] iscsi_ibft, be2iscsi, iscsi_boot: fix boot kobj data lifetime management
be2iscsi passes the boot functions its phba object which is
allocated in the shost, but iscsi_ibft passes in a object
allocated for each item to display. The problem is that
iscsi_boot_sysfs was managing the lifetime of the object
passed in and doing a kfree on release. This causes a double
free for be2iscsi which frees the shost in its pci_remove.
This patch fixes the problem by adding a release callback
which the drivers can call kfree or a put() type of function
(needed for be2iscsi which will do a get/put on the shost).
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/iscsi_boot_sysfs.h | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/include/linux/iscsi_boot_sysfs.h b/include/linux/iscsi_boot_sysfs.h index f1e6c184f14f..f0a2f8b0aa13 100644 --- a/include/linux/iscsi_boot_sysfs.h +++ b/include/linux/iscsi_boot_sysfs.h | |||
@@ -92,6 +92,13 @@ struct iscsi_boot_kobj { | |||
92 | * properties. | 92 | * properties. |
93 | */ | 93 | */ |
94 | mode_t (*is_visible) (void *data, int type); | 94 | mode_t (*is_visible) (void *data, int type); |
95 | |||
96 | /* | ||
97 | * Driver specific release function. | ||
98 | * | ||
99 | * The function should free the data passed in. | ||
100 | */ | ||
101 | void (*release) (void *data); | ||
95 | }; | 102 | }; |
96 | 103 | ||
97 | struct iscsi_boot_kset { | 104 | struct iscsi_boot_kset { |
@@ -103,18 +110,21 @@ struct iscsi_boot_kobj * | |||
103 | iscsi_boot_create_initiator(struct iscsi_boot_kset *boot_kset, int index, | 110 | iscsi_boot_create_initiator(struct iscsi_boot_kset *boot_kset, int index, |
104 | void *data, | 111 | void *data, |
105 | ssize_t (*show) (void *data, int type, char *buf), | 112 | ssize_t (*show) (void *data, int type, char *buf), |
106 | mode_t (*is_visible) (void *data, int type)); | 113 | mode_t (*is_visible) (void *data, int type), |
114 | void (*release) (void *data)); | ||
107 | 115 | ||
108 | struct iscsi_boot_kobj * | 116 | struct iscsi_boot_kobj * |
109 | iscsi_boot_create_ethernet(struct iscsi_boot_kset *boot_kset, int index, | 117 | iscsi_boot_create_ethernet(struct iscsi_boot_kset *boot_kset, int index, |
110 | void *data, | 118 | void *data, |
111 | ssize_t (*show) (void *data, int type, char *buf), | 119 | ssize_t (*show) (void *data, int type, char *buf), |
112 | mode_t (*is_visible) (void *data, int type)); | 120 | mode_t (*is_visible) (void *data, int type), |
121 | void (*release) (void *data)); | ||
113 | struct iscsi_boot_kobj * | 122 | struct iscsi_boot_kobj * |
114 | iscsi_boot_create_target(struct iscsi_boot_kset *boot_kset, int index, | 123 | iscsi_boot_create_target(struct iscsi_boot_kset *boot_kset, int index, |
115 | void *data, | 124 | void *data, |
116 | ssize_t (*show) (void *data, int type, char *buf), | 125 | ssize_t (*show) (void *data, int type, char *buf), |
117 | mode_t (*is_visible) (void *data, int type)); | 126 | mode_t (*is_visible) (void *data, int type), |
127 | void (*release) (void *data)); | ||
118 | 128 | ||
119 | struct iscsi_boot_kset *iscsi_boot_create_kset(const char *set_name); | 129 | struct iscsi_boot_kset *iscsi_boot_create_kset(const char *set_name); |
120 | struct iscsi_boot_kset *iscsi_boot_create_host_kset(unsigned int hostno); | 130 | struct iscsi_boot_kset *iscsi_boot_create_host_kset(unsigned int hostno); |