kobject.c 20.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
/*
 * kobject.c - library routines for handling generic kernel objects
 *
 * Copyright (c) 2002-2003 Patrick Mochel <mochel@osdl.org>
5 6
 * Copyright (c) 2006-2007 Greg Kroah-Hartman <greg@kroah.com>
 * Copyright (c) 2006-2007 Novell Inc.
L
Linus Torvalds 已提交
7 8 9 10 11 12 13 14 15 16 17 18
 *
 * This file is released under the GPLv2.
 *
 *
 * Please see the file Documentation/kobject.txt for critical information
 * about using the kobject interface.
 */

#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/module.h>
#include <linux/stat.h>
T
Tim Schmielau 已提交
19
#include <linux/slab.h>
L
Linus Torvalds 已提交
20

21 22 23
/*
 * populate_dir - populate directory with attributes.
 * @kobj: object we're working on.
L
Linus Torvalds 已提交
24
 *
25 26 27 28
 * Most subsystems have a set of default attributes that are associated
 * with an object that registers with them.  This is a helper called during
 * object registration that loops through the default attributes of the
 * subsystem and creates attributes files for them in sysfs.
L
Linus Torvalds 已提交
29
 */
30
static int populate_dir(struct kobject *kobj)
L
Linus Torvalds 已提交
31
{
32 33
	struct kobj_type *t = get_ktype(kobj);
	struct attribute *attr;
L
Linus Torvalds 已提交
34 35
	int error = 0;
	int i;
36

L
Linus Torvalds 已提交
37 38
	if (t && t->default_attrs) {
		for (i = 0; (attr = t->default_attrs[i]) != NULL; i++) {
39 40
			error = sysfs_create_file(kobj, attr);
			if (error)
L
Linus Torvalds 已提交
41 42 43 44 45 46
				break;
		}
	}
	return error;
}

47
static int create_dir(struct kobject *kobj)
L
Linus Torvalds 已提交
48 49 50
{
	int error = 0;
	if (kobject_name(kobj)) {
51
		error = sysfs_create_dir(kobj);
L
Linus Torvalds 已提交
52
		if (!error) {
53 54
			error = populate_dir(kobj);
			if (error)
L
Linus Torvalds 已提交
55 56 57 58 59 60 61 62 63
				sysfs_remove_dir(kobj);
		}
	}
	return error;
}

static int get_kobj_path_length(struct kobject *kobj)
{
	int length = 1;
64
	struct kobject *parent = kobj;
L
Linus Torvalds 已提交
65

66
	/* walk up the ancestors until we hit the one pointing to the
L
Linus Torvalds 已提交
67 68 69 70
	 * root.
	 * Add 1 to strlen for leading '/' of each level.
	 */
	do {
71 72
		if (kobject_name(parent) == NULL)
			return 0;
L
Linus Torvalds 已提交
73 74 75 76 77 78 79 80
		length += strlen(kobject_name(parent)) + 1;
		parent = parent->parent;
	} while (parent);
	return length;
}

static void fill_kobj_path(struct kobject *kobj, char *path, int length)
{
81
	struct kobject *parent;
L
Linus Torvalds 已提交
82 83 84 85 86 87

	--length;
	for (parent = kobj; parent; parent = parent->parent) {
		int cur = strlen(kobject_name(parent));
		/* back up enough to print this name with '/' */
		length -= cur;
88
		strncpy(path + length, kobject_name(parent), cur);
L
Linus Torvalds 已提交
89 90 91
		*(path + --length) = '/';
	}

92
	pr_debug("kobject: '%s' (%p): %s: path = '%s'\n", kobject_name(kobj),
93
		 kobj, __func__, path);
L
Linus Torvalds 已提交
94 95 96
}

/**
97
 * kobject_get_path - generate and return the path associated with a given kobj and kset pair.
L
Linus Torvalds 已提交
98 99 100
 *
 * @kobj:	kobject in question, with which to build the path
 * @gfp_mask:	the allocation type used to allocate the path
101 102
 *
 * The result must be freed by the caller with kfree().
L
Linus Torvalds 已提交
103
 */
