From 31b9025aa0f89b392077db3f87458fd46bcc4f58 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 18 Jan 2007 12:23:51 -0800 Subject: Kobject: make kobject apis more robust in handling NULL pointers It should be ok to pass in NULL for some kobject functions, so add error checking for all exported kobject functions to be more robust. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 7ce6dc138e90..9aed594bfcac 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -126,6 +126,8 @@ EXPORT_SYMBOL_GPL(kobject_get_path); */ void kobject_init(struct kobject * kobj) { + if (!kobj) + return; kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); init_waitqueue_head(&kobj->poll); @@ -366,6 +368,8 @@ out: void kobject_del(struct kobject * kobj) { + if (!kobj) + return; sysfs_remove_dir(kobj); unlink(kobj); } @@ -377,6 +381,8 @@ void kobject_del(struct kobject * kobj) void kobject_unregister(struct kobject * kobj) { + if (!kobj) + return; pr_debug("kobject %s: unregistering\n",kobject_name(kobj)); kobject_uevent(kobj, KOBJ_REMOVE); kobject_del(kobj); @@ -523,6 +529,8 @@ int kset_add(struct kset * k) int kset_register(struct kset * k) { + if (!k) + return -EINVAL; kset_init(k); return kset_add(k); } @@ -535,6 +543,8 @@ int kset_register(struct kset * k) void kset_unregister(struct kset * k) { + if (!k) + return; kobject_unregister(&k->kobj); } @@ -586,6 +596,9 @@ int subsystem_register(struct subsystem * s) { int error; + if (!s) + return -EINVAL; + subsystem_init(s); pr_debug("subsystem %s: registering\n",s->kset.kobj.name); @@ -598,6 +611,8 @@ int subsystem_register(struct subsystem * s) void subsystem_unregister(struct subsystem * s) { + if (!s) + return; pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name); kset_unregister(&s->kset); } @@ -612,6 +627,10 @@ void subsystem_unregister(struct subsystem * s) int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) { int error = 0; + + if (!s || !a) + return -EINVAL; + if (subsys_get(s)) { error = sysfs_create_file(&s->kset.kobj,&a->attr); subsys_put(s); -- cgit v1.2.3 From c744aeae9d173a953b771a7ad5c872f91fa99dec Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 8 Jan 2007 20:16:44 +0100 Subject: driver core: Allow device_move(dev, NULL). If we allow NULL as the new parent in device_move(), we need to make sure that the device is placed into the same place as it would if it was newly registered: - Consider the device virtual tree. In order to be able to reuse code, setup_parent() has been tweaked a bit. - kobject_move() can fall back to the kset's kobject. - sysfs_move_dir() uses the sysfs root dir as fallback. Signed-off-by: Cornelia Huck Cc: Marcel Holtmann Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 9aed594bfcac..c033dc8fa9af 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -314,7 +314,7 @@ int kobject_rename(struct kobject * kobj, const char *new_name) /** * kobject_move - move object to another parent * @kobj: object in question. - * @new_parent: object's new parent + * @new_parent: object's new parent (can be NULL) */ int kobject_move(struct kobject *kobj, struct kobject *new_parent) @@ -330,8 +330,8 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent) return -EINVAL; new_parent = kobject_get(new_parent); if (!new_parent) { - error = -EINVAL; - goto out; + if (kobj->kset) + new_parent = kobject_get(&kobj->kset->kobj); } /* old object path */ devpath = kobject_get_path(kobj, GFP_KERNEL); -- cgit v1.2.3 From b067db49e1f4013ef02ef68845701b600e88a722 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Tue, 2 Jan 2007 13:44:44 +0100 Subject: kobject: kobject_put cleanup This patch removes redundant argument checks for kobject_put(). Signed-off-by: Mariusz Kozlowski Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index c033dc8fa9af..74b8dbca150e 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -195,8 +195,7 @@ int kobject_add(struct kobject * kobj) if (error) { /* unlink does the kobject_put() for us */ unlink(kobj); - if (parent) - kobject_put(parent); + kobject_put(parent); /* be noisy on error issues */ if (error == -EEXIST) @@ -420,8 +419,7 @@ void kobject_cleanup(struct kobject * kobj) t->release(kobj); if (s) kset_put(s); - if (parent) - kobject_put(parent); + kobject_put(parent); } static void kobject_release(struct kref *kref) -- cgit v1.2.3 From b592fcfe7f06c15ec11774b5be7ce0de3aa86e73 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 24 Jan 2007 12:35:52 -0700 Subject: sysfs: Shadow directory support The problem. When implementing a network namespace I need to be able to have multiple network devices with the same name. Currently this is a problem for /sys/class/net/*. What I want is a separate /sys/class/net directory in sysfs for each network namespace, and I want to name each of them /sys/class/net. I looked and the VFS actually allows that. All that is needed is for /sys/class/net to implement a follow link method to redirect lookups to the real directory you want. Implementing a follow link method that is sensitive to the current network namespace turns out to be 3 lines of code so it looks like a clean approach. Modifying sysfs so it doesn't get in my was is a bit trickier. I am calling the concept of multiple directories all at the same path in the filesystem shadow directories. With the directory entry really at that location the shadow master. The following patch modifies sysfs so it can handle a directory structure slightly different from the kobject tree so I can implement the shadow directories for handling /sys/class/net/. Signed-off-by: Eric W. Biederman Cc: Maneesh Soni Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 74b8dbca150e..c2917ffe8bf1 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -44,11 +44,11 @@ static int populate_dir(struct kobject * kobj) return error; } -static int create_dir(struct kobject * kobj) +static int create_dir(struct kobject * kobj, struct dentry *shadow_parent) { int error = 0; if (kobject_name(kobj)) { - error = sysfs_create_dir(kobj); + error = sysfs_create_dir(kobj, shadow_parent); if (!error) { if ((error = populate_dir(kobj))) sysfs_remove_dir(kobj); @@ -158,9 +158,10 @@ static void unlink(struct kobject * kobj) /** * kobject_add - add an object to the hierarchy. * @kobj: object. + * @shadow_parent: sysfs directory to add to. */ -int kobject_add(struct kobject * kobj) +int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent) { int error = 0; struct kobject * parent; @@ -191,7 +192,7 @@ int kobject_add(struct kobject * kobj) } kobj->parent = parent; - error = create_dir(kobj); + error = create_dir(kobj, shadow_parent); if (error) { /* unlink does the kobject_put() for us */ unlink(kobj); @@ -212,6 +213,15 @@ int kobject_add(struct kobject * kobj) return error; } +/** + * kobject_add - add an object to the hierarchy. + * @kobj: object. + */ +int kobject_add(struct kobject * kobj) +{ + return kobject_shadow_add(kobj, NULL); +} + /** * kobject_register - initialize and add an object. @@ -304,7 +314,29 @@ int kobject_rename(struct kobject * kobj, const char *new_name) kobj = kobject_get(kobj); if (!kobj) return -EINVAL; - error = sysfs_rename_dir(kobj, new_name); + if (!kobj->parent) + return -EINVAL; + error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name); + kobject_put(kobj); + + return error; +} + +/** + * kobject_rename - change the name of an object + * @kobj: object in question. + * @new_name: object's new name + */ + +int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent, + const char *new_name) +{ + int error = 0; + + kobj = kobject_get(kobj); + if (!kobj) + return -EINVAL; + error = sysfs_rename_dir(kobj, new_parent, new_name); kobject_put(kobj); return error; -- cgit v1.2.3