aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kobject.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-07 22:22:26 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-07 22:22:26 -0500
commitf2aca47dc3c2d0c2d5dbd972558557e74232bbce (patch)
treeeae58f599a25a1f3ab41bf616a2b7c4b3c6e2277 /lib/kobject.c
parent7677ced48e2bbbb8d847d34f37e5d96d2b0e41e4 (diff)
parentb592fcfe7f06c15ec11774b5be7ce0de3aa86e73 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6: (28 commits) sysfs: Shadow directory support Driver Core: Increase the default timeout value of the firmware subsystem Driver core: allow to delay the uevent at device creation time Driver core: add device_type to struct device Driver core: add uevent vars for devices of a class SYSFS: Fix missing include of list.h in sysfs.h HOWTO: Add a reference to Harbison and Steele sysfs: error handling in sysfs, fill_read_buffer() kobject: kobject_put cleanup sysfs: kobject_put cleanup sysfs: suppress lockdep warnings Driver core: fix race in sysfs between sysfs_remove_file() and read()/write() driver core: Change function call order in device_bind_driver(). driver core: Don't stop probing on ->probe errors. driver core fixes: device_register() retval check in platform.c driver core fixes: make_class_name() retval checks /sys/modules/*/holders USB: add the sysfs driver name to all modules SERIO: add the sysfs driver name to all modules PCI: add the sysfs driver name to all modules ...
Diffstat (limited to 'lib/kobject.c')
-rw-r--r--lib/kobject.c73
1 files changed, 61 insertions, 12 deletions
diff --git a/lib/kobject.c b/lib/kobject.c
index 7ce6dc138e90..c2917ffe8bf1 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -44,11 +44,11 @@ static int populate_dir(struct kobject * kobj)
44 return error; 44 return error;
45} 45}
46 46
47static int create_dir(struct kobject * kobj) 47static int create_dir(struct kobject * kobj, struct dentry *shadow_parent)
48{ 48{
49 int error = 0; 49 int error = 0;
50 if (kobject_name(kobj)) { 50 if (kobject_name(kobj)) {
51 error = sysfs_create_dir(kobj); 51 error = sysfs_create_dir(kobj, shadow_parent);
52 if (!error) { 52 if (!error) {
53 if ((error = populate_dir(kobj))) 53 if ((error = populate_dir(kobj)))
54 sysfs_remove_dir(kobj); 54 sysfs_remove_dir(kobj);
@@ -126,6 +126,8 @@ EXPORT_SYMBOL_GPL(kobject_get_path);
126 */ 126 */
127void kobject_init(struct kobject * kobj) 127void kobject_init(struct kobject * kobj)
128{ 128{
129 if (!kobj)
130 return;
129 kref_init(&kobj->kref); 131 kref_init(&kobj->kref);
130 INIT_LIST_HEAD(&kobj->entry); 132 INIT_LIST_HEAD(&kobj->entry);
131 init_waitqueue_head(&kobj->poll); 133 init_waitqueue_head(&kobj->poll);
@@ -156,9 +158,10 @@ static void unlink(struct kobject * kobj)
156/** 158/**
157 * kobject_add - add an object to the hierarchy. 159 * kobject_add - add an object to the hierarchy.
158 * @kobj: object. 160 * @kobj: object.
161 * @shadow_parent: sysfs directory to add to.
159 */ 162 */
160 163
161int kobject_add(struct kobject * kobj) 164int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
162{ 165{
163 int error = 0; 166 int error = 0;
164 struct kobject * parent; 167 struct kobject * parent;
@@ -189,12 +192,11 @@ int kobject_add(struct kobject * kobj)
189 } 192 }
190 kobj->parent = parent; 193 kobj->parent = parent;
191 194
192 error = create_dir(kobj); 195 error = create_dir(kobj, shadow_parent);
193 if (error) { 196 if (error) {
194 /* unlink does the kobject_put() for us */ 197 /* unlink does the kobject_put() for us */
195 unlink(kobj); 198 unlink(kobj);
196 if (parent) 199 kobject_put(parent);
197 kobject_put(parent);
198 200
199 /* be noisy on error issues */ 201 /* be noisy on error issues */
200 if (error == -EEXIST) 202 if (error == -EEXIST)
@@ -211,6 +213,15 @@ int kobject_add(struct kobject * kobj)
211 return error; 213 return error;
212} 214}
213 215
216/**
217 * kobject_add - add an object to the hierarchy.
218 * @kobj: object.
219 */
220int kobject_add(struct kobject * kobj)
221{
222 return kobject_shadow_add(kobj, NULL);
223}
224
214 225
215/** 226/**
216 * kobject_register - initialize and add an object. 227 * kobject_register - initialize and add an object.
@@ -303,7 +314,29 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
303 kobj = kobject_get(kobj); 314 kobj = kobject_get(kobj);
304 if (!kobj) 315 if (!kobj)
305 return -EINVAL; 316 return -EINVAL;
306 error = sysfs_rename_dir(kobj, new_name); 317 if (!kobj->parent)
318 return -EINVAL;
319 error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name);
320 kobject_put(kobj);
321
322 return error;
323}
324
325/**
326 * kobject_rename - change the name of an object
327 * @kobj: object in question.
328 * @new_name: object's new name
329 */
330
331int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent,
332 const char *new_name)
333{
334 int error = 0;
335
336 kobj = kobject_get(kobj);
337 if (!kobj)
338 return -EINVAL;
339 error = sysfs_rename_dir(kobj, new_parent, new_name);
307 kobject_put(kobj); 340 kobject_put(kobj);
308 341
309 return error; 342 return error;
@@ -312,7 +345,7 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
312/** 345/**
313 * kobject_move - move object to another parent 346 * kobject_move - move object to another parent
314 * @kobj: object in question. 347 * @kobj: object in question.
315 * @new_parent: object's new parent 348 * @new_parent: object's new parent (can be NULL)
316 */ 349 */
317 350
318int kobject_move(struct kobject *kobj, struct kobject *new_parent) 351int kobject_move(struct kobject *kobj, struct kobject *new_parent)
@@ -328,8 +361,8 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
328 return -EINVAL; 361 return -EINVAL;
329 new_parent = kobject_get(new_parent); 362 new_parent = kobject_get(new_parent);
330 if (!new_parent) { 363 if (!new_parent) {
331 error = -EINVAL; 364 if (kobj->kset)
332 goto out; 365 new_parent = kobject_get(&kobj->kset->kobj);
333 } 366 }
334 /* old object path */ 367 /* old object path */
335 devpath = kobject_get_path(kobj, GFP_KERNEL); 368 devpath = kobject_get_path(kobj, GFP_KERNEL);
@@ -366,6 +399,8 @@ out:
366 399
367void kobject_del(struct kobject * kobj) 400void kobject_del(struct kobject * kobj)
368{ 401{
402 if (!kobj)
403 return;
369 sysfs_remove_dir(kobj); 404 sysfs_remove_dir(kobj);
370 unlink(kobj); 405 unlink(kobj);
371} 406}
@@ -377,6 +412,8 @@ void kobject_del(struct kobject * kobj)
377 412
378void kobject_unregister(struct kobject * kobj) 413void kobject_unregister(struct kobject * kobj)
379{ 414{
415 if (!kobj)
416 return;
380 pr_debug("kobject %s: unregistering\n",kobject_name(kobj)); 417 pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
381 kobject_uevent(kobj, KOBJ_REMOVE); 418 kobject_uevent(kobj, KOBJ_REMOVE);
382 kobject_del(kobj); 419 kobject_del(kobj);
@@ -414,8 +451,7 @@ void kobject_cleanup(struct kobject * kobj)
414 t->release(kobj); 451 t->release(kobj);
415 if (s) 452 if (s)
416 kset_put(s); 453 kset_put(s);
417 if (parent) 454 kobject_put(parent);
418 kobject_put(parent);
419} 455}
420 456
421static void kobject_release(struct kref *kref) 457static void kobject_release(struct kref *kref)
@@ -523,6 +559,8 @@ int kset_add(struct kset * k)
523 559
524int kset_register(struct kset * k) 560int kset_register(struct kset * k)
525{ 561{
562 if (!k)
563 return -EINVAL;
526 kset_init(k); 564 kset_init(k);
527 return kset_add(k); 565 return kset_add(k);
528} 566}
@@ -535,6 +573,8 @@ int kset_register(struct kset * k)
535 573
536void kset_unregister(struct kset * k) 574void kset_unregister(struct kset * k)
537{ 575{
576 if (!k)
577 return;
538 kobject_unregister(&k->kobj); 578 kobject_unregister(&k->kobj);
539} 579}
540 580
@@ -586,6 +626,9 @@ int subsystem_register(struct subsystem * s)
586{ 626{
587 int error; 627 int error;
588 628
629 if (!s)
630 return -EINVAL;
631
589 subsystem_init(s); 632 subsystem_init(s);
590 pr_debug("subsystem %s: registering\n",s->kset.kobj.name); 633 pr_debug("subsystem %s: registering\n",s->kset.kobj.name);
591 634
@@ -598,6 +641,8 @@ int subsystem_register(struct subsystem * s)
598 641
599void subsystem_unregister(struct subsystem * s) 642void subsystem_unregister(struct subsystem * s)
600{ 643{
644 if (!s)
645 return;
601 pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name); 646 pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name);
602 kset_unregister(&s->kset); 647 kset_unregister(&s->kset);
603} 648}
@@ -612,6 +657,10 @@ void subsystem_unregister(struct subsystem * s)
612int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) 657int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
613{ 658{
614 int error = 0; 659 int error = 0;
660
661 if (!s || !a)
662 return -EINVAL;
663
615 if (subsys_get(s)) { 664 if (subsys_get(s)) {
616 error = sysfs_create_file(&s->kset.kobj,&a->attr); 665 error = sysfs_create_file(&s->kset.kobj,&a->attr);
617 subsys_put(s); 666 subsys_put(s);