From 864062457a2e444227bd368ca5f2a2b740de604f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 14 Mar 2007 03:25:56 +0100 Subject: driver core: fix namespace issue with devices assigned to classes - uses a kset in "struct class" to keep track of all directories belonging to this class - merges with the /sys/devices/virtual logic. - removes the namespace-dir if the last member of that class leaves the directory. There may be locking or refcounting fixes left, I stopped when it seemed to work with network and sound modules. :) From: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 12 ++++++++++-- lib/kobject_uevent.c | 16 ++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/kobject.c b/lib/kobject.c index 057921c5945..f6645515560 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -488,13 +488,15 @@ static struct kobj_type dir_ktype = { }; /** - * kobject_add_dir - add sub directory of object. + * kobject__kset_add_dir - add sub directory of object. + * @kset: kset the directory is belongs to. * @parent: object in which a directory is created. * @name: directory name. * * Add a plain directory object as child of given object. */ -struct kobject *kobject_add_dir(struct kobject *parent, const char *name) +struct kobject *kobject_kset_add_dir(struct kset *kset, + struct kobject *parent, const char *name) { struct kobject *k; int ret; @@ -506,6 +508,7 @@ struct kobject *kobject_add_dir(struct kobject *parent, const char *name) if (!k) return NULL; + k->kset = kset; k->parent = parent; k->ktype = &dir_ktype; kobject_set_name(k, name); @@ -520,6 +523,11 @@ struct kobject *kobject_add_dir(struct kobject *parent, const char *name) return k; } +struct kobject *kobject_add_dir(struct kobject *parent, const char *name) +{ + return kobject_kset_add_dir(NULL, parent, name); +} + /** * kset_init - initialize a kset for use * @k: kset diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 82fc1794b69..4122f38330d 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -115,6 +115,16 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, return 0; } + /* originating subsystem */ + if (uevent_ops && uevent_ops->name) + subsystem = uevent_ops->name(kset, kobj); + else + subsystem = kobject_name(&kset->kobj); + if (!subsystem) { + pr_debug("unset subsytem caused the event to drop!\n"); + return 0; + } + /* environment index */ envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL); if (!envp) @@ -134,12 +144,6 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, goto exit; } - /* originating subsystem */ - if (uevent_ops && uevent_ops->name) - subsystem = uevent_ops->name(kset, kobj); - else - subsystem = kobject_name(&kset->kobj); - /* event environemnt for helper process only */ envp[i++] = "HOME=/"; envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; -- cgit v1.2.3-70-g09d2 From 460f7e9a1bde2c74f060f7ce0a308dab4be6a56b Mon Sep 17 00:00:00 2001 From: Dmitriy Monakhov Date: Sat, 10 Mar 2007 14:00:10 +0300 Subject: kobject: kobject_shadow_add cleanup - correct function name in comments - parrent assignment does metter only inside "if" block, so move it inside this block. Signed-off-by: Monakhov Dmitriy Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/kobject.c b/lib/kobject.c index f6645515560..bbbfab4145e 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -157,7 +157,7 @@ static void unlink(struct kobject * kobj) } /** - * kobject_add - add an object to the hierarchy. + * kobject_shadow_add - add an object to the hierarchy. * @kobj: object. * @shadow_parent: sysfs directory to add to. */ @@ -190,8 +190,8 @@ int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent) list_add_tail(&kobj->entry,&kobj->kset->list); spin_unlock(&kobj->kset->list_lock); + kobj->parent = parent; } - kobj->parent = parent; error = create_dir(kobj, shadow_parent); if (error) { -- cgit v1.2.3-70-g09d2 From 1b0b3b9980e482ab7c603430462538334f69f14a Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 2 Apr 2007 14:47:59 +0200 Subject: kref: fix CPU ordering with respect to krefs some atomic operations are only atomic, not ordered. Thus a CPU is allowed to reorder memory references to an object to before the reference is obtained. This fixes it. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- lib/kref.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/kref.c b/lib/kref.c index 0d07cc31c81..a6dc3ec328e 100644 --- a/lib/kref.c +++ b/lib/kref.c @@ -21,6 +21,7 @@ void kref_init(struct kref *kref) { atomic_set(&kref->refcount,1); + smp_mb(); } /** @@ -31,6 +32,7 @@ void kref_get(struct kref *kref) { WARN_ON(!atomic_read(&kref->refcount)); atomic_inc(&kref->refcount); + smp_mb__after_atomic_inc(); } /** -- cgit v1.2.3-70-g09d2 From ca2f37dbc5324c7278577731033a358f1f86050a Mon Sep 17 00:00:00 2001 From: Jean Tourrilhes Date: Wed, 7 Mar 2007 10:49:30 -0800 Subject: Driver core: notify userspace of network device renames Provide rename event for when we rename network devices. Signed-off-by: Jean Tourrilhes Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 30 ++++++++++++++++++++++++++++++ net/core/net-sysfs.c | 11 +++++++++++ 2 files changed, 41 insertions(+) (limited to 'lib') diff --git a/lib/kobject.c b/lib/kobject.c index bbbfab4145e..db1d23707eb 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -311,13 +311,43 @@ EXPORT_SYMBOL(kobject_set_name); int kobject_rename(struct kobject * kobj, const char *new_name) { int error = 0; + const char *devpath = NULL; + char *devpath_string = NULL; + char *envp[2]; kobj = kobject_get(kobj); if (!kobj) return -EINVAL; if (!kobj->parent) return -EINVAL; + + devpath = kobject_get_path(kobj, GFP_KERNEL); + if (!devpath) { + error = -ENOMEM; + goto out; + } + devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL); + if (!devpath_string) { + error = -ENOMEM; + goto out; + } + sprintf(devpath_string, "DEVPATH_OLD=%s", devpath); + envp[0] = devpath_string; + envp[1] = NULL; + /* Note : if we want to send the new name alone, not the full path, + * we could probably use kobject_name(kobj); */ + error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name); + + /* This function is mostly/only used for network interface. + * Some hotplug package track interfaces by their name and + * therefore want to know when the name is changed by the user. */ + if (!error) + kobject_uevent_env(kobj, KOBJ_MOVE, envp); + +out: + kfree(devpath_string); + kfree(devpath); kobject_put(kobj); return error; diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 221a64ab64f..e441ec7988c 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -421,6 +421,17 @@ static int netdev_uevent(struct device *d, char **envp, buf += n; size -= n; + if ((size <= 0) || (i >= num_envp)) + return -ENOMEM; + + /* pass ifindex to uevent. + * ifindex is useful as it won't change (interface name may change) + * and is what RtNetlink uses natively. */ + envp[i++] = buf; + n = snprintf(buf, size, "IFINDEX=%d", dev->ifindex) + 1; + buf += n; + size -= n; + if ((size <= 0) || (i >= num_envp)) return -ENOMEM; -- cgit v1.2.3-70-g09d2 From 14193fb91a7d88d3fe55d3160892edeb2b02e0c2 Mon Sep 17 00:00:00 2001 From: John Anthony Kazos Jr Date: Wed, 4 Apr 2007 07:39:17 -0400 Subject: Kobject: kobject_uevent.c: Collapse unnecessary loop nesting (top_kobj) Collapses a do..while() loop within an if() to a simple while() loop for simplicity and readability. Signed-off-by: John Anthony Kazos Jr. Signed-off-by: Greg Kroah-Hartman --- lib/kobject_uevent.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 4122f38330d..d9a3510ed2e 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -95,10 +95,8 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, /* search the kset we belong to */ top_kobj = kobj; - if (!top_kobj->kset && top_kobj->parent) { - do { - top_kobj = top_kobj->parent; - } while (!top_kobj->kset && top_kobj->parent); + while (!top_kobj->kset && top_kobj->parent) { + top_kobj = top_kobj->parent; } if (!top_kobj->kset) { pr_debug("kobject attempted to send uevent without kset!\n"); -- cgit v1.2.3-70-g09d2 From 88db4721d47bc59b92d46de04e21c7975ea983f2 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 10 Apr 2007 14:35:27 +0200 Subject: kobject: kobject_add() reference leak We leak a reference if we attempt to add a kobject with no name. Signed-off-by: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/kobject.c b/lib/kobject.c index db1d23707eb..eb251aae78d 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -174,6 +174,7 @@ int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent) if (!*kobj->k_name) { pr_debug("kobject attempted to be registered with no name!\n"); WARN_ON(1); + kobject_put(kobj); return -EINVAL; } parent = kobject_get(kobj->parent); -- cgit v1.2.3-70-g09d2 From 4628803062d93dadc6ba8e801fd075526904a38c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Apr 2007 11:52:31 -0400 Subject: kobject core: remove rwsem from struct subsystem It isn't used at all by the driver core anymore, and the few usages of it within the kernel have now all been fixed as most of them were using it incorrectly. So remove it. Now the whole struct subsys can be removed from the system, but that's for a later patch... Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- include/linux/kobject.h | 2 -- lib/kobject.c | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'lib') diff --git a/include/linux/kobject.h b/include/linux/kobject.h index d37cd7f10e3..a659a97eccf 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -177,7 +176,6 @@ extern struct kobject * kset_find_obj(struct kset *, const char *); struct subsystem { struct kset kset; - struct rw_semaphore rwsem; }; #define decl_subsys(_name,_type,_uevent_ops) \ diff --git a/lib/kobject.c b/lib/kobject.c index eb251aae78d..2882aff6f3d 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -652,7 +652,6 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name) void subsystem_init(struct subsystem * s) { - init_rwsem(&s->rwsem); kset_init(&s->kset); } @@ -661,8 +660,7 @@ void subsystem_init(struct subsystem * s) * @s: the subsystem we're registering. * * Once we register the subsystem, we want to make sure that - * the kset points back to this subsystem for correct usage of - * the rwsem. + * the kset points back to this subsystem. */ int subsystem_register(struct subsystem * s) -- cgit v1.2.3-70-g09d2 From 2753133eb3321feb81dcb9c88141dd2aa5973ee1 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 6 Apr 2007 10:47:11 -0600 Subject: kobject: Comment and warning fixes to kobject.c This dots some i's and crosses some t's after left over from when kobject_kset_add_dir was built from kobject_add_dir. Signed-off-by: Eric W. Biederman Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/kobject.c b/lib/kobject.c index 2882aff6f3d..cecf2fbede3 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -519,7 +519,7 @@ static struct kobj_type dir_ktype = { }; /** - * kobject__kset_add_dir - add sub directory of object. + * kobject_kset_add_dir - add sub directory of object. * @kset: kset the directory is belongs to. * @parent: object in which a directory is created. * @name: directory name. @@ -545,8 +545,8 @@ struct kobject *kobject_kset_add_dir(struct kset *kset, kobject_set_name(k, name); ret = kobject_register(k); if (ret < 0) { - printk(KERN_WARNING "kobject_add_dir: " - "kobject_register error: %d\n", ret); + printk(KERN_WARNING "%s: kobject_register error: %d\n", + __func__, ret); kobject_del(k); return NULL; } @@ -554,6 +554,13 @@ struct kobject *kobject_kset_add_dir(struct kset *kset, return k; } +/** + * kobject_add_dir - add sub directory of object. + * @parent: object in which a directory is created. + * @name: directory name. + * + * Add a plain directory object as child of given object. + */ struct kobject *kobject_add_dir(struct kobject *parent, const char *name) { return kobject_kset_add_dir(NULL, parent, name); -- cgit v1.2.3-70-g09d2 From 3106d46f51a1a72fdbf071ebc0800a9bcfcbc544 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 6 Apr 2007 12:21:45 +0200 Subject: the overdue removal of the mount/umount uevents This patch contains the overdue removal of the mount/umount uevents. Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- Documentation/feature-removal-schedule.txt | 9 --------- fs/super.c | 12 ------------ include/linux/kobject.h | 8 +++----- lib/kobject_uevent.c | 4 ---- 4 files changed, 3 insertions(+), 30 deletions(-) (limited to 'lib') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 6da663607f7..ec0b4843b1c 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -134,15 +134,6 @@ Who: Arjan van de Ven --------------------------- -What: mount/umount uevents -When: February 2007 -Why: These events are not correct, and do not properly let userspace know - when a file system has been mounted or unmounted. Userspace should - poll the /proc/mounts file instead to detect this properly. -Who: Greg Kroah-Hartman - ---------------------------- - What: USB driver API moves to EXPORT_SYMBOL_GPL When: February 2008 Files: include/linux/usb.h, drivers/usb/core/driver.c diff --git a/fs/super.c b/fs/super.c index 60b1e50cbf5..8341e4e1d73 100644 --- a/fs/super.c +++ b/fs/super.c @@ -725,16 +725,6 @@ static int test_bdev_super(struct super_block *s, void *data) return (void *)s->s_bdev == data; } -static void bdev_uevent(struct block_device *bdev, enum kobject_action action) -{ - if (bdev->bd_disk) { - if (bdev->bd_part) - kobject_uevent(&bdev->bd_part->kobj, action); - else - kobject_uevent(&bdev->bd_disk->kobj, action); - } -} - int get_sb_bdev(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, int (*fill_super)(struct super_block *, void *, int), @@ -782,7 +772,6 @@ int get_sb_bdev(struct file_system_type *fs_type, } s->s_flags |= MS_ACTIVE; - bdev_uevent(bdev, KOBJ_MOUNT); } return simple_set_mnt(mnt, s); @@ -801,7 +790,6 @@ void kill_block_super(struct super_block *sb) { struct block_device *bdev = sb->s_bdev; - bdev_uevent(bdev, KOBJ_UMOUNT); generic_shutdown_super(sb); sync_blockdev(bdev); close_bdev_excl(bdev); diff --git a/include/linux/kobject.h b/include/linux/kobject.h index a659a97eccf..eb0e63ef297 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -42,11 +42,9 @@ enum kobject_action { KOBJ_ADD = (__force kobject_action_t) 0x01, /* exclusive to core */ KOBJ_REMOVE = (__force kobject_action_t) 0x02, /* exclusive to core */ KOBJ_CHANGE = (__force kobject_action_t) 0x03, /* device state change */ - KOBJ_MOUNT = (__force kobject_action_t) 0x04, /* mount event for block devices (broken) */ - KOBJ_UMOUNT = (__force kobject_action_t) 0x05, /* umount event for block devices (broken) */ - KOBJ_OFFLINE = (__force kobject_action_t) 0x06, /* device offline */ - KOBJ_ONLINE = (__force kobject_action_t) 0x07, /* device online */ - KOBJ_MOVE = (__force kobject_action_t) 0x08, /* device move */ + KOBJ_OFFLINE = (__force kobject_action_t) 0x04, /* device offline */ + KOBJ_ONLINE = (__force kobject_action_t) 0x05, /* device online */ + KOBJ_MOVE = (__force kobject_action_t) 0x06, /* device move */ }; struct kobject { diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index d9a3510ed2e..12e311dc664 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -42,10 +42,6 @@ static char *action_to_string(enum kobject_action action) return "remove"; case KOBJ_CHANGE: return "change"; - case KOBJ_MOUNT: - return "mount"; - case KOBJ_UMOUNT: - return "umount"; case KOBJ_OFFLINE: return "offline"; case KOBJ_ONLINE: -- cgit v1.2.3-70-g09d2