11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * kobject.c - library routines for handling generic kernel objects
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2002-2003 Patrick Mochel <mochel@osdl.org>
5f0e7e1bd77d450ebfa12153b90f93ad46616ab4aGreg Kroah-Hartman * Copyright (c) 2006-2007 Greg Kroah-Hartman <greg@kroah.com>
6f0e7e1bd77d450ebfa12153b90f93ad46616ab4aGreg Kroah-Hartman * Copyright (c) 2006-2007 Novell Inc.
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is released under the GPLv2.
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Please see the file Documentation/kobject.txt for critical information
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * about using the kobject interface.
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kobject.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h>
178bc3bcc93a2b4e47d5d410146f6546bca6171663Paul Gortmaker#include <linux/export.h>
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/stat.h>
194e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/slab.h>
2089c86a64cd056e283323710c9ddf6f7090a450c8Bjorn Helgaas#include <linux/random.h>
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo/**
23e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo * kobject_namespace - return @kobj's namespace tag
24e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo * @kobj: kobject in question
25e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo *
26e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo * Returns namespace tag of @kobj if its parent has namespace ops enabled
27e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo * and thus @kobj should have a namespace tag associated with it.  Returns
28e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo * %NULL otherwise.
29e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo */
30e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heoconst void *kobject_namespace(struct kobject *kobj)
31e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo{
32e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo	const struct kobj_ns_type_operations *ns_ops = kobj_ns_ops(kobj);
33e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo
34e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo	if (!ns_ops || ns_ops->type == KOBJ_NS_TYPE_NONE)
35e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo		return NULL;
36e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo
37a1212d278c05ca0a38f5cbd7ae90ac2e367228a8Linus Torvalds	return kobj->ktype->namespace(kobj);
38e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo}
39e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo
40e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman/*
41e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * populate_dir - populate directory with attributes.
42e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @kobj: object we're working on.
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
44e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * Most subsystems have a set of default attributes that are associated
45e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * with an object that registers with them.  This is a helper called during
46e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * object registration that loops through the default attributes of the
47e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * subsystem and creates attributes files for them in sysfs.
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
49e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartmanstatic int populate_dir(struct kobject *kobj)
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
51e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman	struct kobj_type *t = get_ktype(kobj);
52e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman	struct attribute *attr;
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int error = 0;
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
55e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (t && t->default_attrs) {
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (i = 0; (attr = t->default_attrs[i]) != NULL; i++) {
58e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman			error = sysfs_create_file(kobj, attr);
59e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman			if (error)
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return error;
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
66e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartmanstatic int create_dir(struct kobject *kobj)
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
68c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	const struct kobj_ns_type_operations *ops;
69e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo	int error;
70e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo
71e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo	error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj));
72c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	if (error)
73c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo		return error;
74c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo
75c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	error = populate_dir(kobj);
76c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	if (error) {
77c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo		sysfs_remove_dir(kobj);
78c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo		return error;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8026ea12dec0c84133add937455be76d44fe253d85Tejun Heo
8126ea12dec0c84133add937455be76d44fe253d85Tejun Heo	/*
8226ea12dec0c84133add937455be76d44fe253d85Tejun Heo	 * @kobj->sd may be deleted by an ancestor going away.  Hold an
8326ea12dec0c84133add937455be76d44fe253d85Tejun Heo	 * extra reference so that it stays until @kobj is gone.
8426ea12dec0c84133add937455be76d44fe253d85Tejun Heo	 */
8526ea12dec0c84133add937455be76d44fe253d85Tejun Heo	sysfs_get(kobj->sd);
8626ea12dec0c84133add937455be76d44fe253d85Tejun Heo
87c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	/*
88c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	 * If @kobj has ns_ops, its children need to be filtered based on
89c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	 * their namespace tags.  Enable namespace support on @kobj->sd.
90c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	 */
91c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	ops = kobj_child_ns_ops(kobj);
92c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	if (ops) {
93c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo		BUG_ON(ops->type <= KOBJ_NS_TYPE_NONE);
94c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo		BUG_ON(ops->type >= KOBJ_NS_TYPES);
95c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo		BUG_ON(!kobj_ns_type_registered(ops->type));
96c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo
97fa4cd451cceb77e97432b91fcf50a7e4a7361e29Tejun Heo		sysfs_enable_ns(kobj->sd);
98c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	}
99c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo
100c84a3b27798dfce928b867fa1c9f3c3fd66f0a31Tejun Heo	return 0;
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int get_kobj_path_length(struct kobject *kobj)
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int length = 1;
106e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman	struct kobject *parent = kobj;
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
108e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman	/* walk up the ancestors until we hit the one pointing to the
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * root.
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Add 1 to strlen for leading '/' of each level.
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	do {
113b365b3daf2a9e2a8b002ea9fef877af1c71513fdChuck Ebbert		if (kobject_name(parent) == NULL)
114b365b3daf2a9e2a8b002ea9fef877af1c71513fdChuck Ebbert			return 0;
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		length += strlen(kobject_name(parent)) + 1;
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		parent = parent->parent;
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} while (parent);
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return length;
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void fill_kobj_path(struct kobject *kobj, char *path, int length)
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
123e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman	struct kobject *parent;
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	--length;
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (parent = kobj; parent; parent = parent->parent) {
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int cur = strlen(kobject_name(parent));
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* back up enough to print this name with '/' */
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		length -= cur;
130e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman		strncpy(path + length, kobject_name(parent), cur);
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*(path + --length) = '/';
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1349f66fa2a4690a16da0dbaae2f44ddfc313802504Greg Kroah-Hartman	pr_debug("kobject: '%s' (%p): %s: path = '%s'\n", kobject_name(kobj),
135810304db75b0ca4e6ef071f86aa3e85fdaddee5eHarvey Harrison		 kobj, __func__, path);
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
13972fd4a35a824331d7a0f4168d7576502d95d34b3Robert P. J. Day * kobject_get_path - generate and return the path associated with a given kobj and kset pair.
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @kobj:	kobject in question, with which to build the path
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @gfp_mask:	the allocation type used to allocate the path
14372fd4a35a824331d7a0f4168d7576502d95d34b3Robert P. J. Day *
14472fd4a35a824331d7a0f4168d7576502d95d34b3Robert P. J. Day * The result must be freed by the caller with kfree().
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
146fd4f2df24bc23e6b8fc069765b425c7dacf52347Al Virochar *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *path;
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int len;
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	len = get_kobj_path_length(kobj);
152b365b3daf2a9e2a8b002ea9fef877af1c71513fdChuck Ebbert	if (len == 0)
153b365b3daf2a9e2a8b002ea9fef877af1c71513fdChuck Ebbert		return NULL;
1544668edc334ee90cf50c382c3e423cfc510b5a126Burman Yan	path = kzalloc(len, gfp_mask);
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!path)
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fill_kobj_path(kobj, path, len);
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return path;
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16180fc9f532d8c05d4cb12d55660624ce53a378349Dmitry TorokhovEXPORT_SYMBOL_GPL(kobject_get_path);
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1630f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers/* add the kobject to its kset's list */
1640f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sieversstatic void kobj_kset_join(struct kobject *kobj)
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1660f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	if (!kobj->kset)
16731b9025aa0f89b392077db3f87458fd46bcc4f58Greg Kroah-Hartman		return;
1680f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers
1690f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	kset_get(kobj->kset);
1700f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	spin_lock(&kobj->kset->list_lock);
1710f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	list_add_tail(&kobj->entry, &kobj->kset->list);
1720f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	spin_unlock(&kobj->kset->list_lock);
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1750f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers/* remove the kobject from its kset's list */
1760f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sieversstatic void kobj_kset_leave(struct kobject *kobj)
1770f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers{
1780f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	if (!kobj->kset)
1790f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		return;
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1810f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	spin_lock(&kobj->kset->list_lock);
1820f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	list_del_init(&kobj->entry);
1830f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	spin_unlock(&kobj->kset->list_lock);
1840f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	kset_put(kobj->kset);
1850f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers}
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
187e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartmanstatic void kobject_init_internal(struct kobject *kobj)
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1890f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	if (!kobj)
1900f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		return;
1910f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	kref_init(&kobj->kref);
1920f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	INIT_LIST_HEAD(&kobj->entry);
193a4573c488dd531c6e2d308ce8a7413c4a2646207Greg Kroah-Hartman	kobj->state_in_sysfs = 0;
194a4573c488dd531c6e2d308ce8a7413c4a2646207Greg Kroah-Hartman	kobj->state_add_uevent_sent = 0;
195a4573c488dd531c6e2d308ce8a7413c4a2646207Greg Kroah-Hartman	kobj->state_remove_uevent_sent = 0;
196a4573c488dd531c6e2d308ce8a7413c4a2646207Greg Kroah-Hartman	kobj->state_initialized = 1;
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1990f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers
2009e7bbccd0290e720e0874443932869c55f63d5a8Greg Kroah-Hartmanstatic int kobject_add_internal(struct kobject *kobj)
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int error = 0;
203e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman	struct kobject *parent;
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2050f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	if (!kobj)
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOENT;
2070f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers
208af5ca3f4ec5cc4432a42a73b050dd8898ce8fd00Kay Sievers	if (!kobj->name || !kobj->name[0]) {
209d955c78ac4699ac9c3fe07be62982cda13d13267Arjan van de Ven		WARN(1, "kobject: (%p): attempted to be registered with empty "
2109f66fa2a4690a16da0dbaae2f44ddfc313802504Greg Kroah-Hartman			 "name!\n", kobj);
211c171fef5c8566cf5f57877e7832fa696ecdf5228Greg Kroah-Hartman		return -EINVAL;
212c171fef5c8566cf5f57877e7832fa696ecdf5228Greg Kroah-Hartman	}
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2140f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	parent = kobject_get(kobj->parent);
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2160f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	/* join kset if set, use it as parent if we do not already have one */
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (kobj->kset) {
2180f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		if (!parent)
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			parent = kobject_get(&kobj->kset->kobj);
2200f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		kobj_kset_join(kobj);
221460f7e9a1bde2c74f060f7ce0a308dab4be6a56bDmitriy Monakhov		kobj->parent = parent;
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2240f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n",
225810304db75b0ca4e6ef071f86aa3e85fdaddee5eHarvey Harrison		 kobject_name(kobj), kobj, __func__,
2260f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		 parent ? kobject_name(parent) : "<NULL>",
227e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman		 kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>");
2280f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers
22990bc61359de0148f8627073d68a22edc7ed9893dEric W. Biederman	error = create_dir(kobj);
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (error) {
2310f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		kobj_kset_leave(kobj);
2320f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		kobject_put(parent);
2330f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		kobj->parent = NULL;
234dcd0da002122a70fe1c625c0ca9f58c95aa33ebeGreg Kroah-Hartman
235dcd0da002122a70fe1c625c0ca9f58c95aa33ebeGreg Kroah-Hartman		/* be noisy on error issues */
236dcd0da002122a70fe1c625c0ca9f58c95aa33ebeGreg Kroah-Hartman		if (error == -EEXIST)
237282029c005e65ffdce3aa9f8220f88a8bbbc4daeDan Williams			WARN(1, "%s failed for %s with "
238282029c005e65ffdce3aa9f8220f88a8bbbc4daeDan Williams			     "-EEXIST, don't try to register things with "
239282029c005e65ffdce3aa9f8220f88a8bbbc4daeDan Williams			     "the same name in the same directory.\n",
240282029c005e65ffdce3aa9f8220f88a8bbbc4daeDan Williams			     __func__, kobject_name(kobj));
241dcd0da002122a70fe1c625c0ca9f58c95aa33ebeGreg Kroah-Hartman		else
242282029c005e65ffdce3aa9f8220f88a8bbbc4daeDan Williams			WARN(1, "%s failed for %s (error: %d parent: %s)\n",
243282029c005e65ffdce3aa9f8220f88a8bbbc4daeDan Williams			     __func__, kobject_name(kobj), error,
244282029c005e65ffdce3aa9f8220f88a8bbbc4daeDan Williams			     parent ? kobject_name(parent) : "'none'");
2450f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	} else
2460f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		kobj->state_in_sysfs = 1;
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return error;
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
251b592fcfe7f06c15ec11774b5be7ce0de3aa86e73Eric W. Biederman/**
252663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman * kobject_set_name_vargs - Set the name of an kobject
253663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman * @kobj: struct kobject to set the name of
254663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman * @fmt: format string used to build the name
255663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman * @vargs: vargs to format the string.
256663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman */
2571fa5ae857bb14f6046205171d98506d8112dd74eKay Sieversint kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
258663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman				  va_list vargs)
259663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman{
2609f255651fb41c111ee35a2ae632df8ce9bd61defKay Sievers	const char *old_name = kobj->name;
2619f255651fb41c111ee35a2ae632df8ce9bd61defKay Sievers	char *s;
262663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman
2638a577ffc75d9194fe8cdb7479236f2081c26ca1fKay Sievers	if (kobj->name && !fmt)
2648a577ffc75d9194fe8cdb7479236f2081c26ca1fKay Sievers		return 0;
2658a577ffc75d9194fe8cdb7479236f2081c26ca1fKay Sievers
266a4ca6617421188f50774780cdc91c3782b7d08feKay Sievers	kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs);
267020d30f17f196dcbf0c2c68a874345e8885a3149Maurizio Lombardi	if (!kobj->name) {
268020d30f17f196dcbf0c2c68a874345e8885a3149Maurizio Lombardi		kobj->name = old_name;
269a4ca6617421188f50774780cdc91c3782b7d08feKay Sievers		return -ENOMEM;
270020d30f17f196dcbf0c2c68a874345e8885a3149Maurizio Lombardi	}
271663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman
2729f255651fb41c111ee35a2ae632df8ce9bd61defKay Sievers	/* ewww... some of these buggers have '/' in the name ... */
27325fdeb3f4468595ab2885687b13515fa848731c2Ingo Oeser	while ((s = strchr(kobj->name, '/')))
2749f255651fb41c111ee35a2ae632df8ce9bd61defKay Sievers		s[0] = '!';
2759f255651fb41c111ee35a2ae632df8ce9bd61defKay Sievers
2769f255651fb41c111ee35a2ae632df8ce9bd61defKay Sievers	kfree(old_name);
277663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman	return 0;
278663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman}
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
2818c4606b1a4f6eb09344294b7f11641f36cd402afGreg Kroah-Hartman * kobject_set_name - Set the name of a kobject
282663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman * @kobj: struct kobject to set the name of
2838c4606b1a4f6eb09344294b7f11641f36cd402afGreg Kroah-Hartman * @fmt: format string used to build the name
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2858c4606b1a4f6eb09344294b7f11641f36cd402afGreg Kroah-Hartman * This sets the name of the kobject.  If you have already added the
2868c4606b1a4f6eb09344294b7f11641f36cd402afGreg Kroah-Hartman * kobject to the system, you must call kobject_rename() in order to
2878c4606b1a4f6eb09344294b7f11641f36cd402afGreg Kroah-Hartman * change the name of the kobject.
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
289663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartmanint kobject_set_name(struct kobject *kobj, const char *fmt, ...)
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
291a4ca6617421188f50774780cdc91c3782b7d08feKay Sievers	va_list vargs;
292663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman	int retval;
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
294a4ca6617421188f50774780cdc91c3782b7d08feKay Sievers	va_start(vargs, fmt);
295a4ca6617421188f50774780cdc91c3782b7d08feKay Sievers	retval = kobject_set_name_vargs(kobj, fmt, vargs);
296a4ca6617421188f50774780cdc91c3782b7d08feKay Sievers	va_end(vargs);
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
298663a47430b361f863b515752a97166a7a4b92d35Greg Kroah-Hartman	return retval;
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(kobject_set_name);
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
303f9cb074bff8e762ef24c44678a5a7d907f82fbebGreg Kroah-Hartman * kobject_init - initialize a kobject structure
304e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman * @kobj: pointer to the kobject to initialize
305e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman * @ktype: pointer to the ktype for this kobject.
306e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman *
307e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman * This function will properly initialize a kobject such that it can then
308e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman * be passed to the kobject_add() call.
309e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman *
310e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman * After this function is called, the kobject MUST be cleaned up by a call
311e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman * to kobject_put(), not by a call to kfree directly to ensure that all of
312e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman * the memory is cleaned up properly.
313e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman */
314f9cb074bff8e762ef24c44678a5a7d907f82fbebGreg Kroah-Hartmanvoid kobject_init(struct kobject *kobj, struct kobj_type *ktype)
315e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman{
316e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman	char *err_str;
317e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman
318e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman	if (!kobj) {
319e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman		err_str = "invalid kobject pointer!";
320e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman		goto error;
321e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman	}
322e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman	if (!ktype) {
323e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman		err_str = "must have a ktype to be initialized properly!\n";
324e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman		goto error;
325e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman	}
3260f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	if (kobj->state_initialized) {
327e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman		/* do not error out as sometimes we can recover */
3280f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		printk(KERN_ERR "kobject (%p): tried to init an initialized "
3290f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		       "object, something is seriously wrong.\n", kobj);
330e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman		dump_stack();
331e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman	}
332e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman
333a4573c488dd531c6e2d308ce8a7413c4a2646207Greg Kroah-Hartman	kobject_init_internal(kobj);
334e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman	kobj->ktype = ktype;
335e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman	return;
336e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman
337e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartmanerror:
3380f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	printk(KERN_ERR "kobject (%p): %s\n", kobj, err_str);
339e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman	dump_stack();
340e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman}
341f9cb074bff8e762ef24c44678a5a7d907f82fbebGreg Kroah-HartmanEXPORT_SYMBOL(kobject_init);
342e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman
343244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartmanstatic int kobject_add_varg(struct kobject *kobj, struct kobject *parent,
344244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman			    const char *fmt, va_list vargs)
345244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman{
346244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman	int retval;
347244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman
348a4ca6617421188f50774780cdc91c3782b7d08feKay Sievers	retval = kobject_set_name_vargs(kobj, fmt, vargs);
349244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman	if (retval) {
350244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman		printk(KERN_ERR "kobject: can not set name properly!\n");
351244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman		return retval;
352244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman	}
353244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman	kobj->parent = parent;
3549e7bbccd0290e720e0874443932869c55f63d5a8Greg Kroah-Hartman	return kobject_add_internal(kobj);
355244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman}
356244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman
357244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman/**
358b2d6db5878a0832659ed58476357eea2db915550Greg Kroah-Hartman * kobject_add - the main kobject add function
359244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * @kobj: the kobject to add
360244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * @parent: pointer to the parent of the kobject.
361244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * @fmt: format to name the kobject with.
362244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman *
363244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * The kobject name is set and added to the kobject hierarchy in this
364244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * function.
365244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman *
366244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * If @parent is set, then the parent of the @kobj will be set to it.
367244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * If @parent is NULL, then the parent of the @kobj will be set to the
3689705710e40b9e5acaf003f90d6ed883ba193b314Bart Van Assche * kobject associated with the kset assigned to this kobject.  If no kset
369244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * is assigned to the kobject, then the kobject will be located in the
370244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * root of the sysfs tree.
371244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman *
372244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * If this function returns an error, kobject_put() must be called to
373244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * properly clean up the memory associated with the object.
374244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * Under no instance should the kobject that is passed to this function
375244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * be directly freed with a call to kfree(), that can leak memory.
376244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman *
3770f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers * Note, no "add" uevent will be created with this call, the caller should set
378244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * up all of the necessary sysfs files for the object and then call
379244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * kobject_uevent() with the UEVENT_ADD parameter to ensure that
380244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman * userspace is properly notified of this kobject's creation.
381244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman */
382b2d6db5878a0832659ed58476357eea2db915550Greg Kroah-Hartmanint kobject_add(struct kobject *kobj, struct kobject *parent,
383b2d6db5878a0832659ed58476357eea2db915550Greg Kroah-Hartman		const char *fmt, ...)
384244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman{
385244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman	va_list args;
386244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman	int retval;
387244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman
388244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman	if (!kobj)
389244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman		return -EINVAL;
390244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman
3910f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	if (!kobj->state_initialized) {
3920f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		printk(KERN_ERR "kobject '%s' (%p): tried to add an "
3930f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		       "uninitialized object, something is seriously wrong.\n",
3940f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		       kobject_name(kobj), kobj);
3950f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		dump_stack();
3960f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		return -EINVAL;
3970f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	}
398244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman	va_start(args, fmt);
399244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman	retval = kobject_add_varg(kobj, parent, fmt, args);
400244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman	va_end(args);
401244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman
402244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman	return retval;
403244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman}
404b2d6db5878a0832659ed58476357eea2db915550Greg Kroah-HartmanEXPORT_SYMBOL(kobject_add);
405244f6cee9a928103132a722292bfa0eb84114b07Greg Kroah-Hartman
406e86000d042d23904bbb609af2f8618a541cf129bGreg Kroah-Hartman/**
407c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman * kobject_init_and_add - initialize a kobject structure and add it to the kobject hierarchy
408c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman * @kobj: pointer to the kobject to initialize
409c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman * @ktype: pointer to the ktype for this kobject.
410c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman * @parent: pointer to the parent of this kobject.
411c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman * @fmt: the name of the kobject.
412c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman *
413f9cb074bff8e762ef24c44678a5a7d907f82fbebGreg Kroah-Hartman * This function combines the call to kobject_init() and
414b2d6db5878a0832659ed58476357eea2db915550Greg Kroah-Hartman * kobject_add().  The same type of error handling after a call to
415b2d6db5878a0832659ed58476357eea2db915550Greg Kroah-Hartman * kobject_add() and kobject lifetime rules are the same here.
416c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman */
417c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartmanint kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
418c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman			 struct kobject *parent, const char *fmt, ...)
419c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman{
420c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman	va_list args;
421c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman	int retval;
422c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman
423f9cb074bff8e762ef24c44678a5a7d907f82fbebGreg Kroah-Hartman	kobject_init(kobj, ktype);
424c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman
425c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman	va_start(args, fmt);
426c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman	retval = kobject_add_varg(kobj, parent, fmt, args);
427c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman	va_end(args);
428c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman
429c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman	return retval;
430c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman}
431c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-HartmanEXPORT_SYMBOL_GPL(kobject_init_and_add);
432c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman
433c11c4154e7ff4cebfadad849b1e22689d759c3f4Greg Kroah-Hartman/**
434e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * kobject_rename - change the name of an object
435e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @kobj: object in question.
436e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @new_name: object's new name
437030c1d2bfcc2187650fb975456ca0b61a5bb77f4Eric W. Biederman *
438030c1d2bfcc2187650fb975456ca0b61a5bb77f4Eric W. Biederman * It is the responsibility of the caller to provide mutual
439030c1d2bfcc2187650fb975456ca0b61a5bb77f4Eric W. Biederman * exclusion between two different calls of kobject_rename
440030c1d2bfcc2187650fb975456ca0b61a5bb77f4Eric W. Biederman * on the same kobject and to ensure that new_name is valid and
441030c1d2bfcc2187650fb975456ca0b61a5bb77f4Eric W. Biederman * won't conflict with other kobjects.
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
443e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartmanint kobject_rename(struct kobject *kobj, const char *new_name)
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int error = 0;
446ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	const char *devpath = NULL;
4470b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman	const char *dup_name = NULL, *name;
448ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	char *devpath_string = NULL;
449ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	char *envp[2];
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kobj = kobject_get(kobj);
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!kobj)
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
454b592fcfe7f06c15ec11774b5be7ce0de3aa86e73Eric W. Biederman	if (!kobj->parent)
455b592fcfe7f06c15ec11774b5be7ce0de3aa86e73Eric W. Biederman		return -EINVAL;
456ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes
457ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	devpath = kobject_get_path(kobj, GFP_KERNEL);
458ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	if (!devpath) {
459ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes		error = -ENOMEM;
460ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes		goto out;
461ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	}
462ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);
463ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	if (!devpath_string) {
464ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes		error = -ENOMEM;
465ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes		goto out;
466ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	}
467ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
468ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	envp[0] = devpath_string;
469ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	envp[1] = NULL;
470ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes
4710b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman	name = dup_name = kstrdup(new_name, GFP_KERNEL);
4720b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman	if (!name) {
4730b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman		error = -ENOMEM;
4740b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman		goto out;
4750b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman	}
4760b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman
477e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo	error = sysfs_rename_dir_ns(kobj, new_name, kobject_namespace(kobj));
4780b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman	if (error)
4790b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman		goto out;
4800b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman
4810b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman	/* Install the new kobject name */
4820b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman	dup_name = kobj->name;
4830b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman	kobj->name = name;
484ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes
485ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	/* This function is mostly/only used for network interface.
486ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	 * Some hotplug package track interfaces by their name and
487ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	 * therefore want to know when the name is changed by the user. */
4880b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman	kobject_uevent_env(kobj, KOBJ_MOVE, envp);
489ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes
490ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhesout:
4910b4a4fea253e1296222603ccc55430ed7cd9413aEric W. Biederman	kfree(dup_name);
492ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	kfree(devpath_string);
493ca2f37dbc5324c7278577731033a358f1f86050aJean Tourrilhes	kfree(devpath);
494b592fcfe7f06c15ec11774b5be7ce0de3aa86e73Eric W. Biederman	kobject_put(kobj);
495b592fcfe7f06c15ec11774b5be7ce0de3aa86e73Eric W. Biederman
496b592fcfe7f06c15ec11774b5be7ce0de3aa86e73Eric W. Biederman	return error;
497b592fcfe7f06c15ec11774b5be7ce0de3aa86e73Eric W. Biederman}
4988344b568f5bdc7ee1bba909de3294c6348c36056Alex ChiangEXPORT_SYMBOL_GPL(kobject_rename);
499b592fcfe7f06c15ec11774b5be7ce0de3aa86e73Eric W. Biederman
500b592fcfe7f06c15ec11774b5be7ce0de3aa86e73Eric W. Biederman/**
501e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * kobject_move - move object to another parent
502e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @kobj: object in question.
503e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @new_parent: object's new parent (can be NULL)
5048a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck */
5058a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huckint kobject_move(struct kobject *kobj, struct kobject *new_parent)
5068a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck{
5078a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	int error;
5088a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	struct kobject *old_parent;
5098a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	const char *devpath = NULL;
5108a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	char *devpath_string = NULL;
5118a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	char *envp[2];
5128a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck
5138a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	kobj = kobject_get(kobj);
5148a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (!kobj)
5158a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		return -EINVAL;
5168a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	new_parent = kobject_get(new_parent);
5178a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (!new_parent) {
518c744aeae9d173a953b771a7ad5c872f91fa99decCornelia Huck		if (kobj->kset)
519c744aeae9d173a953b771a7ad5c872f91fa99decCornelia Huck			new_parent = kobject_get(&kobj->kset->kobj);
5208a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	}
521e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo
5228a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	/* old object path */
5238a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	devpath = kobject_get_path(kobj, GFP_KERNEL);
5248a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (!devpath) {
5258a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		error = -ENOMEM;
5268a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		goto out;
5278a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	}
5288a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);
5298a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (!devpath_string) {
5308a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		error = -ENOMEM;
5318a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		goto out;
5328a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	}
5338a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
5348a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	envp[0] = devpath_string;
5358a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	envp[1] = NULL;
536e34ff4906199d2ebd248ae897ae34f52bea151c9Tejun Heo	error = sysfs_move_dir_ns(kobj, new_parent, kobject_namespace(kobj));
5378a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (error)
5388a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		goto out;
5398a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	old_parent = kobj->parent;
5408a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	kobj->parent = new_parent;
5419e993efb0da827634778554070f3c3ec4bdade33Dmitriy Monakhov	new_parent = NULL;
5428a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	kobject_put(old_parent);
5438a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	kobject_uevent_env(kobj, KOBJ_MOVE, envp);
5448a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huckout:
5459e993efb0da827634778554070f3c3ec4bdade33Dmitriy Monakhov	kobject_put(new_parent);
5468a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	kobject_put(kobj);
5478a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	kfree(devpath_string);
5488a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	kfree(devpath);
5498a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	return error;
5508a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck}
5518a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck
5528a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck/**
553e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * kobject_del - unlink kobject from hierarchy.
554e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @kobj: object.
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
556e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartmanvoid kobject_del(struct kobject *kobj)
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
558324a56e16e44baecac3ca799fd216154145c14bfTejun Heo	struct kernfs_node *sd;
55926ea12dec0c84133add937455be76d44fe253d85Tejun Heo
56031b9025aa0f89b392077db3f87458fd46bcc4f58Greg Kroah-Hartman	if (!kobj)
56131b9025aa0f89b392077db3f87458fd46bcc4f58Greg Kroah-Hartman		return;
5620f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers
56326ea12dec0c84133add937455be76d44fe253d85Tejun Heo	sd = kobj->sd;
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sysfs_remove_dir(kobj);
56526ea12dec0c84133add937455be76d44fe253d85Tejun Heo	sysfs_put(sd);
56626ea12dec0c84133add937455be76d44fe253d85Tejun Heo
5670f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	kobj->state_in_sysfs = 0;
5680f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	kobj_kset_leave(kobj);
5690f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	kobject_put(kobj->parent);
5700f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	kobj->parent = NULL;
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
574e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * kobject_get - increment refcount for object.
575e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @kobj: object.
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
577e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartmanstruct kobject *kobject_get(struct kobject *kobj)
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (kobj)
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kref_get(&kobj->kref);
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return kobj;
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5842d864e41710f1d2ba406fb62018ab0487152e6f2Anatol Pomozovstatic struct kobject * __must_check kobject_get_unless_zero(struct kobject *kobj)
585a49b7e82cab0f9b41f483359be83f44fbb6b4979Linus Torvalds{
586a49b7e82cab0f9b41f483359be83f44fbb6b4979Linus Torvalds	if (!kref_get_unless_zero(&kobj->kref))
587a49b7e82cab0f9b41f483359be83f44fbb6b4979Linus Torvalds		kobj = NULL;
588a49b7e82cab0f9b41f483359be83f44fbb6b4979Linus Torvalds	return kobj;
589a49b7e82cab0f9b41f483359be83f44fbb6b4979Linus Torvalds}
590a49b7e82cab0f9b41f483359be83f44fbb6b4979Linus Torvalds
59118041f4775688af073d9b3ab0ffc262c1847e60bGreg Kroah-Hartman/*
59218041f4775688af073d9b3ab0ffc262c1847e60bGreg Kroah-Hartman * kobject_cleanup - free kobject resources.
59318041f4775688af073d9b3ab0ffc262c1847e60bGreg Kroah-Hartman * @kobj: object to cleanup
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
59518041f4775688af073d9b3ab0ffc262c1847e60bGreg Kroah-Hartmanstatic void kobject_cleanup(struct kobject *kobj)
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5970f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	struct kobj_type *t = get_ktype(kobj);
598af5ca3f4ec5cc4432a42a73b050dd8898ce8fd00Kay Sievers	const char *name = kobj->name;
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
600c817a67ecba7c3c2aaa104796d78f160af60920dRussell King	pr_debug("kobject: '%s' (%p): %s, parent %p\n",
601c817a67ecba7c3c2aaa104796d78f160af60920dRussell King		 kobject_name(kobj), kobj, __func__, kobj->parent);
6020f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers
6030f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	if (t && !t->release)
6040f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		pr_debug("kobject: '%s' (%p): does not have a release() "
6050f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers			 "function, it is broken and must be fixed.\n",
6060f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers			 kobject_name(kobj), kobj);
6070f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers
6080f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	/* send "remove" if the caller did not do it but sent "add" */
6090f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) {
6100f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		pr_debug("kobject: '%s' (%p): auto cleanup 'remove' event\n",
6110f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers			 kobject_name(kobj), kobj);
6120f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		kobject_uevent(kobj, KOBJ_REMOVE);
6130f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	}
6140f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers
6150f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	/* remove from sysfs if the caller did not do it */
6160f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	if (kobj->state_in_sysfs) {
6170f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		pr_debug("kobject: '%s' (%p): auto cleanup kobject_del\n",
6180f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers			 kobject_name(kobj), kobj);
6190f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		kobject_del(kobj);
6200f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	}
6210f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers
622ce2c9cb0259acd2aed184499ebe41ab00da13b25Greg Kroah-Hartman	if (t && t->release) {
6230f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		pr_debug("kobject: '%s' (%p): calling ktype release\n",
6240f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers			 kobject_name(kobj), kobj);
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		t->release(kobj);
6260f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	}
6270f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers
6280f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers	/* free name if we allocated it */
629af5ca3f4ec5cc4432a42a73b050dd8898ce8fd00Kay Sievers	if (name) {
6300f4dafc0563c6c49e17fe14b3f5f356e4c4b8806Kay Sievers		pr_debug("kobject: '%s': free name\n", name);
631ce2c9cb0259acd2aed184499ebe41ab00da13b25Greg Kroah-Hartman		kfree(name);
632ce2c9cb0259acd2aed184499ebe41ab00da13b25Greg Kroah-Hartman	}
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
635c817a67ecba7c3c2aaa104796d78f160af60920dRussell King#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
636c817a67ecba7c3c2aaa104796d78f160af60920dRussell Kingstatic void kobject_delayed_cleanup(struct work_struct *work)
637c817a67ecba7c3c2aaa104796d78f160af60920dRussell King{
638c817a67ecba7c3c2aaa104796d78f160af60920dRussell King	kobject_cleanup(container_of(to_delayed_work(work),
639c817a67ecba7c3c2aaa104796d78f160af60920dRussell King				     struct kobject, release));
640c817a67ecba7c3c2aaa104796d78f160af60920dRussell King}
641c817a67ecba7c3c2aaa104796d78f160af60920dRussell King#endif
642c817a67ecba7c3c2aaa104796d78f160af60920dRussell King
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void kobject_release(struct kref *kref)
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
645c817a67ecba7c3c2aaa104796d78f160af60920dRussell King	struct kobject *kobj = container_of(kref, struct kobject, kref);
646c817a67ecba7c3c2aaa104796d78f160af60920dRussell King#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
64789c86a64cd056e283323710c9ddf6f7090a450c8Bjorn Helgaas	unsigned long delay = HZ + HZ * (get_random_int() & 0x3);
64889c86a64cd056e283323710c9ddf6f7090a450c8Bjorn Helgaas	pr_info("kobject: '%s' (%p): %s, parent %p (delayed %ld)\n",
64989c86a64cd056e283323710c9ddf6f7090a450c8Bjorn Helgaas		 kobject_name(kobj), kobj, __func__, kobj->parent, delay);
650c817a67ecba7c3c2aaa104796d78f160af60920dRussell King	INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup);
65189c86a64cd056e283323710c9ddf6f7090a450c8Bjorn Helgaas
65289c86a64cd056e283323710c9ddf6f7090a450c8Bjorn Helgaas	schedule_delayed_work(&kobj->release, delay);
653c817a67ecba7c3c2aaa104796d78f160af60920dRussell King#else
654c817a67ecba7c3c2aaa104796d78f160af60920dRussell King	kobject_cleanup(kobj);
655c817a67ecba7c3c2aaa104796d78f160af60920dRussell King#endif
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
659e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * kobject_put - decrement refcount for object.
660e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @kobj: object.
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
662e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * Decrement the refcount, and if 0, call kobject_cleanup().
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
664e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartmanvoid kobject_put(struct kobject *kobj)
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
666c1ebdae514a356c71c09035f5141d94aab5e8fe4Greg Kroah-Hartman	if (kobj) {
667d955c78ac4699ac9c3fe07be62982cda13d13267Arjan van de Ven		if (!kobj->state_initialized)
668d955c78ac4699ac9c3fe07be62982cda13d13267Arjan van de Ven			WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "
669c1ebdae514a356c71c09035f5141d94aab5e8fe4Greg Kroah-Hartman			       "initialized, yet kobject_put() is being "
670c1ebdae514a356c71c09035f5141d94aab5e8fe4Greg Kroah-Hartman			       "called.\n", kobject_name(kobj), kobj);
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kref_put(&kobj->kref, kobject_release);
672c1ebdae514a356c71c09035f5141d94aab5e8fe4Greg Kroah-Hartman	}
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6753f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartmanstatic void dynamic_kobj_release(struct kobject *kobj)
6767423172a50968de1905a61413c52bb070a62f5ceJun'ichi Nomura{
677810304db75b0ca4e6ef071f86aa3e85fdaddee5eHarvey Harrison	pr_debug("kobject: (%p): %s\n", kobj, __func__);
6787423172a50968de1905a61413c52bb070a62f5ceJun'ichi Nomura	kfree(kobj);
6797423172a50968de1905a61413c52bb070a62f5ceJun'ichi Nomura}
6807423172a50968de1905a61413c52bb070a62f5ceJun'ichi Nomura
6813f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartmanstatic struct kobj_type dynamic_kobj_ktype = {
682386f275f5d097758f867bc99ddeaeb7a03b6b190Kay Sievers	.release	= dynamic_kobj_release,
683386f275f5d097758f867bc99ddeaeb7a03b6b190Kay Sievers	.sysfs_ops	= &kobj_sysfs_ops,
6847423172a50968de1905a61413c52bb070a62f5ceJun'ichi Nomura};
6857423172a50968de1905a61413c52bb070a62f5ceJun'ichi Nomura
68643968d2f1648f4dc92437dc0363a3e88377445b3Greg Kroah-Hartman/**
6873f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman * kobject_create - create a struct kobject dynamically
6883f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman *
6893f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman * This function creates a kobject structure dynamically and sets it up
6903f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman * to be a "dynamic" kobject with a default release function set up.
6913f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman *
6923f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman * If the kobject was not able to be created, NULL will be returned.
69343968d2f1648f4dc92437dc0363a3e88377445b3Greg Kroah-Hartman * The kobject structure returned from here must be cleaned up with a
694f9cb074bff8e762ef24c44678a5a7d907f82fbebGreg Kroah-Hartman * call to kobject_put() and not kfree(), as kobject_init() has
69543968d2f1648f4dc92437dc0363a3e88377445b3Greg Kroah-Hartman * already been called on this structure.
6963f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman */
69743968d2f1648f4dc92437dc0363a3e88377445b3Greg Kroah-Hartmanstruct kobject *kobject_create(void)
6983f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman{
6993f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman	struct kobject *kobj;
7003f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman
7013f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
7023f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman	if (!kobj)
7033f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman		return NULL;
7043f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman
705f9cb074bff8e762ef24c44678a5a7d907f82fbebGreg Kroah-Hartman	kobject_init(kobj, &dynamic_kobj_ktype);
7063f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman	return kobj;
7073f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman}
7083f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman
7093f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman/**
7103f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman * kobject_create_and_add - create a struct kobject dynamically and register it with sysfs
7113f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman *
7129ff1f838e9c019b16b720dca9b04565f1a6e0316Zhi Yong Wu * @name: the name for the kobject
7133f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman * @parent: the parent kobject of this kobject, if any.
7143f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman *
715f70701a34e217fd5f4f180f7bf4bb5c137d76e8aDave Young * This function creates a kobject structure dynamically and registers it
7163f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman * with sysfs.  When you are finished with this structure, call
71778a2d906b40fe530ea800c1e873bfe8f02326f1eGreg Kroah-Hartman * kobject_put() and the structure will be dynamically freed when
7183f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman * it is no longer being used.
7193f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman *
7203f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman * If the kobject was not able to be created, NULL will be returned.
7213f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman */
7223f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartmanstruct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
7233f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman{
7243f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman	struct kobject *kobj;
7253f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman	int retval;
7263f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman
7273f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman	kobj = kobject_create();
7283f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman	if (!kobj)
7293f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman		return NULL;
7303f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman
731b2d6db5878a0832659ed58476357eea2db915550Greg Kroah-Hartman	retval = kobject_add(kobj, parent, "%s", name);
7323f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman	if (retval) {
7333f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman		printk(KERN_WARNING "%s: kobject_add error: %d\n",
734810304db75b0ca4e6ef071f86aa3e85fdaddee5eHarvey Harrison		       __func__, retval);
7353f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman		kobject_put(kobj);
7363f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman		kobj = NULL;
7373f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman	}
7383f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman	return kobj;
7393f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman}
7403f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-HartmanEXPORT_SYMBOL_GPL(kobject_create_and_add);
7413f9e3ee9dc3605e5c593b5d708494571fb0d3970Greg Kroah-Hartman
7427423172a50968de1905a61413c52bb070a62f5ceJun'ichi Nomura/**
743e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * kset_init - initialize a kset for use
744e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @k: kset
7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
746e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartmanvoid kset_init(struct kset *k)
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
748e1543ddf739b22a8c4218716ad50c26b3e147403Greg Kroah-Hartman	kobject_init_internal(&k->kobj);
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INIT_LIST_HEAD(&k->list);
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_init(&k->list_lock);
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
75323b5212cc7422f475b82124334b64277b5b43013Kay Sievers/* default kobject attribute operations */
75423b5212cc7422f475b82124334b64277b5b43013Kay Sieversstatic ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr,
75523b5212cc7422f475b82124334b64277b5b43013Kay Sievers			      char *buf)
75623b5212cc7422f475b82124334b64277b5b43013Kay Sievers{
75723b5212cc7422f475b82124334b64277b5b43013Kay Sievers	struct kobj_attribute *kattr;
75823b5212cc7422f475b82124334b64277b5b43013Kay Sievers	ssize_t ret = -EIO;
75923b5212cc7422f475b82124334b64277b5b43013Kay Sievers
76023b5212cc7422f475b82124334b64277b5b43013Kay Sievers	kattr = container_of(attr, struct kobj_attribute, attr);
76123b5212cc7422f475b82124334b64277b5b43013Kay Sievers	if (kattr->show)
76223b5212cc7422f475b82124334b64277b5b43013Kay Sievers		ret = kattr->show(kobj, kattr, buf);
76323b5212cc7422f475b82124334b64277b5b43013Kay Sievers	return ret;
76423b5212cc7422f475b82124334b64277b5b43013Kay Sievers}
76523b5212cc7422f475b82124334b64277b5b43013Kay Sievers
76623b5212cc7422f475b82124334b64277b5b43013Kay Sieversstatic ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr,
76723b5212cc7422f475b82124334b64277b5b43013Kay Sievers			       const char *buf, size_t count)
76823b5212cc7422f475b82124334b64277b5b43013Kay Sievers{
76923b5212cc7422f475b82124334b64277b5b43013Kay Sievers	struct kobj_attribute *kattr;
77023b5212cc7422f475b82124334b64277b5b43013Kay Sievers	ssize_t ret = -EIO;
77123b5212cc7422f475b82124334b64277b5b43013Kay Sievers
77223b5212cc7422f475b82124334b64277b5b43013Kay Sievers	kattr = container_of(attr, struct kobj_attribute, attr);
77323b5212cc7422f475b82124334b64277b5b43013Kay Sievers	if (kattr->store)
77423b5212cc7422f475b82124334b64277b5b43013Kay Sievers		ret = kattr->store(kobj, kattr, buf, count);
77523b5212cc7422f475b82124334b64277b5b43013Kay Sievers	return ret;
77623b5212cc7422f475b82124334b64277b5b43013Kay Sievers}
77723b5212cc7422f475b82124334b64277b5b43013Kay Sievers
77852cf25d0ab7f78eeecc59ac652ed5090f69b619eEmese Revfyconst struct sysfs_ops kobj_sysfs_ops = {
77923b5212cc7422f475b82124334b64277b5b43013Kay Sievers	.show	= kobj_attr_show,
78023b5212cc7422f475b82124334b64277b5b43013Kay Sievers	.store	= kobj_attr_store,
78123b5212cc7422f475b82124334b64277b5b43013Kay Sievers};
78229dfe2dc0e8f85c5656d13bb4c78a5ffca54c452Jeff MahoneyEXPORT_SYMBOL_GPL(kobj_sysfs_ops);
7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
785e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * kset_register - initialize and add a kset.
786e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @k: kset.
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
788e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartmanint kset_register(struct kset *k)
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
79080f03e349f06a261a8e980bf6005c61811a0d66aKay Sievers	int err;
79180f03e349f06a261a8e980bf6005c61811a0d66aKay Sievers
79231b9025aa0f89b392077db3f87458fd46bcc4f58Greg Kroah-Hartman	if (!k)
79331b9025aa0f89b392077db3f87458fd46bcc4f58Greg Kroah-Hartman		return -EINVAL;
79480f03e349f06a261a8e980bf6005c61811a0d66aKay Sievers
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kset_init(k);
79612e339ac6e31a34fe42396aec8fb1c0b43caf61eGreg Kroah-Hartman	err = kobject_add_internal(&k->kobj);
79780f03e349f06a261a8e980bf6005c61811a0d66aKay Sievers	if (err)
79880f03e349f06a261a8e980bf6005c61811a0d66aKay Sievers		return err;
79980f03e349f06a261a8e980bf6005c61811a0d66aKay Sievers	kobject_uevent(&k->kobj, KOBJ_ADD);
80080f03e349f06a261a8e980bf6005c61811a0d66aKay Sievers	return 0;
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
804e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * kset_unregister - remove a kset.
805e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @k: kset.
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
807e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartmanvoid kset_unregister(struct kset *k)
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
80931b9025aa0f89b392077db3f87458fd46bcc4f58Greg Kroah-Hartman	if (!k)
81031b9025aa0f89b392077db3f87458fd46bcc4f58Greg Kroah-Hartman		return;
81135a5fe695b07ae899510ad76fdf0aeaef85fe951Bjorn Helgaas	kobject_del(&k->kobj);
81278a2d906b40fe530ea800c1e873bfe8f02326f1eGreg Kroah-Hartman	kobject_put(&k->kobj);
8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
816e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * kset_find_obj - search for object in kset.
817e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @kset: kset we're looking in.
818e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * @name: object's name.
8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
820e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * Lock kset via @kset->subsys, and iterate over @kset->list,
821e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * looking for a matching kobject. If matching object is found
822e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman * take a reference and return the object.
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
824e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartmanstruct kobject *kset_find_obj(struct kset *kset, const char *name)
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
826c6a2a3dc26da72e431c293d02549593f9c041f63Robert P. J. Day	struct kobject *k;
827e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman	struct kobject *ret = NULL;
8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock(&kset->list_lock);
830c25d1dfbd403209025df41a737f82ce8f43d93f5Robin Holt
831c6a2a3dc26da72e431c293d02549593f9c041f63Robert P. J. Day	list_for_each_entry(k, &kset->list, entry) {
832e374a2bfebf359f846216336de91670be40499daGreg Kroah-Hartman		if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
833a49b7e82cab0f9b41f483359be83f44fbb6b4979Linus Torvalds			ret = kobject_get_unless_zero(k);
8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
837c25d1dfbd403209025df41a737f82ce8f43d93f5Robin Holt
8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock(&kset->list_lock);
8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
842b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartmanstatic void kset_release(struct kobject *kobj)
843b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman{
844b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	struct kset *kset = container_of(kobj, struct kset, kobj);
8459f66fa2a4690a16da0dbaae2f44ddfc313802504Greg Kroah-Hartman	pr_debug("kobject: '%s' (%p): %s\n",
846810304db75b0ca4e6ef071f86aa3e85fdaddee5eHarvey Harrison		 kobject_name(kobj), kobj, __func__);
847b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	kfree(kset);
848b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman}
849b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman
850386f275f5d097758f867bc99ddeaeb7a03b6b190Kay Sieversstatic struct kobj_type kset_ktype = {
851386f275f5d097758f867bc99ddeaeb7a03b6b190Kay Sievers	.sysfs_ops	= &kobj_sysfs_ops,
852b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	.release = kset_release,
853b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman};
854b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman
855b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman/**
856b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * kset_create - create a struct kset dynamically
857b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman *
858b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * @name: the name for the kset
859b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * @uevent_ops: a struct kset_uevent_ops for the kset
860b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * @parent_kobj: the parent kobject of this kset, if any.
861b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman *
862b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * This function creates a kset structure dynamically.  This structure can
863b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * then be registered with the system and show up in sysfs with a call to
864b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * kset_register().  When you are finished with this structure, if
865b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * kset_register() has been called, call kset_unregister() and the
866b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * structure will be dynamically freed when it is no longer being used.
867b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman *
868b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * If the kset was not able to be created, NULL will be returned.
869b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman */
870b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartmanstatic struct kset *kset_create(const char *name,
8719cd43611ccfb46632bfa7d19f688924ea93f1613Emese Revfy				const struct kset_uevent_ops *uevent_ops,
872b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman				struct kobject *parent_kobj)
873b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman{
874b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	struct kset *kset;
875d9cd8f37855b012757818f31390e8f84db251c89Dave Young	int retval;
876b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman
877b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	kset = kzalloc(sizeof(*kset), GFP_KERNEL);
878b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	if (!kset)
879b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman		return NULL;
880b7165ebbf0898bad9aaeddfa22b918e94ed90e07Kees Cook	retval = kobject_set_name(&kset->kobj, "%s", name);
881d9cd8f37855b012757818f31390e8f84db251c89Dave Young	if (retval) {
882d9cd8f37855b012757818f31390e8f84db251c89Dave Young		kfree(kset);
883d9cd8f37855b012757818f31390e8f84db251c89Dave Young		return NULL;
884d9cd8f37855b012757818f31390e8f84db251c89Dave Young	}
885b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	kset->uevent_ops = uevent_ops;
886b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	kset->kobj.parent = parent_kobj;
887b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman
888b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	/*
889386f275f5d097758f867bc99ddeaeb7a03b6b190Kay Sievers	 * The kobject of this kset will have a type of kset_ktype and belong to
890b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	 * no kset itself.  That way we can properly free it when it is
891b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	 * finished being used.
892b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	 */
893386f275f5d097758f867bc99ddeaeb7a03b6b190Kay Sievers	kset->kobj.ktype = &kset_ktype;
894b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	kset->kobj.kset = NULL;
895b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman
896b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	return kset;
897b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman}
898b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman
899b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman/**
900b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * kset_create_and_add - create a struct kset dynamically and add it to sysfs
901b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman *
902b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * @name: the name for the kset
903b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * @uevent_ops: a struct kset_uevent_ops for the kset
904b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * @parent_kobj: the parent kobject of this kset, if any.
905b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman *
906b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * This function creates a kset structure dynamically and registers it
907b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * with sysfs.  When you are finished with this structure, call
908b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * kset_unregister() and the structure will be dynamically freed when it
909b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * is no longer being used.
910b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman *
911b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman * If the kset was not able to be created, NULL will be returned.
912b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman */
913b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartmanstruct kset *kset_create_and_add(const char *name,
9149cd43611ccfb46632bfa7d19f688924ea93f1613Emese Revfy				 const struct kset_uevent_ops *uevent_ops,
915b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman				 struct kobject *parent_kobj)
916b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman{
917b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	struct kset *kset;
918b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	int error;
919b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman
920b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	kset = kset_create(name, uevent_ops, parent_kobj);
921b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	if (!kset)
922b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman		return NULL;
923b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	error = kset_register(kset);
924b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	if (error) {
925b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman		kfree(kset);
926b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman		return NULL;
927b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	}
928b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman	return kset;
929b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman}
930b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-HartmanEXPORT_SYMBOL_GPL(kset_create_and_add);
931b727c702896f88d2ff6c3e03bd011d7c3dffe3e1Greg Kroah-Hartman
932bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
933bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biedermanstatic DEFINE_SPINLOCK(kobj_ns_type_lock);
934bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biedermanstatic const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES];
935bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
936bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biedermanint kobj_ns_type_register(const struct kobj_ns_type_operations *ops)
937bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman{
938bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	enum kobj_ns_type type = ops->type;
939bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	int error;
940bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
941bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	spin_lock(&kobj_ns_type_lock);
942bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
943bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	error = -EINVAL;
944bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	if (type >= KOBJ_NS_TYPES)
945bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman		goto out;
946bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
947bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	error = -EINVAL;
948bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	if (type <= KOBJ_NS_TYPE_NONE)
949bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman		goto out;
950bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
951bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	error = -EBUSY;
952bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	if (kobj_ns_ops_tbl[type])
953bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman		goto out;
954bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
955bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	error = 0;
956bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	kobj_ns_ops_tbl[type] = ops;
957bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
958bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biedermanout:
959bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	spin_unlock(&kobj_ns_type_lock);
960bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	return error;
961bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman}
962bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
963bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biedermanint kobj_ns_type_registered(enum kobj_ns_type type)
964bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman{
965bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	int registered = 0;
966bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
967bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	spin_lock(&kobj_ns_type_lock);
968bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES))
969bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman		registered = kobj_ns_ops_tbl[type] != NULL;
970bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	spin_unlock(&kobj_ns_type_lock);
971bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
972bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	return registered;
973bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman}
974bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
975bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biedermanconst struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent)
976bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman{
977bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	const struct kobj_ns_type_operations *ops = NULL;
978bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
979bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	if (parent && parent->ktype->child_ns_type)
980bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman		ops = parent->ktype->child_ns_type(parent);
981bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
982bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	return ops;
983bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman}
984bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
985bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biedermanconst struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj)
986bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman{
987bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	return kobj_child_ns_ops(kobj->parent);
988bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman}
989bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
9907dc5dbc879bd0779924b5132a48b731a0bc04a1eEric W. Biedermanbool kobj_ns_current_may_mount(enum kobj_ns_type type)
9917dc5dbc879bd0779924b5132a48b731a0bc04a1eEric W. Biederman{
992730d7d339884f20da28b59bf6f0a16af6400a113Eric W. Biederman	bool may_mount = true;
9937dc5dbc879bd0779924b5132a48b731a0bc04a1eEric W. Biederman
9947dc5dbc879bd0779924b5132a48b731a0bc04a1eEric W. Biederman	spin_lock(&kobj_ns_type_lock);
9957dc5dbc879bd0779924b5132a48b731a0bc04a1eEric W. Biederman	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
9967dc5dbc879bd0779924b5132a48b731a0bc04a1eEric W. Biederman	    kobj_ns_ops_tbl[type])
9977dc5dbc879bd0779924b5132a48b731a0bc04a1eEric W. Biederman		may_mount = kobj_ns_ops_tbl[type]->current_may_mount();
9987dc5dbc879bd0779924b5132a48b731a0bc04a1eEric W. Biederman	spin_unlock(&kobj_ns_type_lock);
9997dc5dbc879bd0779924b5132a48b731a0bc04a1eEric W. Biederman
10007dc5dbc879bd0779924b5132a48b731a0bc04a1eEric W. Biederman	return may_mount;
10017dc5dbc879bd0779924b5132a48b731a0bc04a1eEric W. Biederman}
1002bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
1003a685e08987d1edf1995b76511d4c98ea0e905377Al Virovoid *kobj_ns_grab_current(enum kobj_ns_type type)
1004bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman{
1005a685e08987d1edf1995b76511d4c98ea0e905377Al Viro	void *ns = NULL;
1006bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
1007bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	spin_lock(&kobj_ns_type_lock);
1008bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1009bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	    kobj_ns_ops_tbl[type])
1010a685e08987d1edf1995b76511d4c98ea0e905377Al Viro		ns = kobj_ns_ops_tbl[type]->grab_current_ns();
1011bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	spin_unlock(&kobj_ns_type_lock);
1012bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
1013bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	return ns;
1014bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman}
1015bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
1016bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biedermanconst void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk)
1017bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman{
1018bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	const void *ns = NULL;
1019bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
1020bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	spin_lock(&kobj_ns_type_lock);
1021bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1022bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	    kobj_ns_ops_tbl[type])
1023bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman		ns = kobj_ns_ops_tbl[type]->netlink_ns(sk);
1024bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	spin_unlock(&kobj_ns_type_lock);
1025bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
1026bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	return ns;
1027bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman}
1028bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
1029bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biedermanconst void *kobj_ns_initial(enum kobj_ns_type type)
1030bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman{
1031bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	const void *ns = NULL;
1032bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
1033bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	spin_lock(&kobj_ns_type_lock);
1034bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1035bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	    kobj_ns_ops_tbl[type])
1036bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman		ns = kobj_ns_ops_tbl[type]->initial_ns();
1037bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	spin_unlock(&kobj_ns_type_lock);
1038bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
1039bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman	return ns;
1040bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman}
1041bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
1042a685e08987d1edf1995b76511d4c98ea0e905377Al Virovoid kobj_ns_drop(enum kobj_ns_type type, void *ns)
1043bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman{
1044a685e08987d1edf1995b76511d4c98ea0e905377Al Viro	spin_lock(&kobj_ns_type_lock);
1045a685e08987d1edf1995b76511d4c98ea0e905377Al Viro	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1046a685e08987d1edf1995b76511d4c98ea0e905377Al Viro	    kobj_ns_ops_tbl[type] && kobj_ns_ops_tbl[type]->drop_ns)
1047a685e08987d1edf1995b76511d4c98ea0e905377Al Viro		kobj_ns_ops_tbl[type]->drop_ns(ns);
1048a685e08987d1edf1995b76511d4c98ea0e905377Al Viro	spin_unlock(&kobj_ns_type_lock);
1049bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman}
1050bc451f2058238013e1cdf4acd443c01734d332f0Eric W. Biederman
10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(kobject_get);
10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(kobject_put);
10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(kobject_del);
10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(kset_register);
10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(kset_unregister);
1057