return error;
}
-static inline struct kobject *to_kobj(struct list_head *entry)
-{
- return container_of(entry, struct kobject, entry);
-}
-
static int get_kobj_path_length(struct kobject *kobj)
{
int length = 1;
}
pr_debug("kobject: '%s' (%p): %s: path = '%s'\n", kobject_name(kobj),
- kobj, __FUNCTION__, path);
+ kobj, __func__, path);
}
/**
return;
kref_init(&kobj->kref);
INIT_LIST_HEAD(&kobj->entry);
+ kobj->state_in_sysfs = 0;
+ kobj->state_add_uevent_sent = 0;
+ kobj->state_remove_uevent_sent = 0;
+ kobj->state_initialized = 1;
}
return -ENOENT;
if (!kobj->name || !kobj->name[0]) {
- pr_debug("kobject: (%p): attempted to be registered with empty "
+ WARN(1, "kobject: (%p): attempted to be registered with empty "
"name!\n", kobj);
- WARN_ON(1);
return -EINVAL;
}
}
pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n",
- kobject_name(kobj), kobj, __FUNCTION__,
+ kobject_name(kobj), kobj, __func__,
parent ? kobject_name(parent) : "<NULL>",
kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>");
printk(KERN_ERR "%s failed for %s with "
"-EEXIST, don't try to register things with "
"the same name in the same directory.\n",
- __FUNCTION__, kobject_name(kobj));
+ __func__, kobject_name(kobj));
else
printk(KERN_ERR "%s failed for %s (%d)\n",
- __FUNCTION__, kobject_name(kobj), error);
+ __func__, kobject_name(kobj), error);
dump_stack();
} else
kobj->state_in_sysfs = 1;
* @fmt: format string used to build the name
* @vargs: vargs to format the string.
*/
-static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
+int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
va_list vargs)
{
- va_list aq;
- char *name;
+ const char *old_name = kobj->name;
+ char *s;
- va_copy(aq, vargs);
- name = kvasprintf(GFP_KERNEL, fmt, vargs);
- va_end(aq);
+ if (kobj->name && !fmt)
+ return 0;
- if (!name)
+ kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs);
+ if (!kobj->name)
return -ENOMEM;
- /* Free the old name, if necessary. */
- kfree(kobj->name);
-
- /* Now, set the new name */
- kobj->name = name;
+ /* ewww... some of these buggers have '/' in the name ... */
+ while ((s = strchr(kobj->name, '/')))
+ s[0] = '!';
+ kfree(old_name);
return 0;
}
*/
int kobject_set_name(struct kobject *kobj, const char *fmt, ...)
{
- va_list args;
+ va_list vargs;
int retval;
- va_start(args, fmt);
- retval = kobject_set_name_vargs(kobj, fmt, args);
- va_end(args);
+ va_start(vargs, fmt);
+ retval = kobject_set_name_vargs(kobj, fmt, vargs);
+ va_end(vargs);
return retval;
}
dump_stack();
}
- kref_init(&kobj->kref);
- INIT_LIST_HEAD(&kobj->entry);
+ kobject_init_internal(kobj);
kobj->ktype = ktype;
- kobj->state_in_sysfs = 0;
- kobj->state_add_uevent_sent = 0;
- kobj->state_remove_uevent_sent = 0;
- kobj->state_initialized = 1;
return;
error:
static int kobject_add_varg(struct kobject *kobj, struct kobject *parent,
const char *fmt, va_list vargs)
{
- va_list aq;
int retval;
- va_copy(aq, vargs);
- retval = kobject_set_name_vargs(kobj, fmt, aq);
- va_end(aq);
+ retval = kobject_set_name_vargs(kobj, fmt, vargs);
if (retval) {
printk(KERN_ERR "kobject: can not set name properly!\n");
return retval;
* kobject_rename - change the name of an object
* @kobj: object in question.
* @new_name: object's new name
+ *
+ * It is the responsibility of the caller to provide mutual
+ * exclusion between two different calls of kobject_rename
+ * on the same kobject and to ensure that new_name is valid and
+ * won't conflict with other kobjects.
*/
int kobject_rename(struct kobject *kobj, const char *new_name)
{
int error = 0;
const char *devpath = NULL;
+ const char *dup_name = NULL, *name;
char *devpath_string = NULL;
char *envp[2];
if (!kobj->parent)
return -EINVAL;
- /* see if this name is already in use */
- if (kobj->kset) {
- struct kobject *temp_kobj;
- temp_kobj = kset_find_obj(kobj->kset, new_name);
- if (temp_kobj) {
- printk(KERN_WARNING "kobject '%s' cannot be renamed "
- "to '%s' as '%s' is already in existence.\n",
- kobject_name(kobj), new_name, new_name);
- kobject_put(temp_kobj);
- return -EINVAL;
- }
- }
-
devpath = kobject_get_path(kobj, GFP_KERNEL);
if (!devpath) {
error = -ENOMEM;
envp[0] = devpath_string;
envp[1] = NULL;
+ name = dup_name = kstrdup(new_name, GFP_KERNEL);
+ if (!name) {
+ error = -ENOMEM;
+ goto out;
+ }
+
error = sysfs_rename_dir(kobj, new_name);
+ if (error)
+ goto out;
+
+ /* Install the new kobject name */
+ dup_name = kobj->name;
+ kobj->name = 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);
+ kobject_uevent_env(kobj, KOBJ_MOVE, envp);
out:
+ kfree(dup_name);
kfree(devpath_string);
kfree(devpath);
kobject_put(kobj);
return error;
}
+EXPORT_SYMBOL_GPL(kobject_rename);
/**
* kobject_move - move object to another parent
const char *name = kobj->name;
pr_debug("kobject: '%s' (%p): %s\n",
- kobject_name(kobj), kobj, __FUNCTION__);
+ kobject_name(kobj), kobj, __func__);
if (t && !t->release)
pr_debug("kobject: '%s' (%p): does not have a release() "
*/
void kobject_put(struct kobject *kobj)
{
- if (kobj)
+ if (kobj) {
+ if (!kobj->state_initialized)
+ WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "
+ "initialized, yet kobject_put() is being "
+ "called.\n", kobject_name(kobj), kobj);
kref_put(&kobj->kref, kobject_release);
+ }
}
static void dynamic_kobj_release(struct kobject *kobj)
{
- pr_debug("kobject: (%p): %s\n", kobj, __FUNCTION__);
+ pr_debug("kobject: (%p): %s\n", kobj, __func__);
kfree(kobj);
}
retval = kobject_add(kobj, parent, "%s", name);
if (retval) {
printk(KERN_WARNING "%s: kobject_add error: %d\n",
- __FUNCTION__, retval);
+ __func__, retval);
kobject_put(kobj);
kobj = NULL;
}
*/
struct kobject *kset_find_obj(struct kset *kset, const char *name)
{
- struct list_head *entry;
+ struct kobject *k;
struct kobject *ret = NULL;
spin_lock(&kset->list_lock);
- list_for_each(entry, &kset->list) {
- struct kobject *k = to_kobj(entry);
+ list_for_each_entry(k, &kset->list, entry) {
if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
ret = kobject_get(k);
break;
{
struct kset *kset = container_of(kobj, struct kset, kobj);
pr_debug("kobject: '%s' (%p): %s\n",
- kobject_name(kobj), kobj, __FUNCTION__);
+ kobject_name(kobj), kobj, __func__);
kfree(kset);
}
struct kobject *parent_kobj)
{
struct kset *kset;
+ int retval;
kset = kzalloc(sizeof(*kset), GFP_KERNEL);
if (!kset)
return NULL;
- kobject_set_name(&kset->kobj, name);
+ retval = kobject_set_name(&kset->kobj, name);
+ if (retval) {
+ kfree(kset);
+ return NULL;
+ }
kset->uevent_ops = uevent_ops;
kset->kobj.parent = parent_kobj;