Blame view

lib/kobject.c 23.2 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
  /*
   * kobject.c - library routines for handling generic kernel objects
   *
   * Copyright (c) 2002-2003 Patrick Mochel <mochel@osdl.org>
f0e7e1bd7   Greg Kroah-Hartman   kobject: update t...
5
6
   * Copyright (c) 2006-2007 Greg Kroah-Hartman <greg@kroah.com>
   * Copyright (c) 2006-2007 Novell Inc.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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>
4e57b6817   Tim Schmielau   [PATCH] fix missi...
19
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20

e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
21
22
23
  /*
   * populate_dir - populate directory with attributes.
   * @kobj: object we're working on.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
   *
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
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.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
30
  static int populate_dir(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
  {
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
32
33
  	struct kobj_type *t = get_ktype(kobj);
  	struct attribute *attr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
  	int error = 0;
  	int i;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
36

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
38
  	if (t && t->default_attrs) {
  		for (i = 0; (attr = t->default_attrs[i]) != NULL; i++) {
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
39
40
  			error = sysfs_create_file(kobj, attr);
  			if (error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
42
43
44
45
  				break;
  		}
  	}
  	return error;
  }
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
46
  static int create_dir(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47
48
49
  {
  	int error = 0;
  	if (kobject_name(kobj)) {
90bc61359   Eric W. Biederman   sysfs: Remove fir...
50
  		error = sysfs_create_dir(kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
  		if (!error) {
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
52
53
  			error = populate_dir(kobj);
  			if (error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
57
58
  				sysfs_remove_dir(kobj);
  		}
  	}
  	return error;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
  static int get_kobj_path_length(struct kobject *kobj)
  {
  	int length = 1;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
62
  	struct kobject *parent = kobj;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63

e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
64
  	/* walk up the ancestors until we hit the one pointing to the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
67
68
  	 * root.
  	 * Add 1 to strlen for leading '/' of each level.
  	 */
  	do {
b365b3daf   Chuck Ebbert   [PATCH] kobject: ...
69
70
  		if (kobject_name(parent) == NULL)
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
74
75
76
77
78
  		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)
  {
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
79
  	struct kobject *parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
82
83
84
85
  
  	--length;
  	for (parent = kobj; parent; parent = parent->parent) {
  		int cur = strlen(kobject_name(parent));
  		/* back up enough to print this name with '/' */
  		length -= cur;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
86
  		strncpy(path + length, kobject_name(parent), cur);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
  		*(path + --length) = '/';
  	}
9f66fa2a4   Greg Kroah-Hartman   kobject: clean up...
89
90
  	pr_debug("kobject: '%s' (%p): %s: path = '%s'
  ", kobject_name(kobj),
810304db7   Harvey Harrison   lib: replace rema...
91
  		 kobj, __func__, path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
93
94
  }
  
  /**
72fd4a35a   Robert P. J. Day   [PATCH] Numerous ...
95
   * kobject_get_path - generate and return the path associated with a given kobj and kset pair.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
98
   *
   * @kobj:	kobject in question, with which to build the path
   * @gfp_mask:	the allocation type used to allocate the path
72fd4a35a   Robert P. J. Day   [PATCH] Numerous ...
99
100
   *
   * The result must be freed by the caller with kfree().
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
   */
fd4f2df24   Al Viro   [PATCH] gfp_t: lib/*
102
  char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
104
105
106
107
  {
  	char *path;
  	int len;
  
  	len = get_kobj_path_length(kobj);
b365b3daf   Chuck Ebbert   [PATCH] kobject: ...
108
109
  	if (len == 0)
  		return NULL;
4668edc33   Burman Yan   [PATCH] kernel co...
110
  	path = kzalloc(len, gfp_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
112
  	if (!path)
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
116
  	fill_kobj_path(kobj, path, len);
  
  	return path;
  }
80fc9f532   Dmitry Torokhov   Input: add missin...
117
  EXPORT_SYMBOL_GPL(kobject_get_path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118

0f4dafc05   Kay Sievers   Kobject: auto-cle...
119
120
  /* add the kobject to its kset's list */
  static void kobj_kset_join(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
  {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
122
  	if (!kobj->kset)
31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
123
  		return;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
124
125
126
127
128
  
  	kset_get(kobj->kset);
  	spin_lock(&kobj->kset->list_lock);
  	list_add_tail(&kobj->entry, &kobj->kset->list);
  	spin_unlock(&kobj->kset->list_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
  }
0f4dafc05   Kay Sievers   Kobject: auto-cle...
130
131
132
133
134
  /* remove the kobject from its kset's list */
  static void kobj_kset_leave(struct kobject *kobj)
  {
  	if (!kobj->kset)
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135

0f4dafc05   Kay Sievers   Kobject: auto-cle...
136
137
138
139
140
  	spin_lock(&kobj->kset->list_lock);
  	list_del_init(&kobj->entry);
  	spin_unlock(&kobj->kset->list_lock);
  	kset_put(kobj->kset);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141

e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
142
  static void kobject_init_internal(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
  {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
144
145
146
147
  	if (!kobj)
  		return;
  	kref_init(&kobj->kref);
  	INIT_LIST_HEAD(&kobj->entry);
a4573c488   Greg Kroah-Hartman   kobject: properly...
148
149
150
151
  	kobj->state_in_sysfs = 0;
  	kobj->state_add_uevent_sent = 0;
  	kobj->state_remove_uevent_sent = 0;
  	kobj->state_initialized = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
  }
0f4dafc05   Kay Sievers   Kobject: auto-cle...
153

9e7bbccd0   Greg Kroah-Hartman   Kobject: remove k...
154
  static int kobject_add_internal(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
156
  {
  	int error = 0;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
157
  	struct kobject *parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158

0f4dafc05   Kay Sievers   Kobject: auto-cle...
159
  	if (!kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
  		return -ENOENT;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
161

af5ca3f4e   Kay Sievers   Driver core: chan...
162
  	if (!kobj->name || !kobj->name[0]) {
d955c78ac   Arjan van de Ven   Example use of WA...
163
  		WARN(1, "kobject: (%p): attempted to be registered with empty "
9f66fa2a4   Greg Kroah-Hartman   kobject: clean up...
164
165
  			 "name!
  ", kobj);
c171fef5c   Greg Kroah-Hartman   [PATCH] kobject_a...
166
167
  		return -EINVAL;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168

0f4dafc05   Kay Sievers   Kobject: auto-cle...
169
  	parent = kobject_get(kobj->parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170

0f4dafc05   Kay Sievers   Kobject: auto-cle...
171
  	/* join kset if set, use it as parent if we do not already have one */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
  	if (kobj->kset) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
173
  		if (!parent)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
  			parent = kobject_get(&kobj->kset->kobj);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
175
  		kobj_kset_join(kobj);
460f7e9a1   Dmitriy Monakhov   kobject: kobject_...
176
  		kobj->parent = parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178

0f4dafc05   Kay Sievers   Kobject: auto-cle...
179
180
  	pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'
  ",
810304db7   Harvey Harrison   lib: replace rema...
181
  		 kobject_name(kobj), kobj, __func__,
0f4dafc05   Kay Sievers   Kobject: auto-cle...
182
  		 parent ? kobject_name(parent) : "<NULL>",
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
183
  		 kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>");
0f4dafc05   Kay Sievers   Kobject: auto-cle...
184

90bc61359   Eric W. Biederman   sysfs: Remove fir...
185
  	error = create_dir(kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  	if (error) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
187
188
189
  		kobj_kset_leave(kobj);
  		kobject_put(parent);
  		kobj->parent = NULL;
dcd0da002   Greg Kroah-Hartman   [PATCH] Kobject: ...
190
191
192
  
  		/* be noisy on error issues */
  		if (error == -EEXIST)
9e7bbccd0   Greg Kroah-Hartman   Kobject: remove k...
193
  			printk(KERN_ERR "%s failed for %s with "
5c73a3fba   Greg Kroah-Hartman   kobject: use the ...
194
195
196
  			       "-EEXIST, don't try to register things with "
  			       "the same name in the same directory.
  ",
810304db7   Harvey Harrison   lib: replace rema...
197
  			       __func__, kobject_name(kobj));
dcd0da002   Greg Kroah-Hartman   [PATCH] Kobject: ...
198
  		else
9e7bbccd0   Greg Kroah-Hartman   Kobject: remove k...
199
200
  			printk(KERN_ERR "%s failed for %s (%d)
  ",
810304db7   Harvey Harrison   lib: replace rema...
201
  			       __func__, kobject_name(kobj), error);
5c73a3fba   Greg Kroah-Hartman   kobject: use the ...
202
  		dump_stack();
0f4dafc05   Kay Sievers   Kobject: auto-cle...
203
204
  	} else
  		kobj->state_in_sysfs = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
206
207
  
  	return error;
  }
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
208
  /**
663a47430   Greg Kroah-Hartman   kobject: fix up k...
209
210
211
212
213
   * 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.
   */
1fa5ae857   Kay Sievers   driver core: get ...
214
  int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
663a47430   Greg Kroah-Hartman   kobject: fix up k...
215
216
  				  va_list vargs)
  {
9f255651f   Kay Sievers   kobject: replace ...
217
218
  	const char *old_name = kobj->name;
  	char *s;
663a47430   Greg Kroah-Hartman   kobject: fix up k...
219

8a577ffc7   Kay Sievers   driver: dont upda...
220
221
  	if (kobj->name && !fmt)
  		return 0;
a4ca66174   Kay Sievers   kobject: do not c...
222
223
224
  	kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs);
  	if (!kobj->name)
  		return -ENOMEM;
663a47430   Greg Kroah-Hartman   kobject: fix up k...
225

9f255651f   Kay Sievers   kobject: replace ...
226
  	/* ewww... some of these buggers have '/' in the name ... */
25fdeb3f4   Ingo Oeser   kobject: Replace ...
227
  	while ((s = strchr(kobj->name, '/')))
9f255651f   Kay Sievers   kobject: replace ...
228
229
230
  		s[0] = '!';
  
  	kfree(old_name);
663a47430   Greg Kroah-Hartman   kobject: fix up k...
231
232
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
234
  
  /**
8c4606b1a   Greg Kroah-Hartman   kobject: fix the ...
235
   * kobject_set_name - Set the name of a kobject
663a47430   Greg Kroah-Hartman   kobject: fix up k...
236
   * @kobj: struct kobject to set the name of
8c4606b1a   Greg Kroah-Hartman   kobject: fix the ...
237
   * @fmt: format string used to build the name
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
   *
8c4606b1a   Greg Kroah-Hartman   kobject: fix the ...
239
240
241
   * 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.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
   */
663a47430   Greg Kroah-Hartman   kobject: fix up k...
243
  int kobject_set_name(struct kobject *kobj, const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
  {
a4ca66174   Kay Sievers   kobject: do not c...
245
  	va_list vargs;
663a47430   Greg Kroah-Hartman   kobject: fix up k...
246
  	int retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247

a4ca66174   Kay Sievers   kobject: do not c...
248
249
250
  	va_start(vargs, fmt);
  	retval = kobject_set_name_vargs(kobj, fmt, vargs);
  	va_end(vargs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251

663a47430   Greg Kroah-Hartman   kobject: fix up k...
252
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
  EXPORT_SYMBOL(kobject_set_name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
  /**
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
256
   * kobject_init - initialize a kobject structure
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
257
258
259
260
261
262
263
264
265
266
   * @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.
   */
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
267
  void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
268
269
270
271
272
273
274
275
276
277
278
279
  {
  	char *err_str;
  
  	if (!kobj) {
  		err_str = "invalid kobject pointer!";
  		goto error;
  	}
  	if (!ktype) {
  		err_str = "must have a ktype to be initialized properly!
  ";
  		goto error;
  	}
0f4dafc05   Kay Sievers   Kobject: auto-cle...
280
  	if (kobj->state_initialized) {
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
281
  		/* do not error out as sometimes we can recover */
0f4dafc05   Kay Sievers   Kobject: auto-cle...
282
283
284
  		printk(KERN_ERR "kobject (%p): tried to init an initialized "
  		       "object, something is seriously wrong.
  ", kobj);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
285
286
  		dump_stack();
  	}
a4573c488   Greg Kroah-Hartman   kobject: properly...
287
  	kobject_init_internal(kobj);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
288
289
290
291
  	kobj->ktype = ktype;
  	return;
  
  error:
0f4dafc05   Kay Sievers   Kobject: auto-cle...
292
293
  	printk(KERN_ERR "kobject (%p): %s
  ", kobj, err_str);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
294
295
  	dump_stack();
  }
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
296
  EXPORT_SYMBOL(kobject_init);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
297

244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
298
299
300
  static int kobject_add_varg(struct kobject *kobj, struct kobject *parent,
  			    const char *fmt, va_list vargs)
  {
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
301
  	int retval;
a4ca66174   Kay Sievers   kobject: do not c...
302
  	retval = kobject_set_name_vargs(kobj, fmt, vargs);
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
303
304
305
306
307
308
  	if (retval) {
  		printk(KERN_ERR "kobject: can not set name properly!
  ");
  		return retval;
  	}
  	kobj->parent = parent;
9e7bbccd0   Greg Kroah-Hartman   Kobject: remove k...
309
  	return kobject_add_internal(kobj);
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
310
311
312
  }
  
  /**
b2d6db587   Greg Kroah-Hartman   Kobject: rename k...
313
   * kobject_add - the main kobject add function
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
   * @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.
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
329
330
331
   * Under no instance should the kobject that is passed to this function
   * be directly freed with a call to kfree(), that can leak memory.
   *
0f4dafc05   Kay Sievers   Kobject: auto-cle...
332
   * Note, no "add" uevent will be created with this call, the caller should set
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
333
334
335
336
   * 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.
   */
b2d6db587   Greg Kroah-Hartman   Kobject: rename k...
337
338
  int kobject_add(struct kobject *kobj, struct kobject *parent,
  		const char *fmt, ...)
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
339
340
341
342
343
344
  {
  	va_list args;
  	int retval;
  
  	if (!kobj)
  		return -EINVAL;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
345
346
347
348
349
350
351
352
  	if (!kobj->state_initialized) {
  		printk(KERN_ERR "kobject '%s' (%p): tried to add an "
  		       "uninitialized object, something is seriously wrong.
  ",
  		       kobject_name(kobj), kobj);
  		dump_stack();
  		return -EINVAL;
  	}
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
353
354
355
356
357
358
  	va_start(args, fmt);
  	retval = kobject_add_varg(kobj, parent, fmt, args);
  	va_end(args);
  
  	return retval;
  }
b2d6db587   Greg Kroah-Hartman   Kobject: rename k...
359
  EXPORT_SYMBOL(kobject_add);
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
360

e86000d04   Greg Kroah-Hartman   kobject: add kobj...
361
  /**
c11c4154e   Greg Kroah-Hartman   kobject: add kobj...
362
363
364
365
366
367
   * 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.
   *
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
368
   * This function combines the call to kobject_init() and
b2d6db587   Greg Kroah-Hartman   Kobject: rename k...
369
370
   * kobject_add().  The same type of error handling after a call to
   * kobject_add() and kobject lifetime rules are the same here.
c11c4154e   Greg Kroah-Hartman   kobject: add kobj...
371
372
373
374
375
376
   */
  int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
  			 struct kobject *parent, const char *fmt, ...)
  {
  	va_list args;
  	int retval;
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
377
  	kobject_init(kobj, ktype);
c11c4154e   Greg Kroah-Hartman   kobject: add kobj...
378
379
380
381
382
383
384
385
386
387
  
  	va_start(args, fmt);
  	retval = kobject_add_varg(kobj, parent, fmt, args);
  	va_end(args);
  
  	return retval;
  }
  EXPORT_SYMBOL_GPL(kobject_init_and_add);
  
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
388
389
390
   * kobject_rename - change the name of an object
   * @kobj: object in question.
   * @new_name: object's new name
030c1d2bf   Eric W. Biederman   kobject: Fix kobj...
391
392
393
394
395
   *
   * 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.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
397
  int kobject_rename(struct kobject *kobj, const char *new_name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
399
  {
  	int error = 0;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
400
  	const char *devpath = NULL;
0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
401
  	const char *dup_name = NULL, *name;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
402
403
  	char *devpath_string = NULL;
  	char *envp[2];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404
405
406
407
  
  	kobj = kobject_get(kobj);
  	if (!kobj)
  		return -EINVAL;
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
408
409
  	if (!kobj->parent)
  		return -EINVAL;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
410
411
412
413
414
415
416
417
418
419
420
421
422
423
  
  	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;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
424

0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
425
426
427
428
429
  	name = dup_name = kstrdup(new_name, GFP_KERNEL);
  	if (!name) {
  		error = -ENOMEM;
  		goto out;
  	}
90bc61359   Eric W. Biederman   sysfs: Remove fir...
430
  	error = sysfs_rename_dir(kobj, new_name);
0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
431
432
433
434
435
436
  	if (error)
  		goto out;
  
  	/* Install the new kobject name */
  	dup_name = kobj->name;
  	kobj->name = name;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
437
438
439
440
  
  	/* 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. */
0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
441
  	kobject_uevent_env(kobj, KOBJ_MOVE, envp);
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
442
443
  
  out:
0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
444
  	kfree(dup_name);
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
445
446
  	kfree(devpath_string);
  	kfree(devpath);
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
447
448
449
450
  	kobject_put(kobj);
  
  	return error;
  }
8344b568f   Alex Chiang   PCI: ACPI PCI slo...
451
  EXPORT_SYMBOL_GPL(kobject_rename);
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
452
453
  
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
454
455
456
   * kobject_move - move object to another parent
   * @kobj: object in question.
   * @new_parent: object's new parent (can be NULL)
8a82472f8   Cornelia Huck   driver core: Intr...
457
   */
8a82472f8   Cornelia Huck   driver core: Intr...
458
459
460
461
462
463
464
465
466
467
468
469
470
  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) {
c744aeae9   Cornelia Huck   driver core: Allo...
471
472
  		if (kobj->kset)
  			new_parent = kobject_get(&kobj->kset->kobj);
8a82472f8   Cornelia Huck   driver core: Intr...
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
  	}
  	/* 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;
9e993efb0   Dmitriy Monakhov   kobject: new_devi...
493
  	new_parent = NULL;
8a82472f8   Cornelia Huck   driver core: Intr...
494
495
496
  	kobject_put(old_parent);
  	kobject_uevent_env(kobj, KOBJ_MOVE, envp);
  out:
9e993efb0   Dmitriy Monakhov   kobject: new_devi...
497
  	kobject_put(new_parent);
8a82472f8   Cornelia Huck   driver core: Intr...
498
499
500
501
502
503
504
  	kobject_put(kobj);
  	kfree(devpath_string);
  	kfree(devpath);
  	return error;
  }
  
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
505
506
   * kobject_del - unlink kobject from hierarchy.
   * @kobj: object.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
508
  void kobject_del(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
  {
31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
510
511
  	if (!kobj)
  		return;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
512

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513
  	sysfs_remove_dir(kobj);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
514
515
516
517
  	kobj->state_in_sysfs = 0;
  	kobj_kset_leave(kobj);
  	kobject_put(kobj->parent);
  	kobj->parent = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
518
519
520
  }
  
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
521
522
   * kobject_get - increment refcount for object.
   * @kobj: object.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
524
  struct kobject *kobject_get(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
525
526
527
528
529
  {
  	if (kobj)
  		kref_get(&kobj->kref);
  	return kobj;
  }
18041f477   Greg Kroah-Hartman   kobject: make kob...
530
531
532
  /*
   * kobject_cleanup - free kobject resources.
   * @kobj: object to cleanup
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
533
   */
18041f477   Greg Kroah-Hartman   kobject: make kob...
534
  static void kobject_cleanup(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535
  {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
536
  	struct kobj_type *t = get_ktype(kobj);
af5ca3f4e   Kay Sievers   Driver core: chan...
537
  	const char *name = kobj->name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538

9f66fa2a4   Greg Kroah-Hartman   kobject: clean up...
539
540
  	pr_debug("kobject: '%s' (%p): %s
  ",
810304db7   Harvey Harrison   lib: replace rema...
541
  		 kobject_name(kobj), kobj, __func__);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
  
  	if (t && !t->release)
  		pr_debug("kobject: '%s' (%p): does not have a release() "
  			 "function, it is broken and must be fixed.
  ",
  			 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
  ",
  			 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
  ",
  			 kobject_name(kobj), kobj);
  		kobject_del(kobj);
  	}
ce2c9cb02   Greg Kroah-Hartman   kobject: remove t...
564
  	if (t && t->release) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
565
566
567
  		pr_debug("kobject: '%s' (%p): calling ktype release
  ",
  			 kobject_name(kobj), kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
  		t->release(kobj);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
569
570
571
  	}
  
  	/* free name if we allocated it */
af5ca3f4e   Kay Sievers   Driver core: chan...
572
  	if (name) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
573
574
  		pr_debug("kobject: '%s': free name
  ", name);
ce2c9cb02   Greg Kroah-Hartman   kobject: remove t...
575
576
  		kfree(name);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
578
579
580
581
582
583
584
  }
  
  static void kobject_release(struct kref *kref)
  {
  	kobject_cleanup(container_of(kref, struct kobject, kref));
  }
  
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
585
586
   * kobject_put - decrement refcount for object.
   * @kobj: object.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
   *
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
588
   * Decrement the refcount, and if 0, call kobject_cleanup().
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
590
  void kobject_put(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591
  {
c1ebdae51   Greg Kroah-Hartman   kobject: catch ko...
592
  	if (kobj) {
d955c78ac   Arjan van de Ven   Example use of WA...
593
594
  		if (!kobj->state_initialized)
  			WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "
c1ebdae51   Greg Kroah-Hartman   kobject: catch ko...
595
596
597
  			       "initialized, yet kobject_put() is being "
  			       "called.
  ", kobject_name(kobj), kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
  		kref_put(&kobj->kref, kobject_release);
c1ebdae51   Greg Kroah-Hartman   kobject: catch ko...
599
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
600
  }
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
601
  static void dynamic_kobj_release(struct kobject *kobj)
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
602
  {
810304db7   Harvey Harrison   lib: replace rema...
603
604
  	pr_debug("kobject: (%p): %s
  ", kobj, __func__);
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
605
606
  	kfree(kobj);
  }
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
607
  static struct kobj_type dynamic_kobj_ktype = {
386f275f5   Kay Sievers   Driver Core: swit...
608
609
  	.release	= dynamic_kobj_release,
  	.sysfs_ops	= &kobj_sysfs_ops,
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
610
  };
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
611
  /**
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
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.
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
618
   * The kobject structure returned from here must be cleaned up with a
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
619
   * call to kobject_put() and not kfree(), as kobject_init() has
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
620
   * already been called on this structure.
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
621
   */
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
622
  struct kobject *kobject_create(void)
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
623
624
625
626
627
628
  {
  	struct kobject *kobj;
  
  	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
  	if (!kobj)
  		return NULL;
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
629
  	kobject_init(kobj, &dynamic_kobj_ktype);
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
630
631
632
633
634
635
636
637
638
  	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.
   *
f70701a34   Dave Young   kobject: kerneldo...
639
   * This function creates a kobject structure dynamically and registers it
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
640
   * with sysfs.  When you are finished with this structure, call
78a2d906b   Greg Kroah-Hartman   Kobject: convert ...
641
   * kobject_put() and the structure will be dynamically freed when
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
642
643
644
645
646
647
648
649
650
651
652
653
   * 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;
b2d6db587   Greg Kroah-Hartman   Kobject: rename k...
654
  	retval = kobject_add(kobj, parent, "%s", name);
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
655
656
657
  	if (retval) {
  		printk(KERN_WARNING "%s: kobject_add error: %d
  ",
810304db7   Harvey Harrison   lib: replace rema...
658
  		       __func__, retval);
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
659
660
661
662
663
664
  		kobject_put(kobj);
  		kobj = NULL;
  	}
  	return kobj;
  }
  EXPORT_SYMBOL_GPL(kobject_create_and_add);
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
665
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
666
667
   * kset_init - initialize a kset for use
   * @k: kset
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
669
  void kset_init(struct kset *k)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
  {
e1543ddf7   Greg Kroah-Hartman   Kobject: remove k...
671
  	kobject_init_internal(&k->kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
672
673
674
  	INIT_LIST_HEAD(&k->list);
  	spin_lock_init(&k->list_lock);
  }
23b5212cc   Kay Sievers   Driver Core: add ...
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
  /* 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;
  }
52cf25d0a   Emese Revfy   Driver core: Cons...
699
  const struct sysfs_ops kobj_sysfs_ops = {
23b5212cc   Kay Sievers   Driver Core: add ...
700
701
702
  	.show	= kobj_attr_show,
  	.store	= kobj_attr_store,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703
704
  
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
705
706
   * kset_register - initialize and add a kset.
   * @k: kset.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
707
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
708
  int kset_register(struct kset *k)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
709
  {
80f03e349   Kay Sievers   Driver core: add ...
710
  	int err;
31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
711
712
  	if (!k)
  		return -EINVAL;
80f03e349   Kay Sievers   Driver core: add ...
713

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
714
  	kset_init(k);
12e339ac6   Greg Kroah-Hartman   Kset: remove kset...
715
  	err = kobject_add_internal(&k->kobj);
80f03e349   Kay Sievers   Driver core: add ...
716
717
718
719
  	if (err)
  		return err;
  	kobject_uevent(&k->kobj, KOBJ_ADD);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
721
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
722
723
   * kset_unregister - remove a kset.
   * @k: kset.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
724
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
725
  void kset_unregister(struct kset *k)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726
  {
31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
727
728
  	if (!k)
  		return;
78a2d906b   Greg Kroah-Hartman   Kobject: convert ...
729
  	kobject_put(&k->kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
730
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
731
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
732
733
734
   * kset_find_obj - search for object in kset.
   * @kset: kset we're looking in.
   * @name: object's name.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
735
   *
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
736
737
738
   * 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.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
740
  struct kobject *kset_find_obj(struct kset *kset, const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
741
  {
c6a2a3dc2   Robert P. J. Day   Kobject: Replace ...
742
  	struct kobject *k;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
743
  	struct kobject *ret = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
744
745
  
  	spin_lock(&kset->list_lock);
c25d1dfbd   Robin Holt   kobject: Introduc...
746

c6a2a3dc2   Robert P. J. Day   Kobject: Replace ...
747
  	list_for_each_entry(k, &kset->list, entry) {
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
748
  		if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
749
750
751
752
  			ret = kobject_get(k);
  			break;
  		}
  	}
c25d1dfbd   Robin Holt   kobject: Introduc...
753

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
755
756
  	spin_unlock(&kset->list_lock);
  	return ret;
  }
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
757
758
759
  static void kset_release(struct kobject *kobj)
  {
  	struct kset *kset = container_of(kobj, struct kset, kobj);
9f66fa2a4   Greg Kroah-Hartman   kobject: clean up...
760
761
  	pr_debug("kobject: '%s' (%p): %s
  ",
810304db7   Harvey Harrison   lib: replace rema...
762
  		 kobject_name(kobj), kobj, __func__);
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
763
764
  	kfree(kset);
  }
386f275f5   Kay Sievers   Driver Core: swit...
765
766
  static struct kobj_type kset_ktype = {
  	.sysfs_ops	= &kobj_sysfs_ops,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
  	.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,
9cd43611c   Emese Revfy   kobject: Constify...
786
  				const struct kset_uevent_ops *uevent_ops,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
787
788
789
  				struct kobject *parent_kobj)
  {
  	struct kset *kset;
d9cd8f378   Dave Young   kobject: make kse...
790
  	int retval;
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
791
792
793
794
  
  	kset = kzalloc(sizeof(*kset), GFP_KERNEL);
  	if (!kset)
  		return NULL;
d9cd8f378   Dave Young   kobject: make kse...
795
796
797
798
799
  	retval = kobject_set_name(&kset->kobj, name);
  	if (retval) {
  		kfree(kset);
  		return NULL;
  	}
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
800
801
802
803
  	kset->uevent_ops = uevent_ops;
  	kset->kobj.parent = parent_kobj;
  
  	/*
386f275f5   Kay Sievers   Driver Core: swit...
804
  	 * The kobject of this kset will have a type of kset_ktype and belong to
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
805
806
807
  	 * no kset itself.  That way we can properly free it when it is
  	 * finished being used.
  	 */
386f275f5   Kay Sievers   Driver Core: swit...
808
  	kset->kobj.ktype = &kset_ktype;
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
  	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,
9cd43611c   Emese Revfy   kobject: Constify...
829
  				 const struct kset_uevent_ops *uevent_ops,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
  				 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);
bc451f205   Eric W. Biederman   kobj: Add basic i...
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
  
  static DEFINE_SPINLOCK(kobj_ns_type_lock);
  static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES];
  
  int kobj_ns_type_register(const struct kobj_ns_type_operations *ops)
  {
  	enum kobj_ns_type type = ops->type;
  	int error;
  
  	spin_lock(&kobj_ns_type_lock);
  
  	error = -EINVAL;
  	if (type >= KOBJ_NS_TYPES)
  		goto out;
  
  	error = -EINVAL;
  	if (type <= KOBJ_NS_TYPE_NONE)
  		goto out;
  
  	error = -EBUSY;
  	if (kobj_ns_ops_tbl[type])
  		goto out;
  
  	error = 0;
  	kobj_ns_ops_tbl[type] = ops;
  
  out:
  	spin_unlock(&kobj_ns_type_lock);
  	return error;
  }
  
  int kobj_ns_type_registered(enum kobj_ns_type type)
  {
  	int registered = 0;
  
  	spin_lock(&kobj_ns_type_lock);
  	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES))
  		registered = kobj_ns_ops_tbl[type] != NULL;
  	spin_unlock(&kobj_ns_type_lock);
  
  	return registered;
  }
  
  const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent)
  {
  	const struct kobj_ns_type_operations *ops = NULL;
  
  	if (parent && parent->ktype->child_ns_type)
  		ops = parent->ktype->child_ns_type(parent);
  
  	return ops;
  }
  
  const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj)
  {
  	return kobj_child_ns_ops(kobj->parent);
  }
a685e0898   Al Viro   Delay struct net ...
903
  void *kobj_ns_grab_current(enum kobj_ns_type type)
bc451f205   Eric W. Biederman   kobj: Add basic i...
904
  {
a685e0898   Al Viro   Delay struct net ...
905
  	void *ns = NULL;
bc451f205   Eric W. Biederman   kobj: Add basic i...
906
907
908
909
  
  	spin_lock(&kobj_ns_type_lock);
  	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
  	    kobj_ns_ops_tbl[type])
a685e0898   Al Viro   Delay struct net ...
910
  		ns = kobj_ns_ops_tbl[type]->grab_current_ns();
bc451f205   Eric W. Biederman   kobj: Add basic i...
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
  	spin_unlock(&kobj_ns_type_lock);
  
  	return ns;
  }
  
  const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk)
  {
  	const void *ns = NULL;
  
  	spin_lock(&kobj_ns_type_lock);
  	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
  	    kobj_ns_ops_tbl[type])
  		ns = kobj_ns_ops_tbl[type]->netlink_ns(sk);
  	spin_unlock(&kobj_ns_type_lock);
  
  	return ns;
  }
  
  const void *kobj_ns_initial(enum kobj_ns_type type)
  {
  	const void *ns = NULL;
  
  	spin_lock(&kobj_ns_type_lock);
  	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
  	    kobj_ns_ops_tbl[type])
  		ns = kobj_ns_ops_tbl[type]->initial_ns();
  	spin_unlock(&kobj_ns_type_lock);
  
  	return ns;
  }
a685e0898   Al Viro   Delay struct net ...
941
  void kobj_ns_drop(enum kobj_ns_type type, void *ns)
bc451f205   Eric W. Biederman   kobj: Add basic i...
942
  {
a685e0898   Al Viro   Delay struct net ...
943
944
945
946
947
  	spin_lock(&kobj_ns_type_lock);
  	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
  	    kobj_ns_ops_tbl[type] && kobj_ns_ops_tbl[type]->drop_ns)
  		kobj_ns_ops_tbl[type]->drop_ns(ns);
  	spin_unlock(&kobj_ns_type_lock);
bc451f205   Eric W. Biederman   kobj: Add basic i...
948
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
949
950
  EXPORT_SYMBOL(kobject_get);
  EXPORT_SYMBOL(kobject_put);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
951
952
953
954
  EXPORT_SYMBOL(kobject_del);
  
  EXPORT_SYMBOL(kset_register);
  EXPORT_SYMBOL(kset_unregister);