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 /drivers/firmware | |
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 'drivers/firmware')
-rw-r--r-- | drivers/firmware/iscsi_ibft.c | 14 |
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) | |||
566 | return rc; | 566 | return rc; |
567 | } | 567 | } |
568 | 568 | ||
569 | static void ibft_kobj_release(void *data) | ||
570 | { | ||
571 | kfree(data); | ||
572 | } | ||
573 | |||
569 | /* | 574 | /* |
570 | * Helper function for ibft_register_kobjects. | 575 | * Helper function for ibft_register_kobjects. |
571 | */ | 576 | */ |
@@ -595,7 +600,8 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header, | |||
595 | boot_kobj = iscsi_boot_create_initiator(boot_kset, hdr->index, | 600 | boot_kobj = iscsi_boot_create_initiator(boot_kset, hdr->index, |
596 | ibft_kobj, | 601 | ibft_kobj, |
597 | ibft_attr_show_initiator, | 602 | ibft_attr_show_initiator, |
598 | ibft_check_initiator_for); | 603 | ibft_check_initiator_for, |
604 | ibft_kobj_release); | ||
599 | if (!boot_kobj) { | 605 | if (!boot_kobj) { |
600 | rc = -ENOMEM; | 606 | rc = -ENOMEM; |
601 | goto free_ibft_obj; | 607 | goto free_ibft_obj; |
@@ -610,7 +616,8 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header, | |||
610 | boot_kobj = iscsi_boot_create_ethernet(boot_kset, hdr->index, | 616 | boot_kobj = iscsi_boot_create_ethernet(boot_kset, hdr->index, |
611 | ibft_kobj, | 617 | ibft_kobj, |
612 | ibft_attr_show_nic, | 618 | ibft_attr_show_nic, |
613 | ibft_check_nic_for); | 619 | ibft_check_nic_for, |
620 | ibft_kobj_release); | ||
614 | if (!boot_kobj) { | 621 | if (!boot_kobj) { |
615 | rc = -ENOMEM; | 622 | rc = -ENOMEM; |
616 | goto free_ibft_obj; | 623 | goto free_ibft_obj; |
@@ -625,7 +632,8 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header, | |||
625 | boot_kobj = iscsi_boot_create_target(boot_kset, hdr->index, | 632 | boot_kobj = iscsi_boot_create_target(boot_kset, hdr->index, |
626 | ibft_kobj, | 633 | ibft_kobj, |
627 | ibft_attr_show_target, | 634 | ibft_attr_show_target, |
628 | ibft_check_tgt_for); | 635 | ibft_check_tgt_for, |
636 | ibft_kobj_release); | ||
629 | if (!boot_kobj) { | 637 | if (!boot_kobj) { |
630 | rc = -ENOMEM; | 638 | rc = -ENOMEM; |
631 | goto free_ibft_obj; | 639 | goto free_ibft_obj; |