aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kobject.c')
-rw-r--r--lib/kobject.c90
1 files changed, 86 insertions, 4 deletions
diff --git a/lib/kobject.c b/lib/kobject.c
index 084f7b18d0c0..5b4b8886435e 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -13,11 +13,30 @@
13 */ 13 */
14 14
15#include <linux/kobject.h> 15#include <linux/kobject.h>
16#include <linux/kobj_completion.h>
16#include <linux/string.h> 17#include <linux/string.h>
17#include <linux/export.h> 18#include <linux/export.h>
18#include <linux/stat.h> 19#include <linux/stat.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20 21
22/**
23 * kobject_namespace - return @kobj's namespace tag
24 * @kobj: kobject in question
25 *
26 * Returns namespace tag of @kobj if its parent has namespace ops enabled
27 * and thus @kobj should have a namespace tag associated with it. Returns
28 * %NULL otherwise.
29 */
30const void *kobject_namespace(struct kobject *kobj)
31{
32 const struct kobj_ns_type_operations *ns_ops = kobj_ns_ops(kobj);
33
34 if (!ns_ops || ns_ops->type == KOBJ_NS_TYPE_NONE)
35 return NULL;
36
37 return kobj->ktype->namespace(kobj);
38}
39
21/* 40/*
22 * populate_dir - populate directory with attributes. 41 * populate_dir - populate directory with attributes.
23 * @kobj: object we're working on. 42 * @kobj: object we're working on.
@@ -46,13 +65,21 @@ static int populate_dir(struct kobject *kobj)
46 65
47static int create_dir(struct kobject *kobj) 66static int create_dir(struct kobject *kobj)
48{ 67{
49 int error = 0; 68 int error;
50 error = sysfs_create_dir(kobj); 69
70 error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj));
51 if (!error) { 71 if (!error) {
52 error = populate_dir(kobj); 72 error = populate_dir(kobj);
53 if (error) 73 if (error)
54 sysfs_remove_dir(kobj); 74 sysfs_remove_dir(kobj);
55 } 75 }
76
77 /*
78 * @kobj->sd may be deleted by an ancestor going away. Hold an
79 * extra reference so that it stays until @kobj is gone.
80 */
81 sysfs_get(kobj->sd);
82
56 return error; 83 return error;
57} 84}
58 85
@@ -428,7 +455,7 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
428 goto out; 455 goto out;
429 } 456 }
430 457
431 error = sysfs_rename_dir(kobj, new_name); 458 error = sysfs_rename_dir_ns(kobj, new_name, kobject_namespace(kobj));
432 if (error) 459 if (error)
433 goto out; 460 goto out;
434 461
@@ -472,6 +499,7 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
472 if (kobj->kset) 499 if (kobj->kset)
473 new_parent = kobject_get(&kobj->kset->kobj); 500 new_parent = kobject_get(&kobj->kset->kobj);
474 } 501 }
502
475 /* old object path */ 503 /* old object path */
476 devpath = kobject_get_path(kobj, GFP_KERNEL); 504 devpath = kobject_get_path(kobj, GFP_KERNEL);
477 if (!devpath) { 505 if (!devpath) {
@@ -486,7 +514,7 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
486 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath); 514 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
487 envp[0] = devpath_string; 515 envp[0] = devpath_string;
488 envp[1] = NULL; 516 envp[1] = NULL;
489 error = sysfs_move_dir(kobj, new_parent); 517 error = sysfs_move_dir_ns(kobj, new_parent, kobject_namespace(kobj));
490 if (error) 518 if (error)
491 goto out; 519 goto out;
492 old_parent = kobj->parent; 520 old_parent = kobj->parent;
@@ -508,10 +536,15 @@ out:
508 */ 536 */
509void kobject_del(struct kobject *kobj) 537void kobject_del(struct kobject *kobj)
510{ 538{
539 struct sysfs_dirent *sd;
540
511 if (!kobj) 541 if (!kobj)
512 return; 542 return;
513 543
544 sd = kobj->sd;
514 sysfs_remove_dir(kobj); 545 sysfs_remove_dir(kobj);
546 sysfs_put(sd);
547
515 kobj->state_in_sysfs = 0; 548 kobj->state_in_sysfs = 0;
516 kobj_kset_leave(kobj); 549 kobj_kset_leave(kobj);
517 kobject_put(kobj->parent); 550 kobject_put(kobj->parent);
@@ -727,6 +760,55 @@ const struct sysfs_ops kobj_sysfs_ops = {
727}; 760};
728 761
729/** 762/**
763 * kobj_completion_init - initialize a kobj_completion object.
764 * @kc: kobj_completion
765 * @ktype: type of kobject to initialize
766 *
767 * kobj_completion structures can be embedded within structures with different
768 * lifetime rules. During the release of the enclosing object, we can
769 * wait on the release of the kobject so that we don't free it while it's
770 * still busy.
771 */
772void kobj_completion_init(struct kobj_completion *kc, struct kobj_type *ktype)
773{
774 init_completion(&kc->kc_unregister);
775 kobject_init(&kc->kc_kobj, ktype);
776}
777EXPORT_SYMBOL_GPL(kobj_completion_init);
778
779/**
780 * kobj_completion_release - release a kobj_completion object
781 * @kobj: kobject embedded in kobj_completion
782 *
783 * Used with kobject_release to notify waiters that the kobject has been
784 * released.
785 */
786void kobj_completion_release(struct kobject *kobj)
787{
788 struct kobj_completion *kc = kobj_to_kobj_completion(kobj);
789 complete(&kc->kc_unregister);
790}
791EXPORT_SYMBOL_GPL(kobj_completion_release);
792
793/**
794 * kobj_completion_del_and_wait - release the kobject and wait for it
795 * @kc: kobj_completion object to release
796 *
797 * Delete the kobject from sysfs and drop the reference count. Then wait
798 * until any other outstanding references are also dropped. This routine
799 * is only necessary once other references may have been taken on the
800 * kobject. Typically this happens when the kobject has been published
801 * to sysfs via kobject_add.
802 */
803void kobj_completion_del_and_wait(struct kobj_completion *kc)
804{
805 kobject_del(&kc->kc_kobj);
806 kobject_put(&kc->kc_kobj);
807 wait_for_completion(&kc->kc_unregister);
808}
809EXPORT_SYMBOL_GPL(kobj_completion_del_and_wait);
810
811/**
730 * kset_register - initialize and add a kset. 812 * kset_register - initialize and add a kset.
731 * @k: kset. 813 * @k: kset.
732 */ 814 */