diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/kobject.c | 60 | ||||
| -rw-r--r-- | lib/kobject_uevent.c | 2 | ||||
| -rw-r--r-- | lib/kref.c | 7 |
3 files changed, 60 insertions, 9 deletions
diff --git a/lib/kobject.c b/lib/kobject.c index efe67fa96a71..25204a41a9b0 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
| @@ -194,6 +194,17 @@ int kobject_add(struct kobject * kobj) | |||
| 194 | unlink(kobj); | 194 | unlink(kobj); |
| 195 | if (parent) | 195 | if (parent) |
| 196 | kobject_put(parent); | 196 | kobject_put(parent); |
| 197 | |||
| 198 | /* be noisy on error issues */ | ||
| 199 | if (error == -EEXIST) | ||
| 200 | printk("kobject_add failed for %s with -EEXIST, " | ||
| 201 | "don't try to register things with the " | ||
| 202 | "same name in the same directory.\n", | ||
| 203 | kobject_name(kobj)); | ||
| 204 | else | ||
| 205 | printk("kobject_add failed for %s (%d)\n", | ||
| 206 | kobject_name(kobj), error); | ||
| 207 | dump_stack(); | ||
| 197 | } | 208 | } |
| 198 | 209 | ||
| 199 | return error; | 210 | return error; |
| @@ -207,18 +218,13 @@ int kobject_add(struct kobject * kobj) | |||
| 207 | 218 | ||
| 208 | int kobject_register(struct kobject * kobj) | 219 | int kobject_register(struct kobject * kobj) |
| 209 | { | 220 | { |
| 210 | int error = 0; | 221 | int error = -EINVAL; |
| 211 | if (kobj) { | 222 | if (kobj) { |
| 212 | kobject_init(kobj); | 223 | kobject_init(kobj); |
| 213 | error = kobject_add(kobj); | 224 | error = kobject_add(kobj); |
| 214 | if (error) { | 225 | if (!error) |
| 215 | printk("kobject_register failed for %s (%d)\n", | ||
| 216 | kobject_name(kobj),error); | ||
| 217 | dump_stack(); | ||
| 218 | } else | ||
| 219 | kobject_uevent(kobj, KOBJ_ADD); | 226 | kobject_uevent(kobj, KOBJ_ADD); |
| 220 | } else | 227 | } |
| 221 | error = -EINVAL; | ||
| 222 | return error; | 228 | return error; |
| 223 | } | 229 | } |
| 224 | 230 | ||
| @@ -379,6 +385,44 @@ void kobject_put(struct kobject * kobj) | |||
| 379 | } | 385 | } |
| 380 | 386 | ||
| 381 | 387 | ||
| 388 | static void dir_release(struct kobject *kobj) | ||
| 389 | { | ||
| 390 | kfree(kobj); | ||
| 391 | } | ||
| 392 | |||
| 393 | static struct kobj_type dir_ktype = { | ||
| 394 | .release = dir_release, | ||
| 395 | .sysfs_ops = NULL, | ||
| 396 | .default_attrs = NULL, | ||
| 397 | }; | ||
| 398 | |||
| 399 | /** | ||
| 400 | * kobject_add_dir - add sub directory of object. | ||
| 401 | * @parent: object in which a directory is created. | ||
| 402 | * @name: directory name. | ||
| 403 | * | ||
| 404 | * Add a plain directory object as child of given object. | ||
| 405 | */ | ||
| 406 | struct kobject *kobject_add_dir(struct kobject *parent, const char *name) | ||
| 407 | { | ||
| 408 | struct kobject *k; | ||
| 409 | |||
| 410 | if (!parent) | ||
| 411 | return NULL; | ||
| 412 | |||
| 413 | k = kzalloc(sizeof(*k), GFP_KERNEL); | ||
| 414 | if (!k) | ||
| 415 | return NULL; | ||
| 416 | |||
| 417 | k->parent = parent; | ||
| 418 | k->ktype = &dir_ktype; | ||
| 419 | kobject_set_name(k, name); | ||
| 420 | kobject_register(k); | ||
| 421 | |||
| 422 | return k; | ||
| 423 | } | ||
| 424 | EXPORT_SYMBOL_GPL(kobject_add_dir); | ||
| 425 | |||
| 382 | /** | 426 | /** |
| 383 | * kset_init - initialize a kset for use | 427 | * kset_init - initialize a kset for use |
| 384 | * @k: kset | 428 | * @k: kset |
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 086a0c6e888e..982226daf939 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
| @@ -26,6 +26,8 @@ | |||
| 26 | #define NUM_ENVP 32 /* number of env pointers */ | 26 | #define NUM_ENVP 32 /* number of env pointers */ |
| 27 | 27 | ||
| 28 | #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) | 28 | #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) |
| 29 | u64 uevent_seqnum; | ||
| 30 | char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug"; | ||
| 29 | static DEFINE_SPINLOCK(sequence_lock); | 31 | static DEFINE_SPINLOCK(sequence_lock); |
| 30 | static struct sock *uevent_sock; | 32 | static struct sock *uevent_sock; |
| 31 | 33 | ||
diff --git a/lib/kref.c b/lib/kref.c index 0d07cc31c818..4a467faf1367 100644 --- a/lib/kref.c +++ b/lib/kref.c | |||
| @@ -52,7 +52,12 @@ int kref_put(struct kref *kref, void (*release)(struct kref *kref)) | |||
| 52 | WARN_ON(release == NULL); | 52 | WARN_ON(release == NULL); |
| 53 | WARN_ON(release == (void (*)(struct kref *))kfree); | 53 | WARN_ON(release == (void (*)(struct kref *))kfree); |
| 54 | 54 | ||
| 55 | if (atomic_dec_and_test(&kref->refcount)) { | 55 | /* |
| 56 | * if current count is one, we are the last user and can release object | ||
| 57 | * right now, avoiding an atomic operation on 'refcount' | ||
| 58 | */ | ||
| 59 | if ((atomic_read(&kref->refcount) == 1) || | ||
| 60 | (atomic_dec_and_test(&kref->refcount))) { | ||
| 56 | release(kref); | 61 | release(kref); |
| 57 | return 1; | 62 | return 1; |
| 58 | } | 63 | } |
