Commit b365b3daf2a9e2a8b002ea9fef877af1c71513fd

Authored by Chuck Ebbert
Committed by Greg Kroah-Hartman
1 parent c171fef5c8

[PATCH] kobject: don't oops on null kobject.name

kobject_get_path() will oops if one of the component names is
NULL.  Fix that by returning NULL instead of oopsing.

Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 1 changed file with 4 additions and 0 deletions Inline Diff

1 /* 1 /*
2 * kobject.c - library routines for handling generic kernel objects 2 * kobject.c - library routines for handling generic kernel objects
3 * 3 *
4 * Copyright (c) 2002-2003 Patrick Mochel <mochel@osdl.org> 4 * Copyright (c) 2002-2003 Patrick Mochel <mochel@osdl.org>
5 * 5 *
6 * This file is released under the GPLv2. 6 * This file is released under the GPLv2.
7 * 7 *
8 * 8 *
9 * Please see the file Documentation/kobject.txt for critical information 9 * Please see the file Documentation/kobject.txt for critical information
10 * about using the kobject interface. 10 * about using the kobject interface.
11 */ 11 */
12 12
13 #include <linux/kobject.h> 13 #include <linux/kobject.h>
14 #include <linux/string.h> 14 #include <linux/string.h>
15 #include <linux/module.h> 15 #include <linux/module.h>
16 #include <linux/stat.h> 16 #include <linux/stat.h>
17 #include <linux/slab.h> 17 #include <linux/slab.h>
18 18
19 /** 19 /**
20 * populate_dir - populate directory with attributes. 20 * populate_dir - populate directory with attributes.
21 * @kobj: object we're working on. 21 * @kobj: object we're working on.
22 * 22 *
23 * Most subsystems have a set of default attributes that 23 * Most subsystems have a set of default attributes that
24 * are associated with an object that registers with them. 24 * are associated with an object that registers with them.
25 * This is a helper called during object registration that 25 * This is a helper called during object registration that
26 * loops through the default attributes of the subsystem 26 * loops through the default attributes of the subsystem
27 * and creates attributes files for them in sysfs. 27 * and creates attributes files for them in sysfs.
28 * 28 *
29 */ 29 */
30 30
31 static int populate_dir(struct kobject * kobj) 31 static int populate_dir(struct kobject * kobj)
32 { 32 {
33 struct kobj_type * t = get_ktype(kobj); 33 struct kobj_type * t = get_ktype(kobj);
34 struct attribute * attr; 34 struct attribute * attr;
35 int error = 0; 35 int error = 0;
36 int i; 36 int i;
37 37
38 if (t && t->default_attrs) { 38 if (t && t->default_attrs) {
39 for (i = 0; (attr = t->default_attrs[i]) != NULL; i++) { 39 for (i = 0; (attr = t->default_attrs[i]) != NULL; i++) {
40 if ((error = sysfs_create_file(kobj,attr))) 40 if ((error = sysfs_create_file(kobj,attr)))
41 break; 41 break;
42 } 42 }
43 } 43 }
44 return error; 44 return error;
45 } 45 }
46 46
47 static int create_dir(struct kobject * kobj) 47 static int create_dir(struct kobject * kobj)
48 { 48 {
49 int error = 0; 49 int error = 0;
50 if (kobject_name(kobj)) { 50 if (kobject_name(kobj)) {
51 error = sysfs_create_dir(kobj); 51 error = sysfs_create_dir(kobj);
52 if (!error) { 52 if (!error) {
53 if ((error = populate_dir(kobj))) 53 if ((error = populate_dir(kobj)))
54 sysfs_remove_dir(kobj); 54 sysfs_remove_dir(kobj);
55 } 55 }
56 } 56 }
57 return error; 57 return error;
58 } 58 }
59 59
60 static inline struct kobject * to_kobj(struct list_head * entry) 60 static inline struct kobject * to_kobj(struct list_head * entry)
61 { 61 {
62 return container_of(entry,struct kobject,entry); 62 return container_of(entry,struct kobject,entry);
63 } 63 }
64 64
65 static int get_kobj_path_length(struct kobject *kobj) 65 static int get_kobj_path_length(struct kobject *kobj)
66 { 66 {
67 int length = 1; 67 int length = 1;
68 struct kobject * parent = kobj; 68 struct kobject * parent = kobj;
69 69
70 /* walk up the ancestors until we hit the one pointing to the 70 /* walk up the ancestors until we hit the one pointing to the
71 * root. 71 * root.
72 * Add 1 to strlen for leading '/' of each level. 72 * Add 1 to strlen for leading '/' of each level.
73 */ 73 */
74 do { 74 do {
75 if (kobject_name(parent) == NULL)
76 return 0;
75 length += strlen(kobject_name(parent)) + 1; 77 length += strlen(kobject_name(parent)) + 1;
76 parent = parent->parent; 78 parent = parent->parent;
77 } while (parent); 79 } while (parent);
78 return length; 80 return length;
79 } 81 }
80 82
81 static void fill_kobj_path(struct kobject *kobj, char *path, int length) 83 static void fill_kobj_path(struct kobject *kobj, char *path, int length)
82 { 84 {
83 struct kobject * parent; 85 struct kobject * parent;
84 86
85 --length; 87 --length;
86 for (parent = kobj; parent; parent = parent->parent) { 88 for (parent = kobj; parent; parent = parent->parent) {
87 int cur = strlen(kobject_name(parent)); 89 int cur = strlen(kobject_name(parent));
88 /* back up enough to print this name with '/' */ 90 /* back up enough to print this name with '/' */
89 length -= cur; 91 length -= cur;
90 strncpy (path + length, kobject_name(parent), cur); 92 strncpy (path + length, kobject_name(parent), cur);
91 *(path + --length) = '/'; 93 *(path + --length) = '/';
92 } 94 }
93 95
94 pr_debug("%s: path = '%s'\n",__FUNCTION__,path); 96 pr_debug("%s: path = '%s'\n",__FUNCTION__,path);
95 } 97 }
96 98
97 /** 99 /**
98 * kobject_get_path - generate and return the path associated with a given kobj 100 * kobject_get_path - generate and return the path associated with a given kobj
99 * and kset pair. The result must be freed by the caller with kfree(). 101 * and kset pair. The result must be freed by the caller with kfree().
100 * 102 *
101 * @kobj: kobject in question, with which to build the path 103 * @kobj: kobject in question, with which to build the path
102 * @gfp_mask: the allocation type used to allocate the path 104 * @gfp_mask: the allocation type used to allocate the path
103 */ 105 */
104 char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) 106 char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
105 { 107 {
106 char *path; 108 char *path;
107 int len; 109 int len;
108 110
109 len = get_kobj_path_length(kobj); 111 len = get_kobj_path_length(kobj);
112 if (len == 0)
113 return NULL;
110 path = kmalloc(len, gfp_mask); 114 path = kmalloc(len, gfp_mask);
111 if (!path) 115 if (!path)
112 return NULL; 116 return NULL;
113 memset(path, 0x00, len); 117 memset(path, 0x00, len);
114 fill_kobj_path(kobj, path, len); 118 fill_kobj_path(kobj, path, len);
115 119
116 return path; 120 return path;
117 } 121 }
118 122
119 /** 123 /**
120 * kobject_init - initialize object. 124 * kobject_init - initialize object.
121 * @kobj: object in question. 125 * @kobj: object in question.
122 */ 126 */
123 void kobject_init(struct kobject * kobj) 127 void kobject_init(struct kobject * kobj)
124 { 128 {
125 kref_init(&kobj->kref); 129 kref_init(&kobj->kref);
126 INIT_LIST_HEAD(&kobj->entry); 130 INIT_LIST_HEAD(&kobj->entry);
127 kobj->kset = kset_get(kobj->kset); 131 kobj->kset = kset_get(kobj->kset);
128 } 132 }
129 133
130 134
131 /** 135 /**
132 * unlink - remove kobject from kset list. 136 * unlink - remove kobject from kset list.
133 * @kobj: kobject. 137 * @kobj: kobject.
134 * 138 *
135 * Remove the kobject from the kset list and decrement 139 * Remove the kobject from the kset list and decrement
136 * its parent's refcount. 140 * its parent's refcount.
137 * This is separated out, so we can use it in both 141 * This is separated out, so we can use it in both
138 * kobject_del() and kobject_add() on error. 142 * kobject_del() and kobject_add() on error.
139 */ 143 */
140 144
141 static void unlink(struct kobject * kobj) 145 static void unlink(struct kobject * kobj)
142 { 146 {
143 if (kobj->kset) { 147 if (kobj->kset) {
144 spin_lock(&kobj->kset->list_lock); 148 spin_lock(&kobj->kset->list_lock);
145 list_del_init(&kobj->entry); 149 list_del_init(&kobj->entry);
146 spin_unlock(&kobj->kset->list_lock); 150 spin_unlock(&kobj->kset->list_lock);
147 } 151 }
148 kobject_put(kobj); 152 kobject_put(kobj);
149 } 153 }
150 154
151 /** 155 /**
152 * kobject_add - add an object to the hierarchy. 156 * kobject_add - add an object to the hierarchy.
153 * @kobj: object. 157 * @kobj: object.
154 */ 158 */
155 159
156 int kobject_add(struct kobject * kobj) 160 int kobject_add(struct kobject * kobj)
157 { 161 {
158 int error = 0; 162 int error = 0;
159 struct kobject * parent; 163 struct kobject * parent;
160 164
161 if (!(kobj = kobject_get(kobj))) 165 if (!(kobj = kobject_get(kobj)))
162 return -ENOENT; 166 return -ENOENT;
163 if (!kobj->k_name) 167 if (!kobj->k_name)
164 kobj->k_name = kobj->name; 168 kobj->k_name = kobj->name;
165 if (!kobj->k_name) { 169 if (!kobj->k_name) {
166 pr_debug("kobject attempted to be registered with no name!\n"); 170 pr_debug("kobject attempted to be registered with no name!\n");
167 WARN_ON(1); 171 WARN_ON(1);
168 return -EINVAL; 172 return -EINVAL;
169 } 173 }
170 parent = kobject_get(kobj->parent); 174 parent = kobject_get(kobj->parent);
171 175
172 pr_debug("kobject %s: registering. parent: %s, set: %s\n", 176 pr_debug("kobject %s: registering. parent: %s, set: %s\n",
173 kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>", 177 kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>",
174 kobj->kset ? kobj->kset->kobj.name : "<NULL>" ); 178 kobj->kset ? kobj->kset->kobj.name : "<NULL>" );
175 179
176 if (kobj->kset) { 180 if (kobj->kset) {
177 spin_lock(&kobj->kset->list_lock); 181 spin_lock(&kobj->kset->list_lock);
178 182
179 if (!parent) 183 if (!parent)
180 parent = kobject_get(&kobj->kset->kobj); 184 parent = kobject_get(&kobj->kset->kobj);
181 185
182 list_add_tail(&kobj->entry,&kobj->kset->list); 186 list_add_tail(&kobj->entry,&kobj->kset->list);
183 spin_unlock(&kobj->kset->list_lock); 187 spin_unlock(&kobj->kset->list_lock);
184 } 188 }
185 kobj->parent = parent; 189 kobj->parent = parent;
186 190
187 error = create_dir(kobj); 191 error = create_dir(kobj);
188 if (error) { 192 if (error) {
189 /* unlink does the kobject_put() for us */ 193 /* unlink does the kobject_put() for us */
190 unlink(kobj); 194 unlink(kobj);
191 if (parent) 195 if (parent)
192 kobject_put(parent); 196 kobject_put(parent);
193 } 197 }
194 198
195 return error; 199 return error;
196 } 200 }
197 201
198 202
199 /** 203 /**
200 * kobject_register - initialize and add an object. 204 * kobject_register - initialize and add an object.
201 * @kobj: object in question. 205 * @kobj: object in question.
202 */ 206 */
203 207
204 int kobject_register(struct kobject * kobj) 208 int kobject_register(struct kobject * kobj)
205 { 209 {
206 int error = 0; 210 int error = 0;
207 if (kobj) { 211 if (kobj) {
208 kobject_init(kobj); 212 kobject_init(kobj);
209 error = kobject_add(kobj); 213 error = kobject_add(kobj);
210 if (error) { 214 if (error) {
211 printk("kobject_register failed for %s (%d)\n", 215 printk("kobject_register failed for %s (%d)\n",
212 kobject_name(kobj),error); 216 kobject_name(kobj),error);
213 dump_stack(); 217 dump_stack();
214 } else 218 } else
215 kobject_uevent(kobj, KOBJ_ADD); 219 kobject_uevent(kobj, KOBJ_ADD);
216 } else 220 } else
217 error = -EINVAL; 221 error = -EINVAL;
218 return error; 222 return error;
219 } 223 }
220 224
221 225
222 /** 226 /**
223 * kobject_set_name - Set the name of an object 227 * kobject_set_name - Set the name of an object
224 * @kobj: object. 228 * @kobj: object.
225 * @fmt: format string used to build the name 229 * @fmt: format string used to build the name
226 * 230 *
227 * If strlen(name) >= KOBJ_NAME_LEN, then use a dynamically allocated 231 * If strlen(name) >= KOBJ_NAME_LEN, then use a dynamically allocated
228 * string that @kobj->k_name points to. Otherwise, use the static 232 * string that @kobj->k_name points to. Otherwise, use the static
229 * @kobj->name array. 233 * @kobj->name array.
230 */ 234 */
231 int kobject_set_name(struct kobject * kobj, const char * fmt, ...) 235 int kobject_set_name(struct kobject * kobj, const char * fmt, ...)
232 { 236 {
233 int error = 0; 237 int error = 0;
234 int limit = KOBJ_NAME_LEN; 238 int limit = KOBJ_NAME_LEN;
235 int need; 239 int need;
236 va_list args; 240 va_list args;
237 char * name; 241 char * name;
238 242
239 /* 243 /*
240 * First, try the static array 244 * First, try the static array
241 */ 245 */
242 va_start(args,fmt); 246 va_start(args,fmt);
243 need = vsnprintf(kobj->name,limit,fmt,args); 247 need = vsnprintf(kobj->name,limit,fmt,args);
244 va_end(args); 248 va_end(args);
245 if (need < limit) 249 if (need < limit)
246 name = kobj->name; 250 name = kobj->name;
247 else { 251 else {
248 /* 252 /*
249 * Need more space? Allocate it and try again 253 * Need more space? Allocate it and try again
250 */ 254 */
251 limit = need + 1; 255 limit = need + 1;
252 name = kmalloc(limit,GFP_KERNEL); 256 name = kmalloc(limit,GFP_KERNEL);
253 if (!name) { 257 if (!name) {
254 error = -ENOMEM; 258 error = -ENOMEM;
255 goto Done; 259 goto Done;
256 } 260 }
257 va_start(args,fmt); 261 va_start(args,fmt);
258 need = vsnprintf(name,limit,fmt,args); 262 need = vsnprintf(name,limit,fmt,args);
259 va_end(args); 263 va_end(args);
260 264
261 /* Still? Give up. */ 265 /* Still? Give up. */
262 if (need >= limit) { 266 if (need >= limit) {
263 kfree(name); 267 kfree(name);
264 error = -EFAULT; 268 error = -EFAULT;
265 goto Done; 269 goto Done;
266 } 270 }
267 } 271 }
268 272
269 /* Free the old name, if necessary. */ 273 /* Free the old name, if necessary. */
270 if (kobj->k_name && kobj->k_name != kobj->name) 274 if (kobj->k_name && kobj->k_name != kobj->name)
271 kfree(kobj->k_name); 275 kfree(kobj->k_name);
272 276
273 /* Now, set the new name */ 277 /* Now, set the new name */
274 kobj->k_name = name; 278 kobj->k_name = name;
275 Done: 279 Done:
276 return error; 280 return error;
277 } 281 }
278 282
279 EXPORT_SYMBOL(kobject_set_name); 283 EXPORT_SYMBOL(kobject_set_name);
280 284
281 285
282 /** 286 /**
283 * kobject_rename - change the name of an object 287 * kobject_rename - change the name of an object
284 * @kobj: object in question. 288 * @kobj: object in question.
285 * @new_name: object's new name 289 * @new_name: object's new name
286 */ 290 */
287 291
288 int kobject_rename(struct kobject * kobj, const char *new_name) 292 int kobject_rename(struct kobject * kobj, const char *new_name)
289 { 293 {
290 int error = 0; 294 int error = 0;
291 295
292 kobj = kobject_get(kobj); 296 kobj = kobject_get(kobj);
293 if (!kobj) 297 if (!kobj)
294 return -EINVAL; 298 return -EINVAL;
295 error = sysfs_rename_dir(kobj, new_name); 299 error = sysfs_rename_dir(kobj, new_name);
296 kobject_put(kobj); 300 kobject_put(kobj);
297 301
298 return error; 302 return error;
299 } 303 }
300 304
301 /** 305 /**
302 * kobject_del - unlink kobject from hierarchy. 306 * kobject_del - unlink kobject from hierarchy.
303 * @kobj: object. 307 * @kobj: object.
304 */ 308 */
305 309
306 void kobject_del(struct kobject * kobj) 310 void kobject_del(struct kobject * kobj)
307 { 311 {
308 sysfs_remove_dir(kobj); 312 sysfs_remove_dir(kobj);
309 unlink(kobj); 313 unlink(kobj);
310 } 314 }
311 315
312 /** 316 /**
313 * kobject_unregister - remove object from hierarchy and decrement refcount. 317 * kobject_unregister - remove object from hierarchy and decrement refcount.
314 * @kobj: object going away. 318 * @kobj: object going away.
315 */ 319 */
316 320
317 void kobject_unregister(struct kobject * kobj) 321 void kobject_unregister(struct kobject * kobj)
318 { 322 {
319 pr_debug("kobject %s: unregistering\n",kobject_name(kobj)); 323 pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
320 kobject_uevent(kobj, KOBJ_REMOVE); 324 kobject_uevent(kobj, KOBJ_REMOVE);
321 kobject_del(kobj); 325 kobject_del(kobj);
322 kobject_put(kobj); 326 kobject_put(kobj);
323 } 327 }
324 328
325 /** 329 /**
326 * kobject_get - increment refcount for object. 330 * kobject_get - increment refcount for object.
327 * @kobj: object. 331 * @kobj: object.
328 */ 332 */
329 333
330 struct kobject * kobject_get(struct kobject * kobj) 334 struct kobject * kobject_get(struct kobject * kobj)
331 { 335 {
332 if (kobj) 336 if (kobj)
333 kref_get(&kobj->kref); 337 kref_get(&kobj->kref);
334 return kobj; 338 return kobj;
335 } 339 }
336 340
337 /** 341 /**
338 * kobject_cleanup - free kobject resources. 342 * kobject_cleanup - free kobject resources.
339 * @kobj: object. 343 * @kobj: object.
340 */ 344 */
341 345
342 void kobject_cleanup(struct kobject * kobj) 346 void kobject_cleanup(struct kobject * kobj)
343 { 347 {
344 struct kobj_type * t = get_ktype(kobj); 348 struct kobj_type * t = get_ktype(kobj);
345 struct kset * s = kobj->kset; 349 struct kset * s = kobj->kset;
346 struct kobject * parent = kobj->parent; 350 struct kobject * parent = kobj->parent;
347 351
348 pr_debug("kobject %s: cleaning up\n",kobject_name(kobj)); 352 pr_debug("kobject %s: cleaning up\n",kobject_name(kobj));
349 if (kobj->k_name != kobj->name) 353 if (kobj->k_name != kobj->name)
350 kfree(kobj->k_name); 354 kfree(kobj->k_name);
351 kobj->k_name = NULL; 355 kobj->k_name = NULL;
352 if (t && t->release) 356 if (t && t->release)
353 t->release(kobj); 357 t->release(kobj);
354 if (s) 358 if (s)
355 kset_put(s); 359 kset_put(s);
356 if (parent) 360 if (parent)
357 kobject_put(parent); 361 kobject_put(parent);
358 } 362 }
359 363
360 static void kobject_release(struct kref *kref) 364 static void kobject_release(struct kref *kref)
361 { 365 {
362 kobject_cleanup(container_of(kref, struct kobject, kref)); 366 kobject_cleanup(container_of(kref, struct kobject, kref));
363 } 367 }
364 368
365 /** 369 /**
366 * kobject_put - decrement refcount for object. 370 * kobject_put - decrement refcount for object.
367 * @kobj: object. 371 * @kobj: object.
368 * 372 *
369 * Decrement the refcount, and if 0, call kobject_cleanup(). 373 * Decrement the refcount, and if 0, call kobject_cleanup().
370 */ 374 */
371 void kobject_put(struct kobject * kobj) 375 void kobject_put(struct kobject * kobj)
372 { 376 {
373 if (kobj) 377 if (kobj)
374 kref_put(&kobj->kref, kobject_release); 378 kref_put(&kobj->kref, kobject_release);
375 } 379 }
376 380
377 381
378 /** 382 /**
379 * kset_init - initialize a kset for use 383 * kset_init - initialize a kset for use
380 * @k: kset 384 * @k: kset
381 */ 385 */
382 386
383 void kset_init(struct kset * k) 387 void kset_init(struct kset * k)
384 { 388 {
385 kobject_init(&k->kobj); 389 kobject_init(&k->kobj);
386 INIT_LIST_HEAD(&k->list); 390 INIT_LIST_HEAD(&k->list);
387 spin_lock_init(&k->list_lock); 391 spin_lock_init(&k->list_lock);
388 } 392 }
389 393
390 394
391 /** 395 /**
392 * kset_add - add a kset object to the hierarchy. 396 * kset_add - add a kset object to the hierarchy.
393 * @k: kset. 397 * @k: kset.
394 * 398 *
395 * Simply, this adds the kset's embedded kobject to the 399 * Simply, this adds the kset's embedded kobject to the
396 * hierarchy. 400 * hierarchy.
397 * We also try to make sure that the kset's embedded kobject 401 * We also try to make sure that the kset's embedded kobject
398 * has a parent before it is added. We only care if the embedded 402 * has a parent before it is added. We only care if the embedded
399 * kobject is not part of a kset itself, since kobject_add() 403 * kobject is not part of a kset itself, since kobject_add()
400 * assigns a parent in that case. 404 * assigns a parent in that case.
401 * If that is the case, and the kset has a controlling subsystem, 405 * If that is the case, and the kset has a controlling subsystem,
402 * then we set the kset's parent to be said subsystem. 406 * then we set the kset's parent to be said subsystem.
403 */ 407 */
404 408
405 int kset_add(struct kset * k) 409 int kset_add(struct kset * k)
406 { 410 {
407 if (!k->kobj.parent && !k->kobj.kset && k->subsys) 411 if (!k->kobj.parent && !k->kobj.kset && k->subsys)
408 k->kobj.parent = &k->subsys->kset.kobj; 412 k->kobj.parent = &k->subsys->kset.kobj;
409 413
410 return kobject_add(&k->kobj); 414 return kobject_add(&k->kobj);
411 } 415 }
412 416
413 417
414 /** 418 /**
415 * kset_register - initialize and add a kset. 419 * kset_register - initialize and add a kset.
416 * @k: kset. 420 * @k: kset.
417 */ 421 */
418 422
419 int kset_register(struct kset * k) 423 int kset_register(struct kset * k)
420 { 424 {
421 kset_init(k); 425 kset_init(k);
422 return kset_add(k); 426 return kset_add(k);
423 } 427 }
424 428
425 429
426 /** 430 /**
427 * kset_unregister - remove a kset. 431 * kset_unregister - remove a kset.
428 * @k: kset. 432 * @k: kset.
429 */ 433 */
430 434
431 void kset_unregister(struct kset * k) 435 void kset_unregister(struct kset * k)
432 { 436 {
433 kobject_unregister(&k->kobj); 437 kobject_unregister(&k->kobj);
434 } 438 }
435 439
436 440
437 /** 441 /**
438 * kset_find_obj - search for object in kset. 442 * kset_find_obj - search for object in kset.
439 * @kset: kset we're looking in. 443 * @kset: kset we're looking in.
440 * @name: object's name. 444 * @name: object's name.
441 * 445 *
442 * Lock kset via @kset->subsys, and iterate over @kset->list, 446 * Lock kset via @kset->subsys, and iterate over @kset->list,
443 * looking for a matching kobject. If matching object is found 447 * looking for a matching kobject. If matching object is found
444 * take a reference and return the object. 448 * take a reference and return the object.
445 */ 449 */
446 450
447 struct kobject * kset_find_obj(struct kset * kset, const char * name) 451 struct kobject * kset_find_obj(struct kset * kset, const char * name)
448 { 452 {
449 struct list_head * entry; 453 struct list_head * entry;
450 struct kobject * ret = NULL; 454 struct kobject * ret = NULL;
451 455
452 spin_lock(&kset->list_lock); 456 spin_lock(&kset->list_lock);
453 list_for_each(entry,&kset->list) { 457 list_for_each(entry,&kset->list) {
454 struct kobject * k = to_kobj(entry); 458 struct kobject * k = to_kobj(entry);
455 if (kobject_name(k) && !strcmp(kobject_name(k),name)) { 459 if (kobject_name(k) && !strcmp(kobject_name(k),name)) {
456 ret = kobject_get(k); 460 ret = kobject_get(k);
457 break; 461 break;
458 } 462 }
459 } 463 }
460 spin_unlock(&kset->list_lock); 464 spin_unlock(&kset->list_lock);
461 return ret; 465 return ret;
462 } 466 }
463 467
464 468
465 void subsystem_init(struct subsystem * s) 469 void subsystem_init(struct subsystem * s)
466 { 470 {
467 init_rwsem(&s->rwsem); 471 init_rwsem(&s->rwsem);
468 kset_init(&s->kset); 472 kset_init(&s->kset);
469 } 473 }
470 474
471 /** 475 /**
472 * subsystem_register - register a subsystem. 476 * subsystem_register - register a subsystem.
473 * @s: the subsystem we're registering. 477 * @s: the subsystem we're registering.
474 * 478 *
475 * Once we register the subsystem, we want to make sure that 479 * Once we register the subsystem, we want to make sure that
476 * the kset points back to this subsystem for correct usage of 480 * the kset points back to this subsystem for correct usage of
477 * the rwsem. 481 * the rwsem.
478 */ 482 */
479 483
480 int subsystem_register(struct subsystem * s) 484 int subsystem_register(struct subsystem * s)
481 { 485 {
482 int error; 486 int error;
483 487
484 subsystem_init(s); 488 subsystem_init(s);
485 pr_debug("subsystem %s: registering\n",s->kset.kobj.name); 489 pr_debug("subsystem %s: registering\n",s->kset.kobj.name);
486 490
487 if (!(error = kset_add(&s->kset))) { 491 if (!(error = kset_add(&s->kset))) {
488 if (!s->kset.subsys) 492 if (!s->kset.subsys)
489 s->kset.subsys = s; 493 s->kset.subsys = s;
490 } 494 }
491 return error; 495 return error;
492 } 496 }
493 497
494 void subsystem_unregister(struct subsystem * s) 498 void subsystem_unregister(struct subsystem * s)
495 { 499 {
496 pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name); 500 pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name);
497 kset_unregister(&s->kset); 501 kset_unregister(&s->kset);
498 } 502 }
499 503
500 504
501 /** 505 /**
502 * subsystem_create_file - export sysfs attribute file. 506 * subsystem_create_file - export sysfs attribute file.
503 * @s: subsystem. 507 * @s: subsystem.
504 * @a: subsystem attribute descriptor. 508 * @a: subsystem attribute descriptor.
505 */ 509 */
506 510
507 int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) 511 int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
508 { 512 {
509 int error = 0; 513 int error = 0;
510 if (subsys_get(s)) { 514 if (subsys_get(s)) {
511 error = sysfs_create_file(&s->kset.kobj,&a->attr); 515 error = sysfs_create_file(&s->kset.kobj,&a->attr);
512 subsys_put(s); 516 subsys_put(s);
513 } 517 }
514 return error; 518 return error;
515 } 519 }
516 520
517 521
518 /** 522 /**
519 * subsystem_remove_file - remove sysfs attribute file. 523 * subsystem_remove_file - remove sysfs attribute file.
520 * @s: subsystem. 524 * @s: subsystem.
521 * @a: attribute desciptor. 525 * @a: attribute desciptor.
522 */ 526 */
523 527
524 void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a) 528 void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a)
525 { 529 {
526 if (subsys_get(s)) { 530 if (subsys_get(s)) {
527 sysfs_remove_file(&s->kset.kobj,&a->attr); 531 sysfs_remove_file(&s->kset.kobj,&a->attr);
528 subsys_put(s); 532 subsys_put(s);
529 } 533 }
530 } 534 }
531 535
532 EXPORT_SYMBOL(kobject_init); 536 EXPORT_SYMBOL(kobject_init);
533 EXPORT_SYMBOL(kobject_register); 537 EXPORT_SYMBOL(kobject_register);
534 EXPORT_SYMBOL(kobject_unregister); 538 EXPORT_SYMBOL(kobject_unregister);
535 EXPORT_SYMBOL(kobject_get); 539 EXPORT_SYMBOL(kobject_get);
536 EXPORT_SYMBOL(kobject_put); 540 EXPORT_SYMBOL(kobject_put);
537 EXPORT_SYMBOL(kobject_add); 541 EXPORT_SYMBOL(kobject_add);
538 EXPORT_SYMBOL(kobject_del); 542 EXPORT_SYMBOL(kobject_del);
539 543
540 EXPORT_SYMBOL(kset_register); 544 EXPORT_SYMBOL(kset_register);
541 EXPORT_SYMBOL(kset_unregister); 545 EXPORT_SYMBOL(kset_unregister);
542 EXPORT_SYMBOL(kset_find_obj); 546 EXPORT_SYMBOL(kset_find_obj);
543 547
544 EXPORT_SYMBOL(subsystem_init); 548 EXPORT_SYMBOL(subsystem_init);
545 EXPORT_SYMBOL(subsystem_register); 549 EXPORT_SYMBOL(subsystem_register);
546 EXPORT_SYMBOL(subsystem_unregister); 550 EXPORT_SYMBOL(subsystem_unregister);
547 EXPORT_SYMBOL(subsys_create_file); 551 EXPORT_SYMBOL(subsys_create_file);
548 EXPORT_SYMBOL(subsys_remove_file); 552 EXPORT_SYMBOL(subsys_remove_file);
549 553