A
Al Viro 已提交
104
char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
L
Linus Torvalds 已提交
105 106 107 108 109
{
	char *path;
	int len;

	len = get_kobj_path_length(kobj);
110 111
	if (len == 0)
		return NULL;
112
	path = kzalloc(len, gfp_mask);
L
Linus Torvalds 已提交
113 114 115 116 117 118
	if (!path)
		return NULL;
	fill_kobj_path(kobj, path, len);

	return path;
}
119
EXPORT_SYMBOL_GPL(kobject_get_path);
L
Linus Torvalds 已提交
120

121 122
/* add the kobject to its kset's list */
static void kobj_kset_join(struct kobject *kobj)
L
Linus Torvalds 已提交
123
{
124
	if (!kobj->kset)
125
		return;
126 127 128 129 130

	kset_get(kobj->kset);
	spin_lock(&kobj->kset->list_lock);
	list_add_tail(&kobj->entry, &kobj->kset->list);
	spin_unlock(&kobj->kset->list_lock);
L
Linus Torvalds 已提交
131 132
}

133 134 135 136 137
/* remove the kobject from its kset's list */
static void kobj_kset_leave(struct kobject *kobj)
{
	if (!kobj->kset)
		return;
L
Linus Torvalds 已提交
138

139 140 141 142 143
	spin_lock(&kobj->kset->list_lock);
	list_del_init(&kobj->entry);
	spin_unlock(&kobj->kset->list_lock);
	kset_put(kobj->kset);
}
L
Linus Torvalds 已提交
144

145
static void kobject_init_internal(struct kobject *kobj)
L
Linus Torvalds 已提交
146
{
147 148 149 150
	if (!kobj)
		return;
	kref_init(&kobj->kref);
	INIT_LIST_HEAD(&kobj->entry);
151 152 153 154
	kobj->state_in_sysfs = 0;
	kobj->state_add_uevent_sent = 0;
	kobj->state_remove_uevent_sent = 0;
	kobj->state_initialized = 1;
L
Linus Torvalds 已提交
155 156
}

157

158
static int kobject_add_internal(struct kobject *kobj)
L
Linus Torvalds 已提交
159 160
{
	int error = 0;
161
	struct kobject *parent;
L
Linus Torvalds 已提交
162

163
	if (!kobj)
L
Linus Torvalds 已提交
164
		return -ENOENT;
165

166
	if (!kobj->name || !kobj->name[0]) {
A
Arjan van de Ven 已提交
167
		WARN(1, "kobject: (%p): attempted to be registered with empty "
168
			 "name!\n", kobj);
169 170
		return -EINVAL;
	}
L
Linus Torvalds 已提交
171

172
	parent = kobject_get(kobj->parent);
L
Linus Torvalds 已提交
173

174
	/* join kset if set, use it as parent if we do not already have one */
L
Linus Torvalds 已提交
175
	if (kobj->kset) {
176
		if (!parent)
L
Linus Torvalds 已提交
177
			parent = kobject_get(&kobj->kset->kobj);
178
		kobj_kset_join(kobj);
179
		kobj->parent = parent;
L
Linus Torvalds 已提交
180 181
	}

182
	pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n",
183
		 kobject_name(kobj), kobj, __func__,
184
		 parent ? kobject_name(parent) : "<NULL>",
185
		 kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>");
186

187
	error = create_dir(kobj);
L
Linus Torvalds 已提交
188
	if (error) {
189 190 191
		kobj_kset_leave(kobj);
		kobject_put(parent);
		kobj->parent = NULL;
192 193 194

		/* be noisy on error issues */
		if (error == -EEXIST)
195
			printk(KERN_ERR "%s failed for %s with "
196 197
			       "-EEXIST, don't try to register things with "
			       "the same name in the same directory.\n",
198
			       __func__, kobject_name(kobj));
199
		else
200
			printk(KERN_ERR "%s failed for %s (%d)\n",
201
			       __func__, kobject_name(kobj), error);
202
		dump_stack();
203 204
	} else
		kobj->state_in_sysfs = 1;
L
Linus Torvalds 已提交
205 206 207 208

	return error;
}

209 210 211 212 213 214
/**
 * kobject_set_name_vargs - Set the name of an kobject
 * @kobj: struct kobject to set the name of
 * @fmt: format string used to build the name
 * @vargs: vargs to format the string.
 */
