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