summaryrefslogtreecommitdiffstats
path: root/drivers/firmware/iscsi_ibft.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2011-06-24 22:11:53 +0200
committerJames Bottomley <JBottomley@Parallels.com>2011-06-29 23:43:06 +0200
commitf457a46f179df41b0f6d80dee33b6e629945f276 (patch)
treeacbeac8630b898610fe71295f11cbc71f956b8ba /drivers/firmware/iscsi_ibft.c
parent[SCSI] iscsi_boot_sysfs: have this module check for null on destruction (diff)
downloadlinux-f457a46f179df41b0f6d80dee33b6e629945f276.tar.xz
linux-f457a46f179df41b0f6d80dee33b6e629945f276.zip
[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 'drivers/firmware/iscsi_ibft.c')
-rw-r--r--drivers/firmware/iscsi_ibft.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index ce33f4626957..c811cb107904 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -566,6 +566,11 @@ static mode_t __init ibft_check_initiator_for(void *data, int type)
return rc;
}
+static void ibft_kobj_release(void *data)
+{
+ kfree(data);
+}
+
/*
* Helper function for ibft_register_kobjects.
*/
@@ -595,7 +600,8 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header,
boot_kobj = iscsi_boot_create_initiator(boot_kset, hdr->index,
ibft_kobj,
ibft_attr_show_initiator,
- ibft_check_initiator_for);
+ ibft_check_initiator_for,
+ ibft_kobj_release);
if (!boot_kobj) {
rc = -ENOMEM;
goto free_ibft_obj;
@@ -610,7 +616,8 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header,
boot_kobj = iscsi_boot_create_ethernet(boot_kset, hdr->index,
ibft_kobj,
ibft_attr_show_nic,
- ibft_check_nic_for);
+ ibft_check_nic_for,
+ ibft_kobj_release);
if (!boot_kobj) {
rc = -ENOMEM;
goto free_ibft_obj;
@@ -625,7 +632,8 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header,
boot_kobj = iscsi_boot_create_target(boot_kset, hdr->index,
ibft_kobj,
ibft_attr_show_target,
- ibft_check_tgt_for);
+ ibft_check_tgt_for,
+ ibft_kobj_release);
if (!boot_kobj) {
rc = -ENOMEM;
goto free_ibft_obj;