215
int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
216 217
				  va_list vargs)
{
218 219
	const char *old_name = kobj->name;
	char *s;
220

221 222 223
	if (kobj->name && !fmt)
		return 0;

224 225 226
	kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs);
	if (!kobj->name)
		return -ENOMEM;
227

228
	/* ewww... some of these buggers have '/' in the name ... */
229
	while ((s = strchr(kobj->name, '/')))
230 231 232
		s[0] = '!';

	kfree(old_name);
233 234
	return 0;
}
L
Linus Torvalds 已提交
235 236

/**
237
 * kobject_set_name - Set the name of a kobject
238
 * @kobj: struct kobject to set the name of
239
 * @fmt: format string used to build the name
L
Linus Torvalds 已提交
240
 *
241 242 243
 * This sets the name of the kobject.  If you have already added the
 * kobject to the system, you must call kobject_rename() in order to
 * change the name of the kobject.
L
Linus Torvalds 已提交
244
 */
245
int kobject_set_name(struct kobject *kobj, const char *fmt, ...)
L
Linus Torvalds 已提交
246
{
247
	va_list vargs;
248
	int retval;
L
Linus Torvalds 已提交
249

250 251 252
	va_start(vargs, fmt);
	retval = kobject_set_name_vargs(kobj, fmt, vargs);
	va_end(vargs);
L
Linus Torvalds 已提交
253

254
	return retval;
L
Linus Torvalds 已提交
255 256 257
}
EXPORT_SYMBOL(kobject_set_name);

258
/**
259
 * kobject_init - initialize a kobject structure
260 261 262 263 264 265 266 267 268 269
 * @kobj: pointer to the kobject to initialize
 * @ktype: pointer to the ktype for this kobject.
 *
 * This function will properly initialize a kobject such that it can then
 * be passed to the kobject_add() call.
 *
 * After this function is called, the kobject MUST be cleaned up by a call
 * to kobject_put(), not by a call to kfree directly to ensure that all of
 * the memory is cleaned up properly.
 */
270
void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
271 272 273 274 275 276 277 278 279 280 281
{
	char *err_str;

	if (!kobj) {
		err_str = "invalid kobject pointer!";
		goto error;
	}
	if (!ktype) {
		err_str = "must have a ktype to be initialized properly!\n";
		goto error;
	}
282
	if (kobj->state_initialized) {
283
		/* do not error out as sometimes we can recover */
284 285
		printk(KERN_ERR "kobject (%p): tried to init an initialized "
		       "object, something is seriously wrong.\n", kobj);
286 287 288
		dump_stack();
	}

289
	kobject_init_internal(kobj);
290 291 292 293
	kobj->ktype = ktype;
	return;

error:
294
	printk(KERN_ERR "kobject (%p): %s\n", kobj, err_str);
295 296
	dump_stack();
}
297
EXPORT_SYMBOL(kobject_init);
298

299 300 301 302 303
static int kobject_add_varg(struct kobject *kobj, struct kobject *parent,
			    const char *fmt, va_list vargs)
{
	int retval;

304
	retval = kobject_set_name_vargs(kobj, fmt, vargs);
305 306 307 308 309
	if (retval) {
		printk(KERN_ERR "kobject: can not set name properly!\n");
		return retval;
	}
	kobj->parent = parent;
310
	return kobject_add_internal(kobj);
311 312 313
}

/**
314
 * kobject_add - the main kobject add function
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
 * @kobj: the kobject to add
 * @parent: pointer to the parent of the kobject.
 * @fmt: format to name the kobject with.
 *
 * The kobject name is set and added to the kobject hierarchy in this
 * function.
 *
 * If @parent is set, then the parent of the @kobj will be set to it.
 * If @parent is NULL, then the parent of the @kobj will be set to the
 * kobject associted with the kset assigned to this kobject.  If no kset
 * is assigned to the kobject, then the kobject will be located in the
 * root of the sysfs tree.
 *
 * If this function returns an error, kobject_put() must be called to
 * properly clean up the memory associated with the object.
 * Under no instance should the kobject that is passed to this function
 * be directly freed with a call to kfree(), that can leak memory.
 *
333
 * Note, no "add" uevent will be created with this call, the caller should set
334 335 336 337
 * up all of the necessary sysfs files for the object and then call
 * kobject_uevent() with the UEVENT_ADD parameter to ensure that
 * userspace is properly notified of this kobject's creation.
 */
