Blame view

lib/kobject.c 28.2 KB
d9d16e16a   Greg Kroah-Hartman   kobject: add SPDX...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
  /*
   * 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...
6
7
   * Copyright (c) 2006-2007 Greg Kroah-Hartman <greg@kroah.com>
   * Copyright (c) 2006-2007 Novell Inc.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
   *
0c1bc6b84   Mauro Carvalho Chehab   docs: filesystems...
9
   * Please see the file Documentation/core-api/kobject.rst for critical information
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
12
13
14
   * about using the kobject interface.
   */
  
  #include <linux/kobject.h>
  #include <linux/string.h>
8bc3bcc93   Paul Gortmaker   lib: reduce the u...
15
  #include <linux/export.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
  #include <linux/stat.h>
4e57b6817   Tim Schmielau   [PATCH] fix missi...
17
  #include <linux/slab.h>
89c86a64c   Bjorn Helgaas   kobject: delay ko...
18
  #include <linux/random.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19

e34ff4906   Tejun Heo   sysfs: remove kty...
20
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
21
   * kobject_namespace() - Return @kobj's namespace tag.
e34ff4906   Tejun Heo   sysfs: remove kty...
22
23
24
25
26
27
28
29
30
31
32
33
   * @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...
34
  	return kobj->ktype->namespace(kobj);
e34ff4906   Tejun Heo   sysfs: remove kty...
35
  }
5f81880d5   Dmitry Torokhov   sysfs, kobject: a...
36
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
37
   * kobject_get_ownership() - Get sysfs ownership data for @kobj.
5f81880d5   Dmitry Torokhov   sysfs, kobject: a...
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
   * @kobj: kobject in question
   * @uid: kernel user ID for sysfs objects
   * @gid: kernel group ID for sysfs objects
   *
   * Returns initial uid/gid pair that should be used when creating sysfs
   * representation of given kobject. Normally used to adjust ownership of
   * objects in a container.
   */
  void kobject_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid)
  {
  	*uid = GLOBAL_ROOT_UID;
  	*gid = GLOBAL_ROOT_GID;
  
  	if (kobj->ktype->get_ownership)
  		kobj->ktype->get_ownership(kobj, uid, gid);
  }
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
54
55
56
  /*
   * populate_dir - populate directory with attributes.
   * @kobj: object we're working on.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
   *
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
58
59
60
61
   * 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
62
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
63
  static int populate_dir(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
  {
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
65
66
  	struct kobj_type *t = get_ktype(kobj);
  	struct attribute *attr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
  	int error = 0;
  	int i;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
69

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
  	if (t && t->default_attrs) {
  		for (i = 0; (attr = t->default_attrs[i]) != NULL; i++) {
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
72
73
  			error = sysfs_create_file(kobj, attr);
  			if (error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
76
77
78
  				break;
  		}
  	}
  	return error;
  }
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
79
  static int create_dir(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
  {
aa30f47cf   Kimberly Brown   kobject: Add supp...
81
  	const struct kobj_type *ktype = get_ktype(kobj);
c84a3b277   Tejun Heo   sysfs: drop kobj_...
82
  	const struct kobj_ns_type_operations *ops;
e34ff4906   Tejun Heo   sysfs: remove kty...
83
84
85
  	int error;
  
  	error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj));
c84a3b277   Tejun Heo   sysfs: drop kobj_...
86
87
88
89
90
91
92
  	if (error)
  		return error;
  
  	error = populate_dir(kobj);
  	if (error) {
  		sysfs_remove_dir(kobj);
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
  	}
26ea12dec   Tejun Heo   kobject: grab an ...
94

aa30f47cf   Kimberly Brown   kobject: Add supp...
95
96
97
98
99
100
101
  	if (ktype) {
  		error = sysfs_create_groups(kobj, ktype->default_groups);
  		if (error) {
  			sysfs_remove_dir(kobj);
  			return error;
  		}
  	}
26ea12dec   Tejun Heo   kobject: grab an ...
102
103
104
105
106
  	/*
  	 * @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_...
107
108
109
110
111
112
113
114
115
  	/*
  	 * 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...
116
  		sysfs_enable_ns(kobj->sd);
c84a3b277   Tejun Heo   sysfs: drop kobj_...
117
118
119
  	}
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
122
123
  static int get_kobj_path_length(struct kobject *kobj)
  {
  	int length = 1;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
124
  	struct kobject *parent = kobj;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125

e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
126
  	/* walk up the ancestors until we hit the one pointing to the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
130
  	 * root.
  	 * Add 1 to strlen for leading '/' of each level.
  	 */
  	do {
b365b3daf   Chuck Ebbert   [PATCH] kobject: ...
131
132
  		if (kobject_name(parent) == NULL)
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
134
135
136
137
138
139
140
  		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...
141
  	struct kobject *parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
144
145
146
147
  
  	--length;
  	for (parent = kobj; parent; parent = parent->parent) {
  		int cur = strlen(kobject_name(parent));
  		/* back up enough to print this name with '/' */
  		length -= cur;
77d2a24b6   Guenter Roeck   kobject: Replace ...
148
  		memcpy(path + length, kobject_name(parent), cur);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
  		*(path + --length) = '/';
  	}
9f66fa2a4   Greg Kroah-Hartman   kobject: clean up...
151
152
  	pr_debug("kobject: '%s' (%p): %s: path = '%s'
  ", kobject_name(kobj),
810304db7   Harvey Harrison   lib: replace rema...
153
  		 kobj, __func__, path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
156
  }
  
  /**
8fd7c302b   Tobin C. Harding   kobject: Remove d...
157
   * kobject_get_path() - Allocate memory and fill in the path for @kobj.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
159
   * @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 ...
160
   *
8fd7c302b   Tobin C. Harding   kobject: Remove d...
161
   * Return: The newly allocated memory, caller must free with kfree().
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
   */
fd4f2df24   Al Viro   [PATCH] gfp_t: lib/*
163
  char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
166
167
168
  {
  	char *path;
  	int len;
  
  	len = get_kobj_path_length(kobj);
b365b3daf   Chuck Ebbert   [PATCH] kobject: ...
169
170
  	if (len == 0)
  		return NULL;
4668edc33   Burman Yan   [PATCH] kernel co...
171
  	path = kzalloc(len, gfp_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
  	if (!path)
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
175
176
177
  	fill_kobj_path(kobj, path, len);
  
  	return path;
  }
80fc9f532   Dmitry Torokhov   Input: add missin...
178
  EXPORT_SYMBOL_GPL(kobject_get_path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179

0f4dafc05   Kay Sievers   Kobject: auto-cle...
180
181
  /* add the kobject to its kset's list */
  static void kobj_kset_join(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
  {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
183
  	if (!kobj->kset)
31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
184
  		return;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
185
186
187
188
189
  
  	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
190
  }
0f4dafc05   Kay Sievers   Kobject: auto-cle...
191
192
193
194
195
  /* 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
196

0f4dafc05   Kay Sievers   Kobject: auto-cle...
197
198
199
200
201
  	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
202

e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
203
  static void kobject_init_internal(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
  {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
205
206
207
208
  	if (!kobj)
  		return;
  	kref_init(&kobj->kref);
  	INIT_LIST_HEAD(&kobj->entry);
a4573c488   Greg Kroah-Hartman   kobject: properly...
209
210
211
212
  	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
213
  }
0f4dafc05   Kay Sievers   Kobject: auto-cle...
214

9e7bbccd0   Greg Kroah-Hartman   Kobject: remove k...
215
  static int kobject_add_internal(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
217
  {
  	int error = 0;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
218
  	struct kobject *parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219

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

af5ca3f4e   Kay Sievers   Driver core: chan...
223
  	if (!kobj->name || !kobj->name[0]) {
82d1f1178   Andy Shevchenko   lib/kobject: Join...
224
225
226
227
  		WARN(1,
  		     "kobject: (%p): attempted to be registered with empty name!
  ",
  		     kobj);
c171fef5c   Greg Kroah-Hartman   [PATCH] kobject_a...
228
229
  		return -EINVAL;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230

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

0f4dafc05   Kay Sievers   Kobject: auto-cle...
233
  	/* join kset if set, use it as parent if we do not already have one */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  	if (kobj->kset) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
235
  		if (!parent)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
  			parent = kobject_get(&kobj->kset->kobj);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
237
  		kobj_kset_join(kobj);
460f7e9a1   Dmitriy Monakhov   kobject: kobject_...
238
  		kobj->parent = parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240

0f4dafc05   Kay Sievers   Kobject: auto-cle...
241
242
  	pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'
  ",
810304db7   Harvey Harrison   lib: replace rema...
243
  		 kobject_name(kobj), kobj, __func__,
0f4dafc05   Kay Sievers   Kobject: auto-cle...
244
  		 parent ? kobject_name(parent) : "<NULL>",
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
245
  		 kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>");
0f4dafc05   Kay Sievers   Kobject: auto-cle...
246

90bc61359   Eric W. Biederman   sysfs: Remove fir...
247
  	error = create_dir(kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248
  	if (error) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
249
250
251
  		kobj_kset_leave(kobj);
  		kobject_put(parent);
  		kobj->parent = NULL;
dcd0da002   Greg Kroah-Hartman   [PATCH] Kobject: ...
252
253
254
  
  		/* be noisy on error issues */
  		if (error == -EEXIST)
3e14c6abb   Dmitry Vyukov   kobject: don't us...
255
256
257
  			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: ...
258
  		else
3e14c6abb   Dmitry Vyukov   kobject: don't us...
259
260
261
262
  			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...
263
264
  	} else
  		kobj->state_in_sysfs = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
  
  	return error;
  }
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
268
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
269
   * kobject_set_name_vargs() - Set the name of a kobject.
663a47430   Greg Kroah-Hartman   kobject: fix up k...
270
271
272
273
   * @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 ...
274
  int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
663a47430   Greg Kroah-Hartman   kobject: fix up k...
275
276
  				  va_list vargs)
  {
f773f32d7   Rasmus Villemoes   lib/kobject.c: us...
277
  	const char *s;
663a47430   Greg Kroah-Hartman   kobject: fix up k...
278

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

f773f32d7   Rasmus Villemoes   lib/kobject.c: us...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
  	/*
  	 * 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...
302
  	kobj->name = s;
9f255651f   Kay Sievers   kobject: replace ...
303

663a47430   Greg Kroah-Hartman   kobject: fix up k...
304
305
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
307
  
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
308
   * kobject_set_name() - Set the name of a kobject.
663a47430   Greg Kroah-Hartman   kobject: fix up k...
309
   * @kobj: struct kobject to set the name of
8c4606b1a   Greg Kroah-Hartman   kobject: fix the ...
310
   * @fmt: format string used to build the name
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311
   *
8c4606b1a   Greg Kroah-Hartman   kobject: fix the ...
312
313
314
   * 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
315
   */
663a47430   Greg Kroah-Hartman   kobject: fix up k...
316
  int kobject_set_name(struct kobject *kobj, const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
  {
a4ca66174   Kay Sievers   kobject: do not c...
318
  	va_list vargs;
663a47430   Greg Kroah-Hartman   kobject: fix up k...
319
  	int retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320

a4ca66174   Kay Sievers   kobject: do not c...
321
322
323
  	va_start(vargs, fmt);
  	retval = kobject_set_name_vargs(kobj, fmt, vargs);
  	va_end(vargs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324

663a47430   Greg Kroah-Hartman   kobject: fix up k...
325
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
  EXPORT_SYMBOL(kobject_set_name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
329
   * kobject_init() - Initialize a kobject structure.
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
330
331
332
333
334
335
336
337
338
339
   * @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...
340
  void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
341
342
343
344
345
346
347
348
349
350
351
352
  {
  	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...
353
  	if (kobj->state_initialized) {
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
354
  		/* do not error out as sometimes we can recover */
82d1f1178   Andy Shevchenko   lib/kobject: Join...
355
356
357
  		pr_err("kobject (%p): tried to init an initialized object, something is seriously wrong.
  ",
  		       kobj);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
358
359
  		dump_stack();
  	}
a4573c488   Greg Kroah-Hartman   kobject: properly...
360
  	kobject_init_internal(kobj);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
361
362
363
364
  	kobj->ktype = ktype;
  	return;
  
  error:
82d1f1178   Andy Shevchenko   lib/kobject: Join...
365
366
  	pr_err("kobject (%p): %s
  ", kobj, err_str);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
367
368
  	dump_stack();
  }
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
369
  EXPORT_SYMBOL(kobject_init);
e86000d04   Greg Kroah-Hartman   kobject: add kobj...
370

8db148606   Nicolas Iooss   include, lib: add...
371
372
373
  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...
374
  {
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
375
  	int retval;
a4ca66174   Kay Sievers   kobject: do not c...
376
  	retval = kobject_set_name_vargs(kobj, fmt, vargs);
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
377
  	if (retval) {
82d1f1178   Andy Shevchenko   lib/kobject: Join...
378
379
  		pr_err("kobject: can not set name properly!
  ");
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
380
381
382
  		return retval;
  	}
  	kobj->parent = parent;
9e7bbccd0   Greg Kroah-Hartman   Kobject: remove k...
383
  	return kobject_add_internal(kobj);
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
384
385
386
  }
  
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
387
   * kobject_add() - The main kobject add function.
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
388
389
390
391
392
393
394
395
396
   * @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...
397
   * kobject associated with the kset assigned to this kobject.  If no kset
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
398
399
400
   * is assigned to the kobject, then the kobject will be located in the
   * root of the sysfs tree.
   *
0f4dafc05   Kay Sievers   Kobject: auto-cle...
401
   * Note, no "add" uevent will be created with this call, the caller should set
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
402
403
404
   * 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.
92067f843   Tobin C. Harding   kobject: Improve ...
405
406
407
408
409
410
411
   *
   * Return: If this function returns an error, kobject_put() must be
   *         called to properly clean up the memory associated with the
   *         object.  Under no instance should the kobject that is passed
   *         to this function be directly freed with a call to kfree(),
   *         that can leak memory.
   *
70e16a620   Greg Kroah-Hartman   kobject: clean up...
412
413
414
415
416
417
   *         If this function returns success, kobject_put() must also be called
   *         in order to properly clean up the memory associated with the object.
   *
   *         In short, once this function is called, kobject_put() MUST be called
   *         when the use of the object is finished in order to properly free
   *         everything.
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
418
   */
b2d6db587   Greg Kroah-Hartman   Kobject: rename k...
419
420
  int kobject_add(struct kobject *kobj, struct kobject *parent,
  		const char *fmt, ...)
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
421
422
423
424
425
426
  {
  	va_list args;
  	int retval;
  
  	if (!kobj)
  		return -EINVAL;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
427
  	if (!kobj->state_initialized) {
82d1f1178   Andy Shevchenko   lib/kobject: Join...
428
429
  		pr_err("kobject '%s' (%p): tried to add an uninitialized object, something is seriously wrong.
  ",
0f4dafc05   Kay Sievers   Kobject: auto-cle...
430
431
432
433
  		       kobject_name(kobj), kobj);
  		dump_stack();
  		return -EINVAL;
  	}
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
434
435
436
437
438
439
  	va_start(args, fmt);
  	retval = kobject_add_varg(kobj, parent, fmt, args);
  	va_end(args);
  
  	return retval;
  }
b2d6db587   Greg Kroah-Hartman   Kobject: rename k...
440
  EXPORT_SYMBOL(kobject_add);
244f6cee9   Greg Kroah-Hartman   kobject: add kobj...
441

e86000d04   Greg Kroah-Hartman   kobject: add kobj...
442
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
443
444
   * kobject_init_and_add() - Initialize a kobject structure and add it to
   *                          the kobject hierarchy.
c11c4154e   Greg Kroah-Hartman   kobject: add kobj...
445
446
447
448
449
   * @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.
   *
1fd7c3b43   Tobin C. Harding   kobject: Improve ...
450
451
452
453
454
455
   * This function combines the call to kobject_init() and kobject_add().
   *
   * If this function returns an error, kobject_put() must be called to
   * properly clean up the memory associated with the object.  This is 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...
456
457
458
459
460
461
   */
  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...
462
  	kobject_init(kobj, ktype);
c11c4154e   Greg Kroah-Hartman   kobject: add kobj...
463
464
465
466
467
468
469
470
471
472
  
  	va_start(args, fmt);
  	retval = kobject_add_varg(kobj, parent, fmt, args);
  	va_end(args);
  
  	return retval;
  }
  EXPORT_SYMBOL_GPL(kobject_init_and_add);
  
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
473
   * kobject_rename() - Change the name of an object.
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
474
475
   * @kobj: object in question.
   * @new_name: object's new name
030c1d2bf   Eric W. Biederman   kobject: Fix kobj...
476
477
478
479
480
   *
   * 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
481
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
482
  int kobject_rename(struct kobject *kobj, const char *new_name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
484
  {
  	int error = 0;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
485
  	const char *devpath = NULL;
0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
486
  	const char *dup_name = NULL, *name;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
487
488
  	char *devpath_string = NULL;
  	char *envp[2];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
490
491
492
  
  	kobj = kobject_get(kobj);
  	if (!kobj)
  		return -EINVAL;
122f8ec7b   Lin Yi   lib : kobject: fi...
493
494
  	if (!kobj->parent) {
  		kobject_put(kobj);
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
495
  		return -EINVAL;
122f8ec7b   Lin Yi   lib : kobject: fi...
496
  	}
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
497
498
499
500
501
502
503
504
505
506
507
508
509
510
  
  	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...
511

f773f32d7   Rasmus Villemoes   lib/kobject.c: us...
512
  	name = dup_name = kstrdup_const(new_name, GFP_KERNEL);
0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
513
514
515
516
  	if (!name) {
  		error = -ENOMEM;
  		goto out;
  	}
e34ff4906   Tejun Heo   sysfs: remove kty...
517
  	error = sysfs_rename_dir_ns(kobj, new_name, kobject_namespace(kobj));
0b4a4fea2   Eric W. Biederman   kobject: Cleanup ...
518
519
520
521
522
523
  	if (error)
  		goto out;
  
  	/* Install the new kobject name */
  	dup_name = kobj->name;
  	kobj->name = name;
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
524
525
526
527
  
  	/* 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 ...
528
  	kobject_uevent_env(kobj, KOBJ_MOVE, envp);
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
529
530
  
  out:
f773f32d7   Rasmus Villemoes   lib/kobject.c: us...
531
  	kfree_const(dup_name);
ca2f37dbc   Jean Tourrilhes   Driver core: noti...
532
533
  	kfree(devpath_string);
  	kfree(devpath);
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
534
535
536
537
  	kobject_put(kobj);
  
  	return error;
  }
8344b568f   Alex Chiang   PCI: ACPI PCI slo...
538
  EXPORT_SYMBOL_GPL(kobject_rename);
b592fcfe7   Eric W. Biederman   sysfs: Shadow dir...
539
540
  
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
541
   * kobject_move() - Move object to another parent.
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
542
543
   * @kobj: object in question.
   * @new_parent: object's new parent (can be NULL)
8a82472f8   Cornelia Huck   driver core: Intr...
544
   */
8a82472f8   Cornelia Huck   driver core: Intr...
545
546
547
548
549
550
551
552
553
554
555
556
557
  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...
558
559
  		if (kobj->kset)
  			new_parent = kobject_get(&kobj->kset->kobj);
8a82472f8   Cornelia Huck   driver core: Intr...
560
  	}
e34ff4906   Tejun Heo   sysfs: remove kty...
561

8a82472f8   Cornelia Huck   driver core: Intr...
562
563
564
565
566
567
568
569
570
571
572
573
574
575
  	/* 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...
576
  	error = sysfs_move_dir_ns(kobj, new_parent, kobject_namespace(kobj));
8a82472f8   Cornelia Huck   driver core: Intr...
577
578
579
580
  	if (error)
  		goto out;
  	old_parent = kobj->parent;
  	kobj->parent = new_parent;
9e993efb0   Dmitriy Monakhov   kobject: new_devi...
581
  	new_parent = NULL;
8a82472f8   Cornelia Huck   driver core: Intr...
582
583
584
  	kobject_put(old_parent);
  	kobject_uevent_env(kobj, KOBJ_MOVE, envp);
  out:
9e993efb0   Dmitriy Monakhov   kobject: new_devi...
585
  	kobject_put(new_parent);
8a82472f8   Cornelia Huck   driver core: Intr...
586
587
588
589
590
  	kobject_put(kobj);
  	kfree(devpath_string);
  	kfree(devpath);
  	return error;
  }
24199d206   Anand Jain   lib: export symbo...
591
  EXPORT_SYMBOL_GPL(kobject_move);
8a82472f8   Cornelia Huck   driver core: Intr...
592

079ad2fb4   Heikki Krogerus   kobject: Avoid pr...
593
  static void __kobject_del(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594
  {
324a56e16   Tejun Heo   kernfs: s/sysfs_d...
595
  	struct kernfs_node *sd;
3d378dc71   Colin Ian King   kobject: fix dere...
596
  	const struct kobj_type *ktype;
26ea12dec   Tejun Heo   kobject: grab an ...
597

26ea12dec   Tejun Heo   kobject: grab an ...
598
  	sd = kobj->sd;
3d378dc71   Colin Ian King   kobject: fix dere...
599
  	ktype = get_ktype(kobj);
aa30f47cf   Kimberly Brown   kobject: Add supp...
600
601
602
  
  	if (ktype)
  		sysfs_remove_groups(kobj, ktype->default_groups);
0e5596c54   Greg Kroah-Hartman   kobject: send KOB...
603
604
605
606
607
608
609
  	/* 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);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
610
  	sysfs_remove_dir(kobj);
26ea12dec   Tejun Heo   kobject: grab an ...
611
  	sysfs_put(sd);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
612
613
  	kobj->state_in_sysfs = 0;
  	kobj_kset_leave(kobj);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
614
  	kobj->parent = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
615
  }
079ad2fb4   Heikki Krogerus   kobject: Avoid pr...
616
617
618
619
620
621
622
623
624
625
  
  /**
   * kobject_del() - Unlink kobject from hierarchy.
   * @kobj: object.
   *
   * This is the function that should be called to delete an object
   * successfully added via kobject_add().
   */
  void kobject_del(struct kobject *kobj)
  {
40b8b826a   Andy Shevchenko   kobject: Restore ...
626
627
628
629
  	struct kobject *parent;
  
  	if (!kobj)
  		return;
079ad2fb4   Heikki Krogerus   kobject: Avoid pr...
630

40b8b826a   Andy Shevchenko   kobject: Restore ...
631
  	parent = kobj->parent;
079ad2fb4   Heikki Krogerus   kobject: Avoid pr...
632
633
634
  	__kobject_del(kobj);
  	kobject_put(parent);
  }
fa40ae344   Gabriel Somlo   kobject: move EXP...
635
  EXPORT_SYMBOL(kobject_del);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
637
  
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
638
   * kobject_get() - Increment refcount for object.
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
639
   * @kobj: object.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
640
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
641
  struct kobject *kobject_get(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
642
  {
d82d54af7   Ethan Zhao   kobject: WARN as ...
643
644
  	if (kobj) {
  		if (!kobj->state_initialized)
82d1f1178   Andy Shevchenko   lib/kobject: Join...
645
646
647
648
  			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
649
  		kref_get(&kobj->kref);
d82d54af7   Ethan Zhao   kobject: WARN as ...
650
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
652
  	return kobj;
  }
fa40ae344   Gabriel Somlo   kobject: move EXP...
653
  EXPORT_SYMBOL(kobject_get);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654

c70c176ff   Jan Kara   kobject: Export k...
655
  struct kobject * __must_check kobject_get_unless_zero(struct kobject *kobj)
a49b7e82c   Linus Torvalds   kobject: fix kset...
656
  {
c70c176ff   Jan Kara   kobject: Export k...
657
658
  	if (!kobj)
  		return NULL;
a49b7e82c   Linus Torvalds   kobject: fix kset...
659
660
661
662
  	if (!kref_get_unless_zero(&kobj->kref))
  		kobj = NULL;
  	return kobj;
  }
c70c176ff   Jan Kara   kobject: Export k...
663
  EXPORT_SYMBOL(kobject_get_unless_zero);
a49b7e82c   Linus Torvalds   kobject: fix kset...
664

18041f477   Greg Kroah-Hartman   kobject: make kob...
665
666
667
  /*
   * kobject_cleanup - free kobject resources.
   * @kobj: object to cleanup
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
   */
18041f477   Greg Kroah-Hartman   kobject: make kob...
669
  static void kobject_cleanup(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
  {
079ad2fb4   Heikki Krogerus   kobject: Avoid pr...
671
  	struct kobject *parent = kobj->parent;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
672
  	struct kobj_type *t = get_ktype(kobj);
af5ca3f4e   Kay Sievers   Driver core: chan...
673
  	const char *name = kobj->name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674

c817a67ec   Russell King   kobject: delayed ...
675
676
677
  	pr_debug("kobject: '%s' (%p): %s, parent %p
  ",
  		 kobject_name(kobj), kobj, __func__, kobj->parent);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
678
679
  
  	if (t && !t->release)
0c1bc6b84   Mauro Carvalho Chehab   docs: filesystems...
680
681
  		pr_debug("kobject: '%s' (%p): does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
  ",
0f4dafc05   Kay Sievers   Kobject: auto-cle...
682
  			 kobject_name(kobj), kobj);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
683
684
685
686
687
  	/* 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);
079ad2fb4   Heikki Krogerus   kobject: Avoid pr...
688
689
690
691
  		__kobject_del(kobj);
  	} else {
  		/* avoid dropping the parent reference unnecessarily */
  		parent = NULL;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
692
  	}
ce2c9cb02   Greg Kroah-Hartman   kobject: remove t...
693
  	if (t && t->release) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
694
695
696
  		pr_debug("kobject: '%s' (%p): calling ktype release
  ",
  			 kobject_name(kobj), kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
697
  		t->release(kobj);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
698
699
700
  	}
  
  	/* free name if we allocated it */
af5ca3f4e   Kay Sievers   Driver core: chan...
701
  	if (name) {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
702
703
  		pr_debug("kobject: '%s': free name
  ", name);
f773f32d7   Rasmus Villemoes   lib/kobject.c: us...
704
  		kfree_const(name);
ce2c9cb02   Greg Kroah-Hartman   kobject: remove t...
705
  	}
079ad2fb4   Heikki Krogerus   kobject: Avoid pr...
706
707
  
  	kobject_put(parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708
  }
c817a67ec   Russell King   kobject: delayed ...
709
710
711
712
713
714
715
  #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
716
717
  static void kobject_release(struct kref *kref)
  {
c817a67ec   Russell King   kobject: delayed ...
718
719
  	struct kobject *kobj = container_of(kref, struct kobject, kref);
  #ifdef CONFIG_DEBUG_KOBJECT_RELEASE
89c86a64c   Bjorn Helgaas   kobject: delay ko...
720
721
722
723
  	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 ...
724
  	INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup);
89c86a64c   Bjorn Helgaas   kobject: delay ko...
725
726
  
  	schedule_delayed_work(&kobj->release, delay);
c817a67ec   Russell King   kobject: delayed ...
727
728
729
  #else
  	kobject_cleanup(kobj);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
730
731
732
  }
  
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
733
   * kobject_put() - Decrement refcount for object.
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
734
   * @kobj: object.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
735
   *
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
736
   * Decrement the refcount, and if 0, call kobject_cleanup().
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
737
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
738
  void kobject_put(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739
  {
c1ebdae51   Greg Kroah-Hartman   kobject: catch ko...
740
  	if (kobj) {
d955c78ac   Arjan van de Ven   Example use of WA...
741
  		if (!kobj->state_initialized)
82d1f1178   Andy Shevchenko   lib/kobject: Join...
742
743
744
745
  			WARN(1, KERN_WARNING
  				"kobject: '%s' (%p): is not initialized, yet kobject_put() is being called.
  ",
  			     kobject_name(kobj), kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
746
  		kref_put(&kobj->kref, kobject_release);
c1ebdae51   Greg Kroah-Hartman   kobject: catch ko...
747
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
748
  }
fa40ae344   Gabriel Somlo   kobject: move EXP...
749
  EXPORT_SYMBOL(kobject_put);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750

3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
751
  static void dynamic_kobj_release(struct kobject *kobj)
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
752
  {
810304db7   Harvey Harrison   lib: replace rema...
753
754
  	pr_debug("kobject: (%p): %s
  ", kobj, __func__);
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
755
756
  	kfree(kobj);
  }
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
757
  static struct kobj_type dynamic_kobj_ktype = {
386f275f5   Kay Sievers   Driver Core: swit...
758
759
  	.release	= dynamic_kobj_release,
  	.sysfs_ops	= &kobj_sysfs_ops,
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
760
  };
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
761
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
762
   * kobject_create() - Create a struct kobject dynamically.
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
763
764
765
766
767
   *
   * 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 ...
768
   * The kobject structure returned from here must be cleaned up with a
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
769
   * call to kobject_put() and not kfree(), as kobject_init() has
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
770
   * already been called on this structure.
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
771
   */
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
772
  struct kobject *kobject_create(void)
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
773
774
775
776
777
778
  {
  	struct kobject *kobj;
  
  	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
  	if (!kobj)
  		return NULL;
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
779
  	kobject_init(kobj, &dynamic_kobj_ktype);
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
780
781
782
783
  	return kobj;
  }
  
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
784
785
   * kobject_create_and_add() - Create a struct kobject dynamically and
   *                            register it with sysfs.
9ff1f838e   Zhi Yong Wu   kobject: fix the ...
786
   * @name: the name for the kobject
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
787
788
   * @parent: the parent kobject of this kobject, if any.
   *
f70701a34   Dave Young   kobject: kerneldo...
789
   * This function creates a kobject structure dynamically and registers it
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
790
   * with sysfs.  When you are finished with this structure, call
78a2d906b   Greg Kroah-Hartman   Kobject: convert ...
791
   * kobject_put() and the structure will be dynamically freed when
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
792
793
794
795
796
797
798
799
800
801
802
803
   * 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...
804
  	retval = kobject_add(kobj, parent, "%s", name);
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
805
  	if (retval) {
82d1f1178   Andy Shevchenko   lib/kobject: Join...
806
807
  		pr_warn("%s: kobject_add error: %d
  ", __func__, retval);
3f9e3ee9d   Greg Kroah-Hartman   kobject: add kobj...
808
809
810
811
812
813
  		kobject_put(kobj);
  		kobj = NULL;
  	}
  	return kobj;
  }
  EXPORT_SYMBOL_GPL(kobject_create_and_add);
7423172a5   Jun'ichi Nomura   [PATCH] kobject_a...
814
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
815
   * kset_init() - Initialize a kset for use.
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
816
   * @k: kset
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
817
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
818
  void kset_init(struct kset *k)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
819
  {
e1543ddf7   Greg Kroah-Hartman   Kobject: remove k...
820
  	kobject_init_internal(&k->kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
821
822
823
  	INIT_LIST_HEAD(&k->list);
  	spin_lock_init(&k->list_lock);
  }
23b5212cc   Kay Sievers   Driver Core: add ...
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
  /* 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...
848
  const struct sysfs_ops kobj_sysfs_ops = {
23b5212cc   Kay Sievers   Driver Core: add ...
849
850
851
  	.show	= kobj_attr_show,
  	.store	= kobj_attr_store,
  };
29dfe2dc0   Jeff Mahoney   kobject: export k...
852
  EXPORT_SYMBOL_GPL(kobj_sysfs_ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
854
  
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
855
   * kset_register() - Initialize and add a kset.
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
856
   * @k: kset.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
857
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
858
  int kset_register(struct kset *k)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
859
  {
80f03e349   Kay Sievers   Driver core: add ...
860
  	int err;
31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
861
862
  	if (!k)
  		return -EINVAL;
80f03e349   Kay Sievers   Driver core: add ...
863

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
864
  	kset_init(k);
12e339ac6   Greg Kroah-Hartman   Kset: remove kset...
865
  	err = kobject_add_internal(&k->kobj);
80f03e349   Kay Sievers   Driver core: add ...
866
867
868
869
  	if (err)
  		return err;
  	kobject_uevent(&k->kobj, KOBJ_ADD);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
870
  }
fa40ae344   Gabriel Somlo   kobject: move EXP...
871
  EXPORT_SYMBOL(kset_register);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
873
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
874
   * kset_unregister() - Remove a kset.
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
875
   * @k: kset.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
876
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
877
  void kset_unregister(struct kset *k)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
878
  {
31b9025aa   Greg Kroah-Hartman   Kobject: make kob...
879
880
  	if (!k)
  		return;
35a5fe695   Bjorn Helgaas   kobject: remove k...
881
  	kobject_del(&k->kobj);
78a2d906b   Greg Kroah-Hartman   Kobject: convert ...
882
  	kobject_put(&k->kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
883
  }
fa40ae344   Gabriel Somlo   kobject: move EXP...
884
  EXPORT_SYMBOL(kset_unregister);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
885

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
886
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
887
   * kset_find_obj() - Search for object in kset.
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
888
889
   * @kset: kset we're looking in.
   * @name: object's name.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
890
   *
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
891
892
893
   * 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
894
   */
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
895
  struct kobject *kset_find_obj(struct kset *kset, const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
896
  {
c6a2a3dc2   Robert P. J. Day   Kobject: Replace ...
897
  	struct kobject *k;
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
898
  	struct kobject *ret = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
899
900
  
  	spin_lock(&kset->list_lock);
c25d1dfbd   Robin Holt   kobject: Introduc...
901

c6a2a3dc2   Robert P. J. Day   Kobject: Replace ...
902
  	list_for_each_entry(k, &kset->list, entry) {
e374a2bfe   Greg Kroah-Hartman   Kobject: fix codi...
903
  		if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
a49b7e82c   Linus Torvalds   kobject: fix kset...
904
  			ret = kobject_get_unless_zero(k);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
905
906
907
  			break;
  		}
  	}
c25d1dfbd   Robin Holt   kobject: Introduc...
908

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
909
910
911
  	spin_unlock(&kset->list_lock);
  	return ret;
  }
2fe829aca   Gabriel Somlo   kobject: export k...
912
  EXPORT_SYMBOL_GPL(kset_find_obj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
913

b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
914
915
916
  static void kset_release(struct kobject *kobj)
  {
  	struct kset *kset = container_of(kobj, struct kset, kobj);
9f66fa2a4   Greg Kroah-Hartman   kobject: clean up...
917
918
  	pr_debug("kobject: '%s' (%p): %s
  ",
810304db7   Harvey Harrison   lib: replace rema...
919
  		 kobject_name(kobj), kobj, __func__);
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
920
921
  	kfree(kset);
  }
7ab35a14d   Eric Biggers   kobject: make kse...
922
  static void kset_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid)
d028b6f70   Dmitry Torokhov   kobject: kset_cre...
923
924
925
926
  {
  	if (kobj->parent)
  		kobject_get_ownership(kobj->parent, uid, gid);
  }
386f275f5   Kay Sievers   Driver Core: swit...
927
928
  static struct kobj_type kset_ktype = {
  	.sysfs_ops	= &kobj_sysfs_ops,
d028b6f70   Dmitry Torokhov   kobject: kset_cre...
929
930
  	.release	= kset_release,
  	.get_ownership	= kset_get_ownership,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
931
932
933
  };
  
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
934
   * kset_create() - Create a struct kset dynamically.
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
935
936
937
938
939
940
941
942
943
944
945
946
947
948
   *
   * @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...
949
  				const struct kset_uevent_ops *uevent_ops,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
950
951
952
  				struct kobject *parent_kobj)
  {
  	struct kset *kset;
d9cd8f378   Dave Young   kobject: make kse...
953
  	int retval;
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
954
955
956
957
  
  	kset = kzalloc(sizeof(*kset), GFP_KERNEL);
  	if (!kset)
  		return NULL;
b7165ebbf   Kees Cook   kobject: sanitize...
958
  	retval = kobject_set_name(&kset->kobj, "%s", name);
d9cd8f378   Dave Young   kobject: make kse...
959
960
961
962
  	if (retval) {
  		kfree(kset);
  		return NULL;
  	}
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
963
964
965
966
  	kset->uevent_ops = uevent_ops;
  	kset->kobj.parent = parent_kobj;
  
  	/*
386f275f5   Kay Sievers   Driver Core: swit...
967
  	 * The kobject of this kset will have a type of kset_ktype and belong to
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
968
969
970
  	 * no kset itself.  That way we can properly free it when it is
  	 * finished being used.
  	 */
386f275f5   Kay Sievers   Driver Core: swit...
971
  	kset->kobj.ktype = &kset_ktype;
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
972
973
974
975
976
977
  	kset->kobj.kset = NULL;
  
  	return kset;
  }
  
  /**
ed856349d   Tobin C. Harding   kobject: Fix kern...
978
   * kset_create_and_add() - Create a struct kset dynamically and add it to sysfs.
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
979
980
981
982
983
984
985
986
987
988
989
990
991
   *
   * @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...
992
  				 const struct kset_uevent_ops *uevent_ops,
b727c7028   Greg Kroah-Hartman   kset: add kset_cr...
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
  				 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...
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
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
  
  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...
1055
  	if (parent && parent->ktype && parent->ktype->child_ns_type)
bc451f205   Eric W. Biederman   kobj: Add basic i...
1056
1057
1058
1059
1060
1061
1062
1063
1064
  		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...
1065
1066
  bool kobj_ns_current_may_mount(enum kobj_ns_type type)
  {
730d7d339   Eric W. Biederman   sysfs: Allow moun...
1067
  	bool may_mount = true;
7dc5dbc87   Eric W. Biederman   sysfs: Restrict m...
1068
1069
1070
1071
1072
1073
1074
1075
1076
  
  	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...
1077

a685e0898   Al Viro   Delay struct net ...
1078
  void *kobj_ns_grab_current(enum kobj_ns_type type)
bc451f205   Eric W. Biederman   kobj: Add basic i...
1079
  {
a685e0898   Al Viro   Delay struct net ...
1080
  	void *ns = NULL;
bc451f205   Eric W. Biederman   kobj: Add basic i...
1081
1082
1083
1084
  
  	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 ...
1085
  		ns = kobj_ns_ops_tbl[type]->grab_current_ns();
bc451f205   Eric W. Biederman   kobj: Add basic i...
1086
1087
1088
1089
  	spin_unlock(&kobj_ns_type_lock);
  
  	return ns;
  }
172856eac   Bart Van Assche   kobject: Export k...
1090
  EXPORT_SYMBOL_GPL(kobj_ns_grab_current);
bc451f205   Eric W. Biederman   kobj: Add basic i...
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
  
  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 ...
1117
  void kobj_ns_drop(enum kobj_ns_type type, void *ns)
bc451f205   Eric W. Biederman   kobj: Add basic i...
1118
  {
a685e0898   Al Viro   Delay struct net ...
1119
1120
1121
1122
1123
  	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...
1124
  }
172856eac   Bart Van Assche   kobject: Export k...
1125
  EXPORT_SYMBOL_GPL(kobj_ns_drop);