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) | |||
64 | struct iscsi_boot_kobj *boot_kobj = | 64 | struct iscsi_boot_kobj *boot_kobj = |
65 | container_of(kobj, struct iscsi_boot_kobj, kobj); | 65 | container_of(kobj, struct iscsi_boot_kobj, kobj); |
66 | 66 | ||
67 | kfree(boot_kobj->data); | 67 | if (boot_kobj->release) |
68 | boot_kobj->release(boot_kobj->data); | ||
68 | kfree(boot_kobj); | 69 | kfree(boot_kobj); |
69 | } | 70 | } |
70 | 71 | ||
@@ -305,7 +306,8 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset, | |||
305 | struct attribute_group *attr_group, | 306 | struct attribute_group *attr_group, |
306 | const char *name, int index, void *data, | 307 | const char *name, int index, void *data, |
307 | ssize_t (*show) (void *data, int type, char *buf), | 308 | ssize_t (*show) (void *data, int type, char *buf), |
308 | mode_t (*is_visible) (void *data, int type)) | 309 | mode_t (*is_visible) (void *data, int type), |
310 | void (*release) (void *data)) | ||
309 | { | 311 | { |
310 | struct iscsi_boot_kobj *boot_kobj; | 312 | struct iscsi_boot_kobj *boot_kobj; |
311 | 313 | ||
@@ -323,6 +325,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset, | |||
323 | boot_kobj->data = data; | 325 | boot_kobj->data = data; |
324 | boot_kobj->show = show; | 326 | boot_kobj->show = show; |
325 | boot_kobj->is_visible = is_visible; | 327 | boot_kobj->is_visible = is_visible; |
328 | boot_kobj->release = release; | ||
326 | 329 | ||
327 | if (sysfs_create_group(&boot_kobj->kobj, attr_group)) { | 330 | if (sysfs_create_group(&boot_kobj->kobj, attr_group)) { |
328 | /* | 331 | /* |
@@ -331,7 +334,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset, | |||
331 | * the boot kobj was not setup and the normal release | 334 | * the boot kobj was not setup and the normal release |
332 | * path is not being run. | 335 | * path is not being run. |
333 | */ | 336 | */ |
334 | boot_kobj->data = NULL; | 337 | boot_kobj->release = NULL; |
335 | kobject_put(&boot_kobj->kobj); | 338 | kobject_put(&boot_kobj->kobj); |
336 | return NULL; | 339 | return NULL; |
337 | } | 340 | } |
@@ -357,6 +360,7 @@ static void iscsi_boot_remove_kobj(struct iscsi_boot_kobj *boot_kobj) | |||
357 | * @data: driver specific data for target | 360 | * @data: driver specific data for target |
358 | * @show: attr show function | 361 | * @show: attr show function |
359 | * @is_visible: attr visibility function | 362 | * @is_visible: attr visibility function |
363 | * @release: release function | ||
360 | * | 364 | * |
361 | * Note: The boot sysfs lib will free the data passed in for the caller | 365 | * Note: The boot sysfs lib will free the data passed in for the caller |
362 | * when all refs to the target kobject have been released. | 366 | * when all refs to the target kobject have been released. |
@@ -365,10 +369,12 @@ struct iscsi_boot_kobj * | |||
365 | iscsi_boot_create_target(struct iscsi_boot_kset *boot_kset, int index, | 369 | iscsi_boot_create_target(struct iscsi_boot_kset *boot_kset, int index, |
366 | void *data, | 370 | void *data, |
367 | ssize_t (*show) (void *data, int type, char *buf), | 371 | ssize_t (*show) (void *data, int type, char *buf), |
368 | mode_t (*is_visible) (void *data, int type)) | 372 | mode_t (*is_visible) (void *data, int type), |
373 | void (*release) (void *data)) | ||
369 | { | 374 | { |
370 | return iscsi_boot_create_kobj(boot_kset, &iscsi_boot_target_attr_group, | 375 | return iscsi_boot_create_kobj(boot_kset, &iscsi_boot_target_attr_group, |
371 | "target%d", index, data, show, is_visible); | 376 | "target%d", index, data, show, is_visible, |
377 | release); | ||
372 | } | 378 | } |
373 | EXPORT_SYMBOL_GPL(iscsi_boot_create_target); | 379 | EXPORT_SYMBOL_GPL(iscsi_boot_create_target); |
374 | 380 | ||
@@ -379,6 +385,7 @@ EXPORT_SYMBOL_GPL(iscsi_boot_create_target); | |||
379 | * @data: driver specific data | 385 | * @data: driver specific data |
380 | * @show: attr show function | 386 | * @show: attr show function |
381 | * @is_visible: attr visibility function | 387 | * @is_visible: attr visibility function |
388 | * @release: release function | ||
382 | * | 389 | * |
383 | * Note: The boot sysfs lib will free the data passed in for the caller | 390 | * Note: The boot sysfs lib will free the data passed in for the caller |
384 | * when all refs to the initiator kobject have been released. | 391 | * when all refs to the initiator kobject have been released. |
@@ -387,12 +394,13 @@ struct iscsi_boot_kobj * | |||
387 | iscsi_boot_create_initiator(struct iscsi_boot_kset *boot_kset, int index, | 394 | iscsi_boot_create_initiator(struct iscsi_boot_kset *boot_kset, int index, |
388 | void *data, | 395 | void *data, |
389 | ssize_t (*show) (void *data, int type, char *buf), | 396 | ssize_t (*show) (void *data, int type, char *buf), |
390 | mode_t (*is_visible) (void *data, int type)) | 397 | mode_t (*is_visible) (void *data, int type), |
398 | void (*release) (void *data)) | ||
391 | { | 399 | { |
392 | return iscsi_boot_create_kobj(boot_kset, | 400 | return iscsi_boot_create_kobj(boot_kset, |
393 | &iscsi_boot_initiator_attr_group, | 401 | &iscsi_boot_initiator_attr_group, |
394 | "initiator", index, data, show, | 402 | "initiator", index, data, show, |
395 | is_visible); | 403 | is_visible, release); |
396 | } | 404 | } |
397 | EXPORT_SYMBOL_GPL(iscsi_boot_create_initiator); | 405 | EXPORT_SYMBOL_GPL(iscsi_boot_create_initiator); |
398 | 406 | ||
@@ -403,6 +411,7 @@ EXPORT_SYMBOL_GPL(iscsi_boot_create_initiator); | |||
403 | * @data: driver specific data | 411 | * @data: driver specific data |
404 | * @show: attr show function | 412 | * @show: attr show function |
405 | * @is_visible: attr visibility function | 413 | * @is_visible: attr visibility function |
414 | * @release: release function | ||
406 | * | 415 | * |
407 | * Note: The boot sysfs lib will free the data passed in for the caller | 416 | * Note: The boot sysfs lib will free the data passed in for the caller |
408 | * when all refs to the ethernet kobject have been released. | 417 | * when all refs to the ethernet kobject have been released. |
@@ -411,12 +420,13 @@ struct iscsi_boot_kobj * | |||
411 | iscsi_boot_create_ethernet(struct iscsi_boot_kset *boot_kset, int index, | 420 | iscsi_boot_create_ethernet(struct iscsi_boot_kset *boot_kset, int index, |
412 | void *data, | 421 | void *data, |
413 | ssize_t (*show) (void *data, int type, char *buf), | 422 | ssize_t (*show) (void *data, int type, char *buf), |
414 | mode_t (*is_visible) (void *data, int type)) | 423 | mode_t (*is_visible) (void *data, int type), |
424 | void (*release) (void *data)) | ||
415 | { | 425 | { |
416 | return iscsi_boot_create_kobj(boot_kset, | 426 | return iscsi_boot_create_kobj(boot_kset, |
417 | &iscsi_boot_ethernet_attr_group, | 427 | &iscsi_boot_ethernet_attr_group, |
418 | "ethernet%d", index, data, show, | 428 | "ethernet%d", index, data, show, |
419 | is_visible); | 429 | is_visible, release); |
420 | } | 430 | } |
421 | EXPORT_SYMBOL_GPL(iscsi_boot_create_ethernet); | 431 | EXPORT_SYMBOL_GPL(iscsi_boot_create_ethernet); |
422 | 432 | ||
@@ -472,6 +482,9 @@ void iscsi_boot_destroy_kset(struct iscsi_boot_kset *boot_kset) | |||
472 | { | 482 | { |
473 | struct iscsi_boot_kobj *boot_kobj, *tmp_kobj; | 483 | struct iscsi_boot_kobj *boot_kobj, *tmp_kobj; |
474 | 484 | ||
485 | if (!boot_kset) | ||
486 | return; | ||
487 | |||
475 | list_for_each_entry_safe(boot_kobj, tmp_kobj, | 488 | list_for_each_entry_safe(boot_kobj, tmp_kobj, |
476 | &boot_kset->kobj_list, list) | 489 | &boot_kset->kobj_list, list) |
477 | iscsi_boot_remove_kobj(boot_kobj); | 490 | iscsi_boot_remove_kobj(boot_kobj); |