338 339
int kobject_add(struct kobject *kobj, struct kobject *parent,
		const char *fmt, ...)
340 341 342 343 344 345 346
{
	va_list args;
	int retval;

	if (!kobj)
		return -EINVAL;

347 348 349 350 351 352 353
	if (!kobj->state_initialized) {
		printk(KERN_ERR "kobject '%s' (%p): tried to add an "
		       "uninitialized object, something is seriously wrong.\n",
		       kobject_name(kobj), kobj);
		dump_stack();
		return -EINVAL;
	}
354 355 356 357 358 359
	va_start(args, fmt);
	retval = kobject_add_varg(kobj, parent, fmt, args);
	va_end(args);

	return retval;
}
360
EXPORT_SYMBOL(kobject_add);
361

362 363 364 365 366 367 368
/**
 * kobject_init_and_add - initialize a kobject structure and add it to the kobject hierarchy
 * @kobj: pointer to the kobject to initialize
 * @ktype: pointer to the ktype for this kobject.
 * @parent: pointer to the parent of this kobject.
 * @fmt: the name of the kobject.
 *
369
 * This function combines the call to kobject_init() and
370 371
 * kobject_add().  The same type of error handling after a call to
 * kobject_add() and kobject lifetime rules are the same here.
372 373 374 375 376 377 378
 */
int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
			 struct kobject *parent, const char *fmt, ...)
{
	va_list args;
	int retval;

379
	kobject_init(kobj, ktype);
380 381 382 383 384 385 386 387 388

	va_start(args, fmt);
	retval = kobject_add_varg(kobj, parent, fmt, args);
	va_end(args);

	return retval;
}
EXPORT_SYMBOL_GPL(kobject_init_and_add);

L
Linus Torvalds 已提交
389
/**
390 391 392
 * kobject_rename - change the name of an object
 * @kobj: object in question.
 * @new_name: object's new name
393 394 395 396 397
 *
 * It is the responsibility of the caller to provide mutual
 * exclusion between two different calls of kobject_rename
 * on the same kobject and to ensure that new_name is valid and
 * won't conflict with other kobjects.
L
Linus Torvalds 已提交
398
 */
399
int kobject_rename(struct kobject *kobj, const char *new_name)
L
Linus Torvalds 已提交
400 401
{
	int error = 0;
402
	const char *devpath = NULL;
403
	const char *dup_name = NULL, *name;
404 405
	char *devpath_string = NULL;
	char *envp[2];
L
Linus Torvalds 已提交
406 407 408 409

	kobj = kobject_get(kobj);
	if (!kobj)
		return -EINVAL;
410 411
	if (!kobj->parent)
		return -EINVAL;
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426

	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;

427 428 429 430 431 432
	name = dup_name = kstrdup(new_name, GFP_KERNEL);
	if (!name) {
		error = -ENOMEM;
		goto out;
	}

433
	error = sysfs_rename_dir(kobj, new_name);
434 435 436 437 438 439
	if (error)
		goto out;

	/* Install the new kobject name */
	dup_name = kobj->name;
	kobj->name = name;
440 441 442 443

	/* 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. */
444
	kobject_uevent_env(kobj, KOBJ_MOVE, envp);
445 446

out:
447
	kfree(dup_name);
448 449
	kfree(devpath_string);
	kfree(devpath);
450 451 452 453
	kobject_put(kobj);

	return error;
}
454
EXPORT_SYMBOL_GPL(kobject_rename);
455

456
/**
457 458 459
 * kobject_move - move object to another parent
 * @kobj: object in question.
 * @new_parent: object's new parent (can be NULL)
460 461 462 463 464 465 466 467 468 469 470 471 472 473
 */
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) {
474 475
		if (kobj->kset)
			new_parent = kobject_get(&kobj->kset->kobj);
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
	}
	/* 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;
496
	new_parent = NULL;
497 498 499
	kobject_put(old_parent);
	kobject_uevent_env(kobj, KOBJ_MOVE, envp);
out:
500
	kobject_put(new_parent);
501 502 503 504 505 506
	kobject_put(kobj);
	kfree(devpath_string);
	kfree(devpath);
	return error;
}

L
Linus Torvalds 已提交
507
/**
508 509
 * kobject_del - unlink kobject from hierarchy.
 * @kobj: object.
L
Linus Torvalds 已提交
510
 */
511
void kobject_del(struct kobject *kobj)
L
Linus Torvalds 已提交
512
{
513 514
	if (!kobj)
		return;
515

L
Linus Torvalds 已提交
516
	sysfs_remove_dir(kobj);
517 518 519 520
	kobj->state_in_sysfs = 0;
	kobj_kset_leave(kobj);
	kobject_put(kobj->parent);
	kobj->parent = NULL;
L
Linus Torvalds 已提交
521 522 523
}

/**
524 525
 * kobject_get - increment refcount for object.
 * @kobj: object.
L
Linus Torvalds 已提交
526
 */
527
struct kobject *kobject_get(struct kobject *kobj)
L
Linus Torvalds 已提交
528 529 530 531 532 533
{
	if (kobj)
		kref_get(&kobj->kref);
	return kobj;
}

534 535 536
/*
 * kobject_cleanup - free kobject resources.
 * @kobj: object to cleanup
L
Linus Torvalds 已提交
537
 */
538
static void kobject_cleanup(struct kobject *kobj)
L
Linus Torvalds 已提交
539
{
540
	struct kobj_type *t = get_ktype(kobj);
541
	const char *name = kobj->name;
L
Linus Torvalds 已提交
542

543
	pr_debug("kobject: '%s' (%p): %s\n",
544
		 kobject_name(kobj), kobj, __func__);
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564

	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);
	}

565
	if (t && t->release) {
566 567
		pr_debug("kobject: '%s' (%p): calling ktype release\n",
			 kobject_name(kobj), kobj);
L
Linus Torvalds 已提交
568
		t->release(kobj);
569 570 571
	}

	/* free name if we allocated it */
572
	if (name) {
573
		pr_debug("kobject: '%s': free name\n", name);
574 575
		kfree(name);
	}
L
Linus Torvalds 已提交
576 577 578 579 580 581 582 583
}

static void kobject_release(struct kref *kref)
{
	kobject_cleanup(container_of(kref, struct kobject, kref));
}

/**
584 585
 * kobject_put - decrement refcount for object.
 * @kobj: object.
L
Linus Torvalds 已提交
586
 *
587
 * Decrement the refcount, and if 0, call kobject_cleanup().
L
Linus Torvalds 已提交
588
 */
589
void kobject_put(struct kobject *kobj)
L
Linus Torvalds 已提交
590
{
591
	if (kobj) {
A
Arjan van de Ven 已提交
592 593
		if (!kobj->state_initialized)
			WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "
594 595
			       "initialized, yet kobject_put() is being "
			       "called.\n", kobject_name(kobj), kobj);
L
Linus Torvalds 已提交
596
		kref_put(&kobj->kref, kobject_release);
597
	}
L
Linus Torvalds 已提交
598 599
}

600
static void dynamic_kobj_release(struct kobject *kobj)
J
Jun'ichi Nomura 已提交
601
{
602
	pr_debug("kobject: (%p): %s\n", kobj, __func__);
J
Jun'ichi Nomura 已提交
603 604 605
	kfree(kobj);
}

606
static struct kobj_type dynamic_kobj_ktype = {
607 608
	.release	= dynamic_kobj_release,
	.sysfs_ops	= &kobj_sysfs_ops,
J
Jun'ichi Nomura 已提交
609 610
};

611
/**
612 613 614 615 616 617
 * 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.
618
 * The kobject structure returned from here must be cleaned up with a
619
 * call to kobject_put() and not kfree(), as kobject_init() has
620
 * already been called on this structure.
621
 */
622
struct kobject *kobject_create(void)
623 624 625 626 627 628 629
{
	struct kobject *kobj;

	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
	if (!kobj)
		return NULL;

630
	kobject_init(kobj, &dynamic_kobj_ktype);
631 632 633 634 635 636 637 638 639
	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.
 *
D
Dave Young 已提交
640
 * This function creates a kobject structure dynamically and registers it
641
 * with sysfs.  When you are finished with this structure, call
642
 * kobject_put() and the structure will be dynamically freed when
643 644 645 646 647 648 649 650 651 652 653 654 655
 * 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;

656
	retval = kobject_add(kobj, parent, "%s", name);
657 658
	if (retval) {
		printk(KERN_WARNING "%s: kobject_add error: %d\n",
659
		       __func__, retval);
660 661 662 663 664 665 666
		kobject_put(kobj);
		kobj = NULL;
	}
	return kobj;
}
EXPORT_SYMBOL_GPL(kobject_create_and_add);

L
Linus Torvalds 已提交
667
/**
668 669
 * kset_init - initialize a kset for use
 * @k: kset
L
Linus Torvalds 已提交
670
 */
671
void kset_init(struct kset *k)
L
Linus Torvalds 已提交
672
{
673
	kobject_init_internal(&k->kobj);
L
Linus Torvalds 已提交
674 675 676 677
	INIT_LIST_HEAD(&k->list);
	spin_lock_init(&k->list_lock);
}

678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706
/* 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,
};
L
Linus Torvalds 已提交
707 708

/**
709 710
 * kset_register - initialize and add a kset.
 * @k: kset.
L
Linus Torvalds 已提交
711
 */
712
int kset_register(struct kset *k)
L
Linus Torvalds 已提交
713
{
714 715
	int err;

716 717
	if (!k)
		return -EINVAL;
718

L
Linus Torvalds 已提交
719
	kset_init(k);
720
	err = kobject_add_internal(&k->kobj);
721 722 723 724
	if (err)
		return err;
	kobject_uevent(&k->kobj, KOBJ_ADD);
	return 0;
L
Linus Torvalds 已提交
725 726 727
}

/**
728 729
 * kset_unregister - remove a kset.
 * @k: kset.
L
Linus Torvalds 已提交
730
 */
731
void kset_unregister(struct kset *k)
L
Linus Torvalds 已提交
732
{
733 734
	if (!k)
		return;
735
	kobject_put(&k->kobj);
L
Linus Torvalds 已提交
736 737 738
}

/**
739 740 741
 * kset_find_obj - search for object in kset.
 * @kset: kset we're looking in.
 * @name: object's name.
L
Linus Torvalds 已提交
742
 *
743 744 745
 * 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.
L
Linus Torvalds 已提交
746
 */
747
struct kobject *kset_find_obj(struct kset *kset, const char *name)
L
Linus Torvalds 已提交
748
{
749
	struct kobject *k;
750
	struct kobject *ret = NULL;
L
Linus Torvalds 已提交
751 752

	spin_lock(&kset->list_lock);
753
	list_for_each_entry(k, &kset->list, entry) {
754
		if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
L
Linus Torvalds 已提交
755 756 757 758 759 760 761 762
			ret = kobject_get(k);
			break;
		}
	}
	spin_unlock(&kset->list_lock);
	return ret;
}

763 764 765
static void kset_release(struct kobject *kobj)
{
	struct kset *kset = container_of(kobj, struct kset, kobj);
766
	pr_debug("kobject: '%s' (%p): %s\n",
767
		 kobject_name(kobj), kobj, __func__);
768 769 770
	kfree(kset);
}

771 772
static struct kobj_type kset_ktype = {
	.sysfs_ops	= &kobj_sysfs_ops,
773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791
	.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,
792
				const struct kset_uevent_ops *uevent_ops,
793 794 795
				struct kobject *parent_kobj)
{
	struct kset *kset;
796
	int retval;
797 798 799 800

	kset = kzalloc(sizeof(*kset), GFP_KERNEL);
	if (!kset)
		return NULL;
801 802 803 804 805
	retval = kobject_set_name(&kset->kobj, name);
	if (retval) {
		kfree(kset);
		return NULL;
	}
806 807 808 809
	kset->uevent_ops = uevent_ops;
	kset->kobj.parent = parent_kobj;

	/*
810
	 * The kobject of this kset will have a type of kset_ktype and belong to
811 812 813
	 * no kset itself.  That way we can properly free it when it is
	 * finished being used.
	 */
814
	kset->kobj.ktype = &kset_ktype;
815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
	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,
835
				 const struct kset_uevent_ops *uevent_ops,
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852
				 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);

L
Linus Torvalds 已提交
853 854 855 856 857 858
EXPORT_SYMBOL(kobject_get);
EXPORT_SYMBOL(kobject_put);
EXPORT_SYMBOL(kobject_del);

EXPORT_SYMBOL(kset_register);
EXPORT_SYMBOL(kset_unregister);