Blame view

lib/kobject.c 26.1 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>
89c86a64c   Bjorn Helgaas   kobject: delay ko...
20
  #include <linux/random.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21

e34ff4906   Tejun Heo   sysfs: remove kty...
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  /**
   * kobject_namespace - return @kobj's namespace tag
   * @kobj: kobject in question
   *
   * Returns namespace tag of @kobj if its parent has namespace ops enabled
   * and thus @kobj should have a namespace tag associated with it.  Returns
   * %NULL otherwise.
   */
  const void *kobject_namespace(struct kobject *kobj)
  {
  	const struct kobj_ns_type_operations *ns_ops = kobj_ns_ops(kobj);
  
  	if (!ns_ops || ns_ops->type == KOBJ_NS_TYPE_NONE)
  		return NULL;
a1212d278   Linus Torvalds   Revert "sysfs: dr...
36
  	return kobj->ktype->namespace(kobj);
e34ff4906   Tejun Heo   sysfs: remove kty...
37
  }
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
38
39
40
  /*
   * populate_dir - populate directory with attributes.
   * @kobj: object we're working on.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
   *
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
42
43
44
45
   * 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
46
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
47
  static int populate_dir(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
  {
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
49
50
  	struct kobj_type *t = get_ktype(kobj);
  	struct attribute *attr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
  	int error = 0;
  	int i;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
53

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
  	if (t && t->default_attrs) {
  		for (i = 0; (attr = t->default_attrs[i]) != NULL; i++) {
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
56
57
  			error = sysfs_create_file(kobj, attr);
  			if (error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
60
61
62
  				break;
  		}
  	}
  	return error;
  }
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
63
  static int create_dir(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
  {
c84a3b277   Tejun Heo   sysfs: drop kobj_...
65
  	const struct kobj_ns_type_operations *ops;
e34ff4906   Tejun Heo   sysfs: remove kty...
66
67
68
  	int error;
  
  	error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj));
c84a3b277   Tejun Heo   sysfs: drop kobj_...
69
70
71
72
73
74
75
  	if (error)
  		return error;
  
  	error = populate_dir(kobj);
  	if (error) {
  		sysfs_remove_dir(kobj);
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
  	}
26ea12dec   Tejun Heo   kobject: grab an ...
77
78
79
80
81
82
  
  	/*
  	 * @kobj->sd may be deleted by an ancestor going away.  Hold an
  	 * extra reference so that it stays until @kobj is gone.
  	 */
  	sysfs_get(kobj->sd);
