⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kobject.c

📁 Lib files of linux kernel
💻 C
📖 第 1 页 / 共 2 页
字号:
		error = -ENOMEM;		goto out;	}	sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);	envp[0] = devpath_string;	envp[1] = NULL;	error = sysfs_rename_dir(kobj, new_name);	/* This function is mostly/only used for network interface.	 * Some hotplug package track interfaces by their name and	 * therefore want to know when the name is changed by the user. */	if (!error)		kobject_uevent_env(kobj, KOBJ_MOVE, envp);out:	kfree(devpath_string);	kfree(devpath);	kobject_put(kobj);	return error;}EXPORT_SYMBOL_GPL(kobject_rename);/** * kobject_move - move object to another parent * @kobj: object in question. * @new_parent: object's new parent (can be NULL) */int kobject_move(struct kobject *kobj, struct kobject *new_parent){	int error;	struct kobject *old_parent;	const char *devpath = NULL;	char *devpath_string = NULL;	char *envp[2];	kobj = kobject_get(kobj);	if (!kobj)		return -EINVAL;	new_parent = kobject_get(new_parent);	if (!new_parent) {		if (kobj->kset)			new_parent = kobject_get(&kobj->kset->kobj);	}	/* old object path */	devpath = kobject_get_path(kobj, GFP_KERNEL);	if (!devpath) {		error = -ENOMEM;		goto out;	}	devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);	if (!devpath_string) {		error = -ENOMEM;		goto out;	}	sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);	envp[0] = devpath_string;	envp[1] = NULL;	error = sysfs_move_dir(kobj, new_parent);	if (error)		goto out;	old_parent = kobj->parent;	kobj->parent = new_parent;	new_parent = NULL;	kobject_put(old_parent);	kobject_uevent_env(kobj, KOBJ_MOVE, envp);out:	kobject_put(new_parent);	kobject_put(kobj);	kfree(devpath_string);	kfree(devpath);	return error;}/** * kobject_del - unlink kobject from hierarchy. * @kobj: object. */void kobject_del(struct kobject *kobj){	if (!kobj)		return;	sysfs_remove_dir(kobj);	kobj->state_in_sysfs = 0;	kobj_kset_leave(kobj);	kobject_put(kobj->parent);	kobj->parent = NULL;}/** * kobject_get - increment refcount for object. * @kobj: object. */struct kobject *kobject_get(struct kobject *kobj){	if (kobj)		kref_get(&kobj->kref);	return kobj;}/* * kobject_cleanup - free kobject resources. * @kobj: object to cleanup */static void kobject_cleanup(struct kobject *kobj){	struct kobj_type *t = get_ktype(kobj);	const char *name = kobj->name;	pr_debug("kobject: '%s' (%p): %s\n",		 kobject_name(kobj), kobj, __func__);	if (t && !t->release)		pr_debug("kobject: '%s' (%p): does not have a release() "			 "function, it is broken and must be fixed.\n",			 kobject_name(kobj), kobj);	/* send "remove" if the caller did not do it but sent "add" */	if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) {		pr_debug("kobject: '%s' (%p): auto cleanup 'remove' event\n",			 kobject_name(kobj), kobj);		kobject_uevent(kobj, KOBJ_REMOVE);	}	/* remove from sysfs if the caller did not do it */	if (kobj->state_in_sysfs) {		pr_debug("kobject: '%s' (%p): auto cleanup kobject_del\n",			 kobject_name(kobj), kobj);		kobject_del(kobj);	}	if (t && t->release) {		pr_debug("kobject: '%s' (%p): calling ktype release\n",			 kobject_name(kobj), kobj);		t->release(kobj);	}	/* free name if we allocated it */	if (name) {		pr_debug("kobject: '%s': free name\n", name);		kfree(name);	}}static void kobject_release(struct kref *kref){	kobject_cleanup(container_of(kref, struct kobject, kref));}/** * kobject_put - decrement refcount for object. * @kobj: object. * * Decrement the refcount, and if 0, call kobject_cleanup(). */void kobject_put(struct kobject *kobj){	if (kobj) {		if (!kobj->state_initialized)			WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "			       "initialized, yet kobject_put() is being "			       "called.\n", kobject_name(kobj), kobj);		kref_put(&kobj->kref, kobject_release);	}}static void dynamic_kobj_release(struct kobject *kobj){	pr_debug("kobject: (%p): %s\n", kobj, __func__);	kfree(kobj);}static struct kobj_type dynamic_kobj_ktype = {	.release	= dynamic_kobj_release,	.sysfs_ops	= &kobj_sysfs_ops,};/** * kobject_create - create a struct kobject dynamically * * This function creates a kobject structure dynamically and sets it up * to be a "dynamic" kobject with a default release function set up. * * If the kobject was not able to be created, NULL will be returned. * The kobject structure returned from here must be cleaned up with a * call to kobject_put() and not kfree(), as kobject_init() has * already been called on this structure. */struct kobject *kobject_create(void){	struct kobject *kobj;	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);	if (!kobj)		return NULL;	kobject_init(kobj, &dynamic_kobj_ktype);	return kobj;}/** * kobject_create_and_add - create a struct kobject dynamically and register it with sysfs * * @name: the name for the kset * @parent: the parent kobject of this kobject, if any. * * This function creates a kobject structure dynamically and registers it * with sysfs.  When you are finished with this structure, call * kobject_put() and the structure will be dynamically freed when * it is no longer being used. * * If the kobject was not able to be created, NULL will be returned. */struct kobject *kobject_create_and_add(const char *name, struct kobject *parent){	struct kobject *kobj;	int retval;	kobj = kobject_create();	if (!kobj)		return NULL;	retval = kobject_add(kobj, parent, "%s", name);	if (retval) {		printk(KERN_WARNING "%s: kobject_add error: %d\n",		       __func__, retval);		kobject_put(kobj);		kobj = NULL;	}	return kobj;}EXPORT_SYMBOL_GPL(kobject_create_and_add);/** * kset_init - initialize a kset for use * @k: kset */void kset_init(struct kset *k){	kobject_init_internal(&k->kobj);	INIT_LIST_HEAD(&k->list);	spin_lock_init(&k->list_lock);}/* default kobject attribute operations */static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr,			      char *buf){	struct kobj_attribute *kattr;	ssize_t ret = -EIO;	kattr = container_of(attr, struct kobj_attribute, attr);	if (kattr->show)		ret = kattr->show(kobj, kattr, buf);	return ret;}static ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr,			       const char *buf, size_t count){	struct kobj_attribute *kattr;	ssize_t ret = -EIO;	kattr = container_of(attr, struct kobj_attribute, attr);	if (kattr->store)		ret = kattr->store(kobj, kattr, buf, count);	return ret;}struct sysfs_ops kobj_sysfs_ops = {	.show	= kobj_attr_show,	.store	= kobj_attr_store,};/** * kset_register - initialize and add a kset. * @k: kset. */int kset_register(struct kset *k){	int err;	if (!k)		return -EINVAL;	kset_init(k);	err = kobject_add_internal(&k->kobj);	if (err)		return err;	kobject_uevent(&k->kobj, KOBJ_ADD);	return 0;}/** * kset_unregister - remove a kset. * @k: kset. */void kset_unregister(struct kset *k){	if (!k)		return;	kobject_put(&k->kobj);}/** * kset_find_obj - search for object in kset. * @kset: kset we're looking in. * @name: object's name. * * Lock kset via @kset->subsys, and iterate over @kset->list, * looking for a matching kobject. If matching object is found * take a reference and return the object. */struct kobject *kset_find_obj(struct kset *kset, const char *name){	struct kobject *k;	struct kobject *ret = NULL;	spin_lock(&kset->list_lock);	list_for_each_entry(k, &kset->list, entry) {		if (kobject_name(k) && !strcmp(kobject_name(k), name)) {			ret = kobject_get(k);			break;		}	}	spin_unlock(&kset->list_lock);	return ret;}static void kset_release(struct kobject *kobj){	struct kset *kset = container_of(kobj, struct kset, kobj);	pr_debug("kobject: '%s' (%p): %s\n",		 kobject_name(kobj), kobj, __func__);	kfree(kset);}static struct kobj_type kset_ktype = {	.sysfs_ops	= &kobj_sysfs_ops,	.release = kset_release,};/** * kset_create - create a struct kset dynamically * * @name: the name for the kset * @uevent_ops: a struct kset_uevent_ops for the kset * @parent_kobj: the parent kobject of this kset, if any. * * This function creates a kset structure dynamically.  This structure can * then be registered with the system and show up in sysfs with a call to * kset_register().  When you are finished with this structure, if * kset_register() has been called, call kset_unregister() and the * structure will be dynamically freed when it is no longer being used. * * If the kset was not able to be created, NULL will be returned. */static struct kset *kset_create(const char *name,				struct kset_uevent_ops *uevent_ops,				struct kobject *parent_kobj){	struct kset *kset;	kset = kzalloc(sizeof(*kset), GFP_KERNEL);	if (!kset)		return NULL;	kobject_set_name(&kset->kobj, name);	kset->uevent_ops = uevent_ops;	kset->kobj.parent = parent_kobj;	/*	 * The kobject of this kset will have a type of kset_ktype and belong to	 * no kset itself.  That way we can properly free it when it is	 * finished being used.	 */	kset->kobj.ktype = &kset_ktype;	kset->kobj.kset = NULL;	return kset;}/** * kset_create_and_add - create a struct kset dynamically and add it to sysfs * * @name: the name for the kset * @uevent_ops: a struct kset_uevent_ops for the kset * @parent_kobj: the parent kobject of this kset, if any. * * This function creates a kset structure dynamically and registers it * with sysfs.  When you are finished with this structure, call * kset_unregister() and the structure will be dynamically freed when it * is no longer being used. * * If the kset was not able to be created, NULL will be returned. */struct kset *kset_create_and_add(const char *name,				 struct kset_uevent_ops *uevent_ops,				 struct kobject *parent_kobj){	struct kset *kset;	int error;	kset = kset_create(name, uevent_ops, parent_kobj);	if (!kset)		return NULL;	error = kset_register(kset);	if (error) {		kfree(kset);		return NULL;	}	return kset;}EXPORT_SYMBOL_GPL(kset_create_and_add);EXPORT_SYMBOL(kobject_get);EXPORT_SYMBOL(kobject_put);EXPORT_SYMBOL(kobject_del);EXPORT_SYMBOL(kset_register);EXPORT_SYMBOL(kset_unregister);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -