diff options
Diffstat (limited to 'drivers/scsi/iscsi_boot_sysfs.c')
| -rw-r--r-- | drivers/scsi/iscsi_boot_sysfs.c | 31 | 
1 files changed, 22 insertions, 9 deletions
| diff --git a/drivers/scsi/iscsi_boot_sysfs.c b/drivers/scsi/iscsi_boot_sysfs.c index df6bff7366cf..89700cbca16e 100644 --- a/drivers/scsi/iscsi_boot_sysfs.c +++ b/drivers/scsi/iscsi_boot_sysfs.c @@ -64,7 +64,8 @@ static void iscsi_boot_kobj_release(struct kobject *kobj)  	struct iscsi_boot_kobj *boot_kobj =  			container_of(kobj, struct iscsi_boot_kobj, kobj); -	kfree(boot_kobj->data); +	if (boot_kobj->release) +		boot_kobj->release(boot_kobj->data);  	kfree(boot_kobj);  } @@ -305,7 +306,8 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,  		       struct attribute_group *attr_group,  		       const char *name, int index, void *data,  		       ssize_t (*show) (void *data, int type, char *buf), -		       mode_t (*is_visible) (void *data, int type)) +		       mode_t (*is_visible) (void *data, int type), +		       void (*release) (void *data))  {  	struct iscsi_boot_kobj *boot_kobj; @@ -323,6 +325,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,  	boot_kobj->data = data;  	boot_kobj->show = show;  	boot_kobj->is_visible = is_visible; +	boot_kobj->release = release;  	if (sysfs_create_group(&boot_kobj->kobj, attr_group)) {  		/* @@ -331,7 +334,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,  		 * the boot kobj was not setup and the normal release  		 * path is not being run.  		 */ -		boot_kobj->data = NULL; +		boot_kobj->release = NULL;  		kobject_put(&boot_kobj->kobj);  		return NULL;  	} @@ -357,6 +360,7 @@ static void iscsi_boot_remove_kobj(struct iscsi_boot_kobj *boot_kobj)   * @data: driver specific data for target   * @show: attr show function   * @is_visible: attr visibility function + * @release: release function   *   * Note: The boot sysfs lib will free the data passed in for the caller   * when all refs to the target kobject have been released. @@ -365,10 +369,12 @@ struct iscsi_boot_kobj *  iscsi_boot_create_target(struct iscsi_boot_kset *boot_kset, int index,  			 void *data,  			 ssize_t (*show) (void *data, int type, char *buf), -			 mode_t (*is_visible) (void *data, int type)) +			 mode_t (*is_visible) (void *data, int type), +			 void (*release) (void *data))  {  	return iscsi_boot_create_kobj(boot_kset, &iscsi_boot_target_attr_group, -				      "target%d", index, data, show, is_visible); +				      "target%d", index, data, show, is_visible, +				      release);  }  EXPORT_SYMBOL_GPL(iscsi_boot_create_target); @@ -379,6 +385,7 @@ EXPORT_SYMBOL_GPL(iscsi_boot_create_target);   * @data: driver specific data   * @show: attr show function   * @is_visible: attr visibility function + * @release: release function   *   * Note: The boot sysfs lib will free the data passed in for the caller   * when all refs to the initiator kobject have been released. @@ -387,12 +394,13 @@ struct iscsi_boot_kobj *  iscsi_boot_create_initiator(struct iscsi_boot_kset *boot_kset, int index,  			    void *data,  			    ssize_t (*show) (void *data, int type, char *buf), -			    mode_t (*is_visible) (void *data, int type)) +			    mode_t (*is_visible) (void *data, int type), +			    void (*release) (void *data))  {  	return iscsi_boot_create_kobj(boot_kset,  				      &iscsi_boot_initiator_attr_group,  				      "initiator", index, data, show, -				      is_visible); +				      is_visible, release);  }  EXPORT_SYMBOL_GPL(iscsi_boot_create_initiator); @@ -403,6 +411,7 @@ EXPORT_SYMBOL_GPL(iscsi_boot_create_initiator);   * @data: driver specific data   * @show: attr show function   * @is_visible: attr visibility function + * @release: release function   *   * Note: The boot sysfs lib will free the data passed in for the caller   * when all refs to the ethernet kobject have been released. @@ -411,12 +420,13 @@ struct iscsi_boot_kobj *  iscsi_boot_create_ethernet(struct iscsi_boot_kset *boot_kset, int index,  			   void *data,  			   ssize_t (*show) (void *data, int type, char *buf), -			   mode_t (*is_visible) (void *data, int type)) +			   mode_t (*is_visible) (void *data, int type), +			   void (*release) (void *data))  {  	return iscsi_boot_create_kobj(boot_kset,  				      &iscsi_boot_ethernet_attr_group,  				      "ethernet%d", index, data, show, -				      is_visible); +				      is_visible, release);  }  EXPORT_SYMBOL_GPL(iscsi_boot_create_ethernet); @@ -472,6 +482,9 @@ void iscsi_boot_destroy_kset(struct iscsi_boot_kset *boot_kset)  {  	struct iscsi_boot_kobj *boot_kobj, *tmp_kobj; +	if (!boot_kset) +		return; +  	list_for_each_entry_safe(boot_kobj, tmp_kobj,  				 &boot_kset->kobj_list, list)  		iscsi_boot_remove_kobj(boot_kobj); | 