c84a3b277   Tejun Heo   sysfs: drop kobj_...
83
84
85
86
87
88
89
90
91
  	/*
  	 * If @kobj has ns_ops, its children need to be filtered based on
  	 * their namespace tags.  Enable namespace support on @kobj->sd.
  	 */
  	ops = kobj_child_ns_ops(kobj);
  	if (ops) {
  		BUG_ON(ops->type <= KOBJ_NS_TYPE_NONE);
  		BUG_ON(ops->type >= KOBJ_NS_TYPES);
  		BUG_ON(!kobj_ns_type_registered(ops->type));
fa4cd451c   Tejun Heo   sysfs, kobject: a...
92
  		sysfs_enable_ns(kobj->sd);
c84a3b277   Tejun Heo   sysfs: drop kobj_...
93
94
95
  	}
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
  static int get_kobj_path_length(struct kobject *kobj)
  {
  	int length = 1;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
100
  	struct kobject *parent = kobj;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101

e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
102
  	/* walk up the ancestors until we hit the one pointing to the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
104
105
106
  	 * root.
  	 * Add 1 to strlen for leading '/' of each level.
  	 */
  	do {
b365b3daf   Chuck Ebbert   [PATCH] kobject: ...
107
108
  		if (kobject_name(parent) == NULL)
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
110
111
112
113
114
115
116
  		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...
117
  	struct kobject *parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
120
121
122
123
  
  	--length;
  	for (parent = kobj; parent; parent = parent->parent) {
  		int cur = strlen(kobject_name(parent));
  		/* back up enough to print this name with '/' */
  		length -= cur;
af882cb0b   Guenter Roeck   kobject: Replace ...
124
  		memcpy(path + length, kobject_name(parent), cur);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
  		*(path + --length) = '/';
  	}
9f66fa2a4   Greg Kroah-Hartman   kobject: clean up...
127
128
  	pr_debug("kobject: '%s' (%p): %s: path = '%s'
  ", kobject_name(kobj),
810304db7   Harvey Harrison   lib: replace rema...
129
  		 kobj, __func__, path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
131
132
  }
  
  /**
72fd4a35a   Robert P. J. Day   [PATCH] Numerous ...
133
   * kobject_get_path - generate and return the path associated with a given kobj and kset pair.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
   *
   * @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 ...
137
138
   *
   * The result must be freed by the caller with kfree().
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
   */
fd4f2df24   Al Viro   [PATCH] gfp_t: lib/*
140
  char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
142
143
144
145
  {
  	char *path;
  	int len;
  
  	len = get_kobj_path_length(kobj);
b365b3daf   Chuck Ebbert   [PATCH] kobject: ...
146
147
  	if (len == 0)
  		return NULL;
4668edc33   Burman Yan   [PATCH] kernel co...
148
  	path = kzalloc(len, gfp_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
  	if (!path)
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
  	fill_kobj_path(kobj, path, len);
  
  	return path;
  }
80fc9f532   Dmitry Torokhov   Input: add missin...
155
  EXPORT_SYMBOL_GPL(kobject_get_path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156

0f4dafc05   Kay Sievers   Kobject: auto-cle...
157
158
  /* add the kobject to its kset's list */
  static void kobj_kset_join(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
  {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
160
  	if (!kobj->kset)
31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
161
  		return;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
162
163
164
165
166
  
  	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
167
  }
0f4dafc05   Kay Sievers   Kobject: auto-cle...
168
169
170
171
172
  /* 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
173

0f4dafc05   Kay Sievers   Kobject: auto-cle...
174
175
176
177
178
  	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
179

e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
180
  static void kobject_init_internal(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
  {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
182
183
184
185
  	if (!kobj)
  		return;
  	kref_init(&kobj->kref);
  	INIT_LIST_HEAD(&kobj->entry);
a4573c488   Greg Kroah-Hartman   kobject: properly...
186
187
188
189
  	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
190
  }
0f4dafc05   Kay Sievers   Kobject: auto-cle...
191

9e7bbccd0   Greg Kroah-Hartman   Kobject: remove k...
192
  static int kobject_add_internal(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
194
  {
  	int error = 0;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
195
  	struct kobject *parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196

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

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

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

0f4dafc05   Kay Sievers   Kobject: auto-cle...
209
  	/* join kset if set, use it as parent if we do not already have one */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
  	if (kobj->kset) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
211
  		if (!parent)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
  			parent = kobject_get(&kobj->kset->kobj);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
213
  		kobj_kset_join(kobj);
460f7e9a1   Dmitriy Monakhov   kobject: kobject_...
214
  		kobj->parent = parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216

0f4dafc05   Kay Sievers   Kobject: auto-cle...
217
218
  	pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'
  ",
810304db7   Harvey Harrison   lib: replace rema...
219
  		 kobject_name(kobj), kobj, __func__,
0f4dafc05   Kay Sievers   Kobject: auto-cle...
220
  		 parent ? kobject_name(parent) : "<NULL>",
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
221
  		 kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>");
0f4dafc05   Kay Sievers   Kobject: auto-cle...
222

90bc61359   Eric W. Biederman   sysfs: Remove fir...
223
  	error = create_dir(kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
  	if (error) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
225
226
227
  		kobj_kset_leave(kobj);
  		kobject_put(parent);
  		kobj->parent = NULL;
dcd0da002   Greg Kroah-Hartman   [PATCH] Kobject: ...
228
229
230
  
  		/* be noisy on error issues */
  		if (error == -EEXIST)
a5f427678   Dmitry Vyukov   kobject: don't us...
231
232
233
  			pr_err("%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: ...
234
  		else
a5f427678   Dmitry Vyukov   kobject: don't us...
235
236
237
238
  			pr_err("%s failed for %s (error: %d parent: %s)
  ",
  			       __func__, kobject_name(kobj), error,
  			       parent ? kobject_name(parent) : "'none'");
0f4dafc05   Kay Sievers   Kobject: auto-cle...
239
240
  	} else
  		kobj->state_in_sysfs = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
242
243
  
  	return error;
  }
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
244
  /**
663a47430   Greg Kroah-Hartman   kobject: fix up k...
245
246
247
248
249
   * 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 ...
250
  int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
663a47430   Greg Kroah-Hartman   kobject: fix up k...
251
252
  				  va_list vargs)
  {
f773f32d7   Rasmus Villemoes   lib/kobject.c: us...
253
  	const char *s;
663a47430   Greg Kroah-Hartman   kobject: fix up k...
254

8a577ffc7   Kay Sievers   driver: dont upda...
255
256
  	if (kobj->name && !fmt)
  		return 0;
f773f32d7   Rasmus Villemoes   lib/kobject.c: us...
257
  	s = kvasprintf_const(GFP_KERNEL, fmt, vargs);
2abf114fc   Rasmus Villemoes   lib/kobject.c: us...
258
  	if (!s)
a4ca66174   Kay Sievers   kobject: do not c...
259
  		return -ENOMEM;
663a47430   Greg Kroah-Hartman   kobject: fix up k...
260

f773f32d7   Rasmus Villemoes   lib/kobject.c: us...
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
  	/*
  	 * ewww... some of these buggers have '/' in the name ... If
  	 * that's the case, we need to make sure we have an actual
  	 * allocated copy to modify, since kvasprintf_const may have
  	 * returned something from .rodata.
  	 */
  	if (strchr(s, '/')) {
  		char *t;
  
  		t = kstrdup(s, GFP_KERNEL);
  		kfree_const(s);
  		if (!t)
  			return -ENOMEM;
  		strreplace(t, '/', '!');
  		s = t;
  	}
  	kfree_const(kobj->name);
2abf114fc   Rasmus Villemoes   lib/kobject.c: us...
278
  	kobj->name = s;
9f255651f   Kay Sievers   kobject: replace ...
279

663a47430   Greg Kroah-Hartman   kobject: fix up k...
280
281
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
  
  /**
8c4606b1a   Greg Kroah-Hartman   kobject: fix the ...
284
   * kobject_set_name - Set the name of a kobject
663a47430   Greg Kroah-Hartman   kobject: fix up k...
285
   * @kobj: struct kobject to set the name of
8c4606b1a   Greg Kroah-Hartman   kobject: fix the ...
286
   * @fmt: format string used to build the name
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
   *
8c4606b1a   Greg Kroah-Hartman   kobject: fix the ...
288
289
290
   * 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
291
   */
663a47430   Greg Kroah-Hartman   kobject: fix up k...
292
  int kobject_set_name(struct kobject *kobj, const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
  {
a4ca66174   Kay Sievers   kobject: do not c...
294
  	va_list vargs;
663a47430   Greg Kroah-Hartman   kobject: fix up k...
295
  	int retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296

a4ca66174   Kay Sievers   kobject: do not c...
297
298
299
  	va_start(vargs, fmt);
  	retval = kobject_set_name_vargs(kobj, fmt, vargs);
  	va_end(vargs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300

663a47430   Greg Kroah-Hartman   kobject: fix up k...
301
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
  EXPORT_SYMBOL(kobject_set_name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
  /**
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
305
   * kobject_init - initialize a kobject structure
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
306
307
308
309
310
311
312
313
314
315
   * @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...
316
  void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
317
318
319
320
321
322
323
324
325
326
327
328
  {
  	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...
329
  	if (kobj->state_initialized) {
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
330
  		/* do not error out as sometimes we can recover */
0f4dafc05   Kay Sievers   Kobject: auto-cle...
331
332
333
  		printk(KERN_ERR "kobject (%p): tried to init an initialized "
  		       "object, something is seriously wrong.
  ", kobj);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
334
335
  		dump_stack();
  	}
a4573c488   Greg Kroah-Hartman   kobject: properly...
336
  	kobject_init_internal(kobj);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
337
338
339
340
  	kobj->ktype = ktype;
  	return;
  
  error:
0f4dafc05   Kay Sievers   Kobject: auto-cle...
341
342
  	printk(KERN_ERR "kobject (%p): %s
  ", kobj, err_str);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
343
344
  	dump_stack();
  }
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
345
  EXPORT_SYMBOL(kobject_init);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
346

8db148606   Nicolas Iooss   include, lib: add...
347
348
349
  static __printf(3, 0) int kobject_add_varg(struct kobject *kobj,
  					   struct kobject *parent,
  					   const char *fmt, va_list vargs)
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
350
  {
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
351
  	int retval;
a4ca66174   Kay Sievers   kobject: do not c...
352
  	retval = kobject_set_name_vargs(kobj, fmt, vargs);
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
353
354
355
356
357
358
  	if (retval) {
  		printk(KERN_ERR "kobject: can not set name properly!
  ");
  		return retval;
  	}
  	kobj->parent = parent;
9e7bbccd0   Greg Kroah-Hartman   Kobject: remove k...
359
  	return kobject_add_internal(kobj);
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
360
361
362
  }
  
  /**
b2d6db587   Greg Kroah-Hartman   Kobject: rename k...
363
   * kobject_add - the main kobject add function
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
364
365
366
367
368
369
370
371
372
   * @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
9705710e4   Bart Van Assche   kobject: Fix sour...
373
   * kobject associated with the kset assigned to this kobject.  If no kset
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
374
375
376
377
378
   * 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...
379
380
381
   * 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...
382
   * Note, no "add" uevent will be created with this call, the caller should set
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
383
384
385
386
   * 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...
387
388
  int kobject_add(struct kobject *kobj, struct kobject *parent,
  		const char *fmt, ...)
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
389
390
391
392
393
394
  {
  	va_list args;
  	int retval;
  
  	if (!kobj)
  		return -EINVAL;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
395
396
397
398
399
400
401
402
  	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...
403
404
405
406
407
408
  	va_start(args, fmt);
  	retval = kobject_add_varg(kobj, parent, fmt, args);
  	va_end(args);
  
  	return retval;
  }
b2d6db587   Greg Kroah-Hartman   Kobject: rename k...
409
  EXPORT_SYMBOL(kobject_add);
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
410

e86000d04   Greg Kroah-Hartman   kobject: add kobj...
411
  /**
c11c4154e   Greg Kroah-Hartman   kobject: add kobj...
412
413
414
415
416
417
   * 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...
418
   * This function combines the call to kobject_init() and
b2d6db587   Greg Kroah-Hartman   Kobject: rename k...
419
420
   * 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...
421
422
423
424
425
426
   */
  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...
427
  	kobject_init(kobj, ktype);
c11c4154e   Greg Kroah-Hartman   kobject: add kobj...
428
429
430
431
432
433
434
435
436
437
  
  	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...
438
439
440
   * 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...
441
442
443
444
445
   *
   * 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
446
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
447
  int kobject_rename(struct kobject *kobj, const char *new_name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
449
  {
  	int error = 0;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
450
  	const char *devpath = NULL;
0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
451
  	const char *dup_name = NULL, *name;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
452
453
  	char *devpath_string = NULL;
  	char *envp[2];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
455
456
457
  
  	kobj = kobject_get(kobj);
  	if (!kobj)
  		return -EINVAL;
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
458
459
  	if (!kobj->parent)
  		return -EINVAL;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
  
  	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...
474

f773f32d7   Rasmus Villemoes   lib/kobject.c: us...
475
  	name = dup_name = kstrdup_const(new_name, GFP_KERNEL);
0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
476
477
478
479
  	if (!name) {
  		error = -ENOMEM;
  		goto out;
  	}
e34ff4906   Tejun Heo   sysfs: remove kty...
480
  	error = sysfs_rename_dir_ns(kobj, new_name, kobject_namespace(kobj));
0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
481
482
483
484
485
486
  	if (error)
  		goto out;
  
  	/* Install the new kobject name */
  	dup_name = kobj->name;
  	kobj->name = name;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
487
488
489
490
  
  	/* 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 ...
491
  	kobject_uevent_env(kobj, KOBJ_MOVE, envp);
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
492
493
  
  out:
f773f32d7   Rasmus Villemoes   lib/kobject.c: us...
494
  	kfree_const(dup_name);
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
495
496
  	kfree(devpath_string);
  	kfree(devpath);
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
497
498
499
500
  	kobject_put(kobj);
  
  	return error;
  }
8344b568f   Alex Chiang   PCI: ACPI PCI slo...
501
  EXPORT_SYMBOL_GPL(kobject_rename);
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
502
503
  
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
504
505
506
   * 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...
507
   */
8a82472f8   Cornelia Huck   driver core: Intr...
508
509
510
511
512
513
514
515
516
517
518
519
520
  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...
521
522
  		if (kobj->kset)
  			new_parent = kobject_get(&kobj->kset->kobj);
8a82472f8   Cornelia Huck   driver core: Intr...
523
  	}
e34ff4906   Tejun Heo   sysfs: remove kty...
524

8a82472f8   Cornelia Huck   driver core: Intr...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
  	/* 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;
e34ff4906   Tejun Heo   sysfs: remove kty...
539
  	error = sysfs_move_dir_ns(kobj, new_parent, kobject_namespace(kobj));
8a82472f8   Cornelia Huck   driver core: Intr...
540
541
542
543
  	if (error)
  		goto out;
  	old_parent = kobj->parent;
  	kobj->parent = new_parent;
9e993efb0   Dmitriy Monakhov   kobject: new_devi...
544
  	new_parent = NULL;
8a82472f8   Cornelia Huck   driver core: Intr...
545
546
547
  	kobject_put(old_parent);
  	kobject_uevent_env(kobj, KOBJ_MOVE, envp);
  out:
9e993efb0   Dmitriy Monakhov   kobject: new_devi...
548
  	kobject_put(new_parent);
8a82472f8   Cornelia Huck   driver core: Intr...
549
550
551
552
553
  	kobject_put(kobj);
  	kfree(devpath_string);
  	kfree(devpath);
  	return error;
  }
24199d206   Anand Jain   lib: export symbo...
554
  EXPORT_SYMBOL_GPL(kobject_move);
8a82472f8   Cornelia Huck   driver core: Intr...
555
556
  
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
557
558
   * kobject_del - unlink kobject from hierarchy.
   * @kobj: object.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
560
  void kobject_del(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
561
  {
324a56e16   Tejun Heo   kernfs: s/sysfs_d...
562
  	struct kernfs_node *sd;
26ea12dec   Tejun Heo   kobject: grab an ...
563

31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
564
565
  	if (!kobj)
  		return;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
566

26ea12dec   Tejun Heo   kobject: grab an ...
567
  	sd = kobj->sd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
  	sysfs_remove_dir(kobj);
26ea12dec   Tejun Heo   kobject: grab an ...
569
  	sysfs_put(sd);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
570
571
572
573
  	kobj->state_in_sysfs = 0;
  	kobj_kset_leave(kobj);
  	kobject_put(kobj->parent);
  	kobj->parent = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
574
  }
fa40ae344   Gabriel Somlo   kobject: move EXP...
575
  EXPORT_SYMBOL(kobject_del);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
576
577
  
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
578
579
   * kobject_get - increment refcount for object.
   * @kobj: object.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
580
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
581
  struct kobject *kobject_get(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
582
  {
d82d54af7   Ethan Zhao   kobject: WARN as ...
583
584
585
586
587
588
  	if (kobj) {
  		if (!kobj->state_initialized)
  			WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "
  			       "initialized, yet kobject_get() is being "
  			       "called.
  ", kobject_name(kobj), kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589
  		kref_get(&kobj->kref);
d82d54af7   Ethan Zhao   kobject: WARN as ...
590
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591
592
  	return kobj;
  }
fa40ae344   Gabriel Somlo   kobject: move EXP...
593
  EXPORT_SYMBOL(kobject_get);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594

c70c176ff   Jan Kara   kobject: Export k...
595
  struct kobject * __must_check kobject_get_unless_zero(struct kobject *kobj)
a49b7e82c   Linus Torvalds   kobject: fix kset...
596
  {
c70c176ff   Jan Kara   kobject: Export k...
597
598
  	if (!kobj)
  		return NULL;
a49b7e82c   Linus Torvalds   kobject: fix kset...
599
600
601
602
  	if (!kref_get_unless_zero(&kobj->kref))
  		kobj = NULL;
  	return kobj;
  }
c70c176ff   Jan Kara   kobject: Export k...
603
  EXPORT_SYMBOL(kobject_get_unless_zero);
a49b7e82c   Linus Torvalds   kobject: fix kset...
604

18041f477   Greg Kroah-Hartman   kobject: make kob...
605
606
607
  /*
   * kobject_cleanup - free kobject resources.
   * @kobj: object to cleanup
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
608
   */
18041f477   Greg Kroah-Hartman   kobject: make kob...
609
  static void kobject_cleanup(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
610
  {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
611
  	struct kobj_type *t = get_ktype(kobj);
af5ca3f4e   Kay Sievers   Driver core: chan...
612
  	const char *name = kobj->name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613

c817a67ec   Russell King   kobject: delayed ...
614
615
616
  	pr_debug("kobject: '%s' (%p): %s, parent %p
  ",
  		 kobject_name(kobj), kobj, __func__, kobj->parent);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
  
  	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...
639
  	if (t && t->release) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
640
641
642
  		pr_debug("kobject: '%s' (%p): calling ktype release
  ",
  			 kobject_name(kobj), kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643
  		t->release(kobj);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
644
645
646
  	}
  
  	/* free name if we allocated it */
af5ca3f4e   Kay Sievers   Driver core: chan...
647
  	if (name) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
648
649
  		pr_debug("kobject: '%s': free name
  ", name);
f773f32d7   Rasmus Villemoes   lib/kobject.c: us...
650
  		kfree_const(name);
ce2c9cb02   Greg Kroah-Hartman   kobject: remove t...
651
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
  }
c817a67ec   Russell King   kobject: delayed ...
653
654
655
656
657
658
659
  #ifdef CONFIG_DEBUG_KOBJECT_RELEASE
  static void kobject_delayed_cleanup(struct work_struct *work)
  {
  	kobject_cleanup(container_of(to_delayed_work(work),
  				     struct kobject, release));
  }
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
660
661
  static void kobject_release(struct kref *kref)
  {
c817a67ec   Russell King   kobject: delayed ...
662
663
  	struct kobject *kobj = container_of(kref, struct kobject, kref);
  #ifdef CONFIG_DEBUG_KOBJECT_RELEASE
89c86a64c   Bjorn Helgaas   kobject: delay ko...
664
665
666
667
  	unsigned long delay = HZ + HZ * (get_random_int() & 0x3);
  	pr_info("kobject: '%s' (%p): %s, parent %p (delayed %ld)
  ",
  		 kobject_name(kobj), kobj, __func__, kobj->parent, delay);
c817a67ec   Russell King   kobject: delayed ...
668
  	INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup);
89c86a64c   Bjorn Helgaas   kobject: delay ko...
669
670
  
  	schedule_delayed_work(&kobj->release, delay);
c817a67ec   Russell King   kobject: delayed ...
671
672
673
  #else
  	kobject_cleanup(kobj);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
675
676
  }
  
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
677
678
   * kobject_put - decrement refcount for object.
   * @kobj: object.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
679
   *
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
680
   * Decrement the refcount, and if 0, call kobject_cleanup().
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
682
  void kobject_put(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
683
  {
c1ebdae51   Greg Kroah-Hartman   kobject: catch ko...
684
  	if (kobj) {
d955c78ac   Arjan van de Ven   Example use of WA...
685
686
  		if (!kobj->state_initialized)
  			WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "
c1ebdae51   Greg Kroah-Hartman   kobject: catch ko...
687
688
689
  			       "initialized, yet kobject_put() is being "
  			       "called.
  ", kobject_name(kobj), kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
690
  		kref_put(&kobj->kref, kobject_release);
c1ebdae51   Greg Kroah-Hartman   kobject: catch ko...
691
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
692
  }
fa40ae344   Gabriel Somlo   kobject: move EXP...
693
  EXPORT_SYMBOL(kobject_put);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
694

3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
695
  static void dynamic_kobj_release(struct kobject *kobj)
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
696
  {
810304db7   Harvey Harrison   lib: replace rema...
697
698
  	pr_debug("kobject: (%p): %s
  ", kobj, __func__);
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
699
700
  	kfree(kobj);
  }
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
701
  static struct kobj_type dynamic_kobj_ktype = {
386f275f5   Kay Sievers   Driver Core: swit...
702
703
  	.release	= dynamic_kobj_release,
  	.sysfs_ops	= &kobj_sysfs_ops,
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
704
  };
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
705
  /**
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
706
707
708
709
710
711
   * 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 ...
712
   * The kobject structure returned from here must be cleaned up with a
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
713
   * call to kobject_put() and not kfree(), as kobject_init() has
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
714
   * already been called on this structure.
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
715
   */
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
716
  struct kobject *kobject_create(void)
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
717
718
719
720
721
722
  {
  	struct kobject *kobj;
  
  	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
  	if (!kobj)
  		return NULL;
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
723
  	kobject_init(kobj, &dynamic_kobj_ktype);
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
724
725
726
727
728
729
  	return kobj;
  }
  
  /**
   * kobject_create_and_add - create a struct kobject dynamically and register it with sysfs
   *
9ff1f838e   Zhi Yong Wu   kobject: fix the ...
730
   * @name: the name for the kobject
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
731
732
   * @parent: the parent kobject of this kobject, if any.
   *
f70701a34   Dave Young   kobject: kerneldo...
733
   * This function creates a kobject structure dynamically and registers it
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
734
   * with sysfs.  When you are finished with this structure, call
78a2d906b   Greg Kroah-Hartman   Kobject: convert ...
735
   * kobject_put() and the structure will be dynamically freed when
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
736
737
738
739
740
741
742
743
744
745
746
747
   * 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...
748
  	retval = kobject_add(kobj, parent, "%s", name);
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
749
750
751
  	if (retval) {
  		printk(KERN_WARNING "%s: kobject_add error: %d
  ",
810304db7   Harvey Harrison   lib: replace rema...
752
  		       __func__, retval);
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
753
754
755
756
757
758
  		kobject_put(kobj);
  		kobj = NULL;
  	}
  	return kobj;
  }
  EXPORT_SYMBOL_GPL(kobject_create_and_add);
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
759
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
760
761
   * kset_init - initialize a kset for use
   * @k: kset
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
762
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
763
  void kset_init(struct kset *k)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
764
  {
e1543ddf7   Greg Kroah-Hartman   Kobject: remove k...
765
  	kobject_init_internal(&k->kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
766
767
768
  	INIT_LIST_HEAD(&k->list);
  	spin_lock_init(&k->list_lock);
  }
23b5212cc   Kay Sievers   Driver Core: add ...
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
  /* 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...
793
  const struct sysfs_ops kobj_sysfs_ops = {
23b5212cc   Kay Sievers   Driver Core: add ...
794
795
796
  	.show	= kobj_attr_show,
  	.store	= kobj_attr_store,
  };
29dfe2dc0   Jeff Mahoney   kobject: export k...
797
  EXPORT_SYMBOL_GPL(kobj_sysfs_ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798
799
  
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
800
801
   * kset_register - initialize and add a kset.
   * @k: kset.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
802
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
803
  int kset_register(struct kset *k)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
804
  {
80f03e349   Kay Sievers   Driver core: add ...
805
  	int err;
31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
806
807
  	if (!k)
  		return -EINVAL;
80f03e349   Kay Sievers   Driver core: add ...
808

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
809
  	kset_init(k);
12e339ac6   Greg Kroah-Hartman   Kset: remove kset...
810
  	err = kobject_add_internal(&k->kobj);
80f03e349   Kay Sievers   Driver core: add ...
811
812
813
814
  	if (err)
  		return err;
  	kobject_uevent(&k->kobj, KOBJ_ADD);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
  }
fa40ae344   Gabriel Somlo   kobject: move EXP...
816
  EXPORT_SYMBOL(kset_register);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
817

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
818
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
819
820
   * kset_unregister - remove a kset.
   * @k: kset.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
821
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
822
  void kset_unregister(struct kset *k)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
823
  {
31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
824
825
  	if (!k)
  		return;
35a5fe695   Bjorn Helgaas   kobject: remove k...
826
  	kobject_del(&k->kobj);
78a2d906b   Greg Kroah-Hartman   Kobject: convert ...
827
  	kobject_put(&k->kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
  }
fa40ae344   Gabriel Somlo   kobject: move EXP...
829
  EXPORT_SYMBOL(kset_unregister);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
830

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
831
  /**
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
832
833
834
   * 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
835
   *
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
836
837
838
   * 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
839
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
840
  struct kobject *kset_find_obj(struct kset *kset, const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841
  {
c6a2a3dc2   Robert P. J. Day   Kobject: Replace ...
842
  	struct kobject *k;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
843
  	struct kobject *ret = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844
845
  
  	spin_lock(&kset->list_lock);
c25d1dfbd   Robin Holt   kobject: Introduc...
846

c6a2a3dc2   Robert P. J. Day   Kobject: Replace ...
847
  	list_for_each_entry(k, &kset->list, entry) {
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
848
  		if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
a49b7e82c   Linus Torvalds   kobject: fix kset...
849
  			ret = kobject_get_unless_zero(k);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
850
851
852
  			break;
  		}
  	}
c25d1dfbd   Robin Holt   kobject: Introduc...
853

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
854
855
856
  	spin_unlock(&kset->list_lock);
  	return ret;
  }
2fe829aca   Gabriel Somlo   kobject: export k...
857
  EXPORT_SYMBOL_GPL(kset_find_obj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858

b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
859
860
861
  static void kset_release(struct kobject *kobj)
  {
  	struct kset *kset = container_of(kobj, struct kset, kobj);
9f66fa2a4   Greg Kroah-Hartman   kobject: clean up...
862
863
  	pr_debug("kobject: '%s' (%p): %s
  ",
810304db7   Harvey Harrison   lib: replace rema...
864
  		 kobject_name(kobj), kobj, __func__);
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
865
866
  	kfree(kset);
  }
386f275f5   Kay Sievers   Driver Core: swit...
867
868
  static struct kobj_type kset_ktype = {
  	.sysfs_ops	= &kobj_sysfs_ops,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
  	.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...
888
  				const struct kset_uevent_ops *uevent_ops,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
889
890
891
  				struct kobject *parent_kobj)
  {
  	struct kset *kset;
d9cd8f378   Dave Young   kobject: make kse...
892
  	int retval;
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
893
894
895
896
  
  	kset = kzalloc(sizeof(*kset), GFP_KERNEL);
  	if (!kset)
  		return NULL;
b7165ebbf   Kees Cook   kobject: sanitize...
897
  	retval = kobject_set_name(&kset->kobj, "%s", name);
d9cd8f378   Dave Young   kobject: make kse...
898
899
900
901
  	if (retval) {
  		kfree(kset);
  		return NULL;
  	}
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
902
903
904
905
  	kset->uevent_ops = uevent_ops;
  	kset->kobj.parent = parent_kobj;
  
  	/*
386f275f5   Kay Sievers   Driver Core: swit...
906
  	 * The kobject of this kset will have a type of kset_ktype and belong to
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
907
908
909
  	 * no kset itself.  That way we can properly free it when it is
  	 * finished being used.
  	 */
386f275f5   Kay Sievers   Driver Core: swit...
910
  	kset->kobj.ktype = &kset_ktype;
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
  	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...
931
  				 const struct kset_uevent_ops *uevent_ops,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
  				 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...
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
  
  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;
41fb96a4b   Pankaj Dubey   kobject: fix NULL...
994
  	if (parent && parent->ktype && parent->ktype->child_ns_type)
bc451f205   Eric W. Biederman   kobj: Add basic i...
995
996
997
998
999
1000
1001
1002
1003
  		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);
  }
7dc5dbc87   Eric W. Biederman   sysfs: Restrict m...
1004
1005
  bool kobj_ns_current_may_mount(enum kobj_ns_type type)
  {
730d7d339   Eric W. Biederman   sysfs: Allow moun...
1006
  	bool may_mount = true;
7dc5dbc87   Eric W. Biederman   sysfs: Restrict m...
1007
1008
1009
1010
1011
1012
1013
1014
1015
  
  	spin_lock(&kobj_ns_type_lock);
  	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
  	    kobj_ns_ops_tbl[type])
  		may_mount = kobj_ns_ops_tbl[type]->current_may_mount();
  	spin_unlock(&kobj_ns_type_lock);
  
  	return may_mount;
  }
bc451f205   Eric W. Biederman   kobj: Add basic i...
1016

a685e0898   Al Viro   Delay struct net ...
1017
  void *kobj_ns_grab_current(enum kobj_ns_type type)
bc451f205   Eric W. Biederman   kobj: Add basic i...
1018
  {
a685e0898   Al Viro   Delay struct net ...
1019
  	void *ns = NULL;
bc451f205   Eric W. Biederman   kobj: Add basic i...
1020
1021
1022
1023
  
  	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 ...
1024
  		ns = kobj_ns_ops_tbl[type]->grab_current_ns();
bc451f205   Eric W. Biederman   kobj: Add basic i...
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
  	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 ...
1055
  void kobj_ns_drop(enum kobj_ns_type type, void *ns)
bc451f205   Eric W. Biederman   kobj: Add basic i...
1056
  {
a685e0898   Al Viro   Delay struct net ...
1057
1058
1059
1060
1061
  	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...
1062
  }