Commit ce2c9cb0 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

kobject: remove the static array for the name

Due to historical reasons, struct kobject contained a static array for
the name, and a dynamic pointer in case the name got bigger than the
array.  That's just dumb, as people didn't always know which variable to
reference, even with the accessor for the kobject name.

This patch removes the static array, potentially saving a lot of memory
as the majority of kobjects do not have a very long name.

Thanks to Kay for the idea to do this.

Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 34980ca8
...@@ -63,7 +63,6 @@ extern const char *kobject_actions[]; ...@@ -63,7 +63,6 @@ extern const char *kobject_actions[];
struct kobject { struct kobject {
const char * k_name; const char * k_name;
char name[KOBJ_NAME_LEN];
struct kref kref; struct kref kref;
struct list_head entry; struct list_head entry;
struct kobject * parent; struct kobject * parent;
...@@ -188,18 +187,18 @@ extern struct kobject * kset_find_obj(struct kset *, const char *); ...@@ -188,18 +187,18 @@ extern struct kobject * kset_find_obj(struct kset *, const char *);
* Use this when initializing an embedded kset with no other * Use this when initializing an embedded kset with no other
* fields to initialize. * fields to initialize.
*/ */
#define set_kset_name(str) .kset = { .kobj = { .name = str } } #define set_kset_name(str) .kset = { .kobj = { .k_name = str } }
#define decl_subsys(_name,_type,_uevent_ops) \ #define decl_subsys(_name,_type,_uevent_ops) \
struct kset _name##_subsys = { \ struct kset _name##_subsys = { \
.kobj = { .name = __stringify(_name) }, \ .kobj = { .k_name = __stringify(_name) }, \
.ktype = _type, \ .ktype = _type, \
.uevent_ops =_uevent_ops, \ .uevent_ops =_uevent_ops, \
} }
#define decl_subsys_name(_varname,_name,_type,_uevent_ops) \ #define decl_subsys_name(_varname,_name,_type,_uevent_ops) \
struct kset _varname##_subsys = { \ struct kset _varname##_subsys = { \
.kobj = { .name = __stringify(_name) }, \ .kobj = { .k_name = __stringify(_name) }, \
.ktype = _type, \ .ktype = _type, \
.uevent_ops =_uevent_ops, \ .uevent_ops =_uevent_ops, \
} }
......
...@@ -170,7 +170,7 @@ int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent) ...@@ -170,7 +170,7 @@ int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
if (!(kobj = kobject_get(kobj))) if (!(kobj = kobject_get(kobj)))
return -ENOENT; return -ENOENT;
if (!kobj->k_name) if (!kobj->k_name)
kobj->k_name = kobj->name; kobject_set_name(kobj, "NO_NAME");
if (!*kobj->k_name) { if (!*kobj->k_name) {
pr_debug("kobject attempted to be registered with no name!\n"); pr_debug("kobject attempted to be registered with no name!\n");
WARN_ON(1); WARN_ON(1);
...@@ -181,7 +181,7 @@ int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent) ...@@ -181,7 +181,7 @@ int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
pr_debug("kobject %s: registering. parent: %s, set: %s\n", pr_debug("kobject %s: registering. parent: %s, set: %s\n",
kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>", kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>",
kobj->kset ? kobj->kset->kobj.name : "<NULL>" ); kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>" );
if (kobj->kset) { if (kobj->kset) {
spin_lock(&kobj->kset->list_lock); spin_lock(&kobj->kset->list_lock);
...@@ -255,54 +255,50 @@ int kobject_register(struct kobject * kobj) ...@@ -255,54 +255,50 @@ int kobject_register(struct kobject * kobj)
int kobject_set_name(struct kobject * kobj, const char * fmt, ...) int kobject_set_name(struct kobject * kobj, const char * fmt, ...)
{ {
int error = 0; int error = 0;
int limit = KOBJ_NAME_LEN; int limit;
int need; int need;
va_list args; va_list args;
char * name; char *name;
/* /* find out how big a buffer we need */
* First, try the static array name = kmalloc(1024, GFP_KERNEL);
*/ if (!name) {
va_start(args,fmt); error = -ENOMEM;
need = vsnprintf(kobj->name,limit,fmt,args); goto done;
}
va_start(args, fmt);
need = vsnprintf(name, 1024, fmt, args);
va_end(args); va_end(args);
if (need < limit) kfree(name);
name = kobj->name;
else { /* Allocate the new space and copy the string in */
/* limit = need + 1;
* Need more space? Allocate it and try again name = kmalloc(limit, GFP_KERNEL);
*/ if (!name) {
limit = need + 1; error = -ENOMEM;
name = kmalloc(limit,GFP_KERNEL); goto done;
if (!name) { }
error = -ENOMEM; va_start(args, fmt);
goto Done; need = vsnprintf(name, limit, fmt, args);
} va_end(args);
va_start(args,fmt);
need = vsnprintf(name,limit,fmt,args); /* something wrong with the string we copied? */
va_end(args); if (need >= limit) {
kfree(name);
/* Still? Give up. */ error = -EFAULT;
if (need >= limit) { goto done;
kfree(name);
error = -EFAULT;
goto Done;
}
} }
/* Free the old name, if necessary. */ /* Free the old name, if necessary. */
if (kobj->k_name && kobj->k_name != kobj->name) kfree(kobj->k_name);
kfree(kobj->k_name);
/* Now, set the new name */ /* Now, set the new name */
kobj->k_name = name; kobj->k_name = name;
Done: done:
return error; return error;
} }
EXPORT_SYMBOL(kobject_set_name); EXPORT_SYMBOL(kobject_set_name);
/** /**
* kobject_rename - change the name of an object * kobject_rename - change the name of an object
* @kobj: object in question. * @kobj: object in question.
...@@ -477,13 +473,16 @@ void kobject_cleanup(struct kobject * kobj) ...@@ -477,13 +473,16 @@ void kobject_cleanup(struct kobject * kobj)
struct kobj_type * t = get_ktype(kobj); struct kobj_type * t = get_ktype(kobj);
struct kset * s = kobj->kset; struct kset * s = kobj->kset;
struct kobject * parent = kobj->parent; struct kobject * parent = kobj->parent;
const char *name = kobj->k_name;
pr_debug("kobject %s: cleaning up\n",kobject_name(kobj)); pr_debug("kobject %s: cleaning up\n",kobject_name(kobj));
if (kobj->k_name != kobj->name) if (t && t->release) {
kfree(kobj->k_name);
kobj->k_name = NULL;
if (t && t->release)
t->release(kobj); t->release(kobj);
/* If we have a release function, we can guess that this was
* not a statically allocated kobject, so we should be safe to
* free the name */
kfree(name);
}
if (s) if (s)
kset_put(s); kset_put(s);
kobject_put(parent); kobject_put(parent);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment