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
   *
   * 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>
8bc3bcc93   Paul Gortmaker   lib: reduce the u...
17
  #include <linux/export.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
  #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
  {
  	int error = 0;
6b9606106   Yan   lib/kobject.c : R...
49
50
51
52
53
  	error = sysfs_create_dir(kobj);
  	if (!error) {
  		error = populate_dir(kobj);
  		if (error)
  			sysfs_remove_dir(kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
  	}
  	return error;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
  static int get_kobj_path_length(struct kobject *kobj)
  {
  	int length = 1;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
60
  	struct kobject *parent = kobj;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61

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

0f4dafc05   Kay Sievers   Kobject: auto-cle...
117
118
  /* add the kobject to its kset's list */
  static void kobj_kset_join(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
  {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
120
  	if (!kobj->kset)
31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
121
  		return;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
122
123
124
125
126
  
  	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
127
  }
0f4dafc05   Kay Sievers   Kobject: auto-cle...
128
129
130
131
132
  /* 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
133

0f4dafc05   Kay Sievers   Kobject: auto-cle...
134
135
136
137
138
  	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
139

e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
140
  static void kobject_init_internal(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
  {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
142
143
144
145
  	if (!kobj)
  		return;
  	kref_init(&kobj->kref);
  	INIT_LIST_HEAD(&kobj->entry);
a4573c488   Greg Kroah-Hartman   kobject: properly...
146
147
148
149
  	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
150
  }
0f4dafc05   Kay Sievers   Kobject: auto-cle...
151

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

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

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

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

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

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

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

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

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

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

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

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

e86000d04   Greg Kroah-Hartman   kobject: add kobj...
359
  /**
c11c4154e   Greg Kroah-Hartman   kobject: add kobj...
360
361
362
363
364
365
   * 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...
366
   * This function combines the call to kobject_init() and
b2d6db587   Greg Kroah-Hartman   Kobject: rename k...
367
368
   * 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...
369
370
371
372
373
374
   */
  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...
375
  	kobject_init(kobj, ktype);
c11c4154e   Greg Kroah-Hartman   kobject: add kobj...
376
377
378
379
380
381
382
383
384
385
  
  	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...
386
387
388
   * 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...
389
390
391
392
393
   *
   * 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
394
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
395
  int kobject_rename(struct kobject *kobj, const char *new_name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
397
  {
  	int error = 0;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
398
  	const char *devpath = NULL;
0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
399
  	const char *dup_name = NULL, *name;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
400
401
  	char *devpath_string = NULL;
  	char *envp[2];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
403
404
405
  
  	kobj = kobject_get(kobj);
  	if (!kobj)
  		return -EINVAL;
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
406
407
  	if (!kobj->parent)
  		return -EINVAL;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
408
409
410
411
412
413
414
415
416
417
418
419
420
421
  
  	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...
422

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

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

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

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
753
754
  	spin_unlock(&kset->list_lock);
  	return ret;
  }
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
755
756
757
  static void kset_release(struct kobject *kobj)
  {
  	struct kset *kset = container_of(kobj, struct kset, kobj);
9f66fa2a4   Greg Kroah-Hartman   kobject: clean up...
758
759
  	pr_debug("kobject: '%s' (%p): %s
  ",
810304db7   Harvey Harrison   lib: replace rema...
760
  		 kobject_name(kobj), kobj, __func__);
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
761
762
  	kfree(kset);
  }
386f275f5   Kay Sievers   Driver Core: swit...
763
764
  static struct kobj_type kset_ktype = {
  	.sysfs_ops	= &kobj_sysfs_ops,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
  	.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...
784
  				const struct kset_uevent_ops *uevent_ops,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
785
786
787
  				struct kobject *parent_kobj)
  {
  	struct kset *kset;
d9cd8f378   Dave Young   kobject: make kse...
788
  	int retval;
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
789
790
791
792
  
  	kset = kzalloc(sizeof(*kset), GFP_KERNEL);
  	if (!kset)
  		return NULL;
d9cd8f378   Dave Young   kobject: make kse...
793
794
795
796
797
  	retval = kobject_set_name(&kset->kobj, name);
  	if (retval) {
  		kfree(kset);
  		return NULL;
  	}
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
798
799
800
801
  	kset->uevent_ops = uevent_ops;
  	kset->kobj.parent = parent_kobj;
  
  	/*
386f275f5   Kay Sievers   Driver Core: swit...
802
  	 * The kobject of this kset will have a type of kset_ktype and belong to
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
803
804
805
  	 * no kset itself.  That way we can properly free it when it is
  	 * finished being used.
  	 */
386f275f5   Kay Sievers   Driver Core: swit...
806
  	kset->kobj.ktype = &kset_ktype;
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
  	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...
827
  				 const struct kset_uevent_ops *uevent_ops,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
  				 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...
844
845
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
  
  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 ...
901
  void *kobj_ns_grab_current(enum kobj_ns_type type)
bc451f205   Eric W. Biederman   kobj: Add basic i...
902
  {
a685e0898   Al Viro   Delay struct net ...
903
  	void *ns = NULL;
bc451f205   Eric W. Biederman   kobj: Add basic i...
904
905
906
907
  
  	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 ...
908
  		ns = kobj_ns_ops_tbl[type]->grab_current_ns();
bc451f205   Eric W. Biederman   kobj: Add basic i...
909
910
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
  	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 ...
939
  void kobj_ns_drop(enum kobj_ns_type type, void *ns)
bc451f205   Eric W. Biederman   kobj: Add basic i...
940
  {
a685e0898   Al Viro   Delay struct net ...
941
942
943
944
945
  	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...
946
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
947
948
  EXPORT_SYMBOL(kobject_get);
  EXPORT_SYMBOL(kobject_put);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
949
950
951
952
  EXPORT_SYMBOL(kobject_del);
  
  EXPORT_SYMBOL(kset_register);
  EXPORT_SYMBOL(kset_unregister);