diff options
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r-- | fs/sysfs/dir.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index f2ea00683ec9..4762a9aa0b27 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -317,28 +317,55 @@ void sysfs_attach_dirent(struct sysfs_dirent *sd, | |||
317 | } | 317 | } |
318 | } | 318 | } |
319 | 319 | ||
320 | /* | 320 | /** |
321 | * sysfs_find_dirent - find sysfs_dirent with the given name | ||
322 | * @parent_sd: sysfs_dirent to search under | ||
323 | * @name: name to look for | ||
321 | * | 324 | * |
322 | * Return -EEXIST if there is already a sysfs element with the same name for | 325 | * Look for sysfs_dirent with name @name under @parent_sd. |
323 | * the same parent. | ||
324 | * | 326 | * |
325 | * called with parent inode's i_mutex held | 327 | * LOCKING: |
328 | * mutex_lock(parent->i_mutex) | ||
329 | * | ||
330 | * RETURNS: | ||
331 | * Pointer to sysfs_dirent if found, NULL if not. | ||
326 | */ | 332 | */ |
327 | int sysfs_dirent_exist(struct sysfs_dirent *parent_sd, | 333 | struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, |
328 | const unsigned char *new) | 334 | const unsigned char *name) |
329 | { | 335 | { |
330 | struct sysfs_dirent * sd; | 336 | struct sysfs_dirent *sd; |
331 | 337 | ||
332 | for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) { | 338 | for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) |
333 | if (sysfs_type(sd)) { | 339 | if (sysfs_type(sd) && !strcmp(sd->s_name, name)) |
334 | if (strcmp(sd->s_name, new)) | 340 | return sd; |
335 | continue; | 341 | return NULL; |
336 | else | 342 | } |
337 | return -EEXIST; | ||
338 | } | ||
339 | } | ||
340 | 343 | ||
341 | return 0; | 344 | /** |
345 | * sysfs_get_dirent - find and get sysfs_dirent with the given name | ||
346 | * @parent_sd: sysfs_dirent to search under | ||
347 | * @name: name to look for | ||
348 | * | ||
349 | * Look for sysfs_dirent with name @name under @parent_sd and get | ||
350 | * it if found. | ||
351 | * | ||
352 | * LOCKING: | ||
353 | * Kernel thread context (may sleep) | ||
354 | * | ||
355 | * RETURNS: | ||
356 | * Pointer to sysfs_dirent if found, NULL if not. | ||
357 | */ | ||
358 | struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, | ||
359 | const unsigned char *name) | ||
360 | { | ||
361 | struct sysfs_dirent *sd; | ||
362 | |||
363 | mutex_lock(&parent_sd->s_dentry->d_inode->i_mutex); | ||
364 | sd = sysfs_find_dirent(parent_sd, name); | ||
365 | sysfs_get(sd); | ||
366 | mutex_unlock(&parent_sd->s_dentry->d_inode->i_mutex); | ||
367 | |||
368 | return sd; | ||
342 | } | 369 | } |
343 | 370 | ||
344 | static int create_dir(struct kobject *kobj, struct dentry *parent, | 371 | static int create_dir(struct kobject *kobj, struct dentry *parent, |
@@ -382,7 +409,7 @@ static int create_dir(struct kobject *kobj, struct dentry *parent, | |||
382 | 409 | ||
383 | /* link in */ | 410 | /* link in */ |
384 | error = -EEXIST; | 411 | error = -EEXIST; |
385 | if (sysfs_dirent_exist(parent->d_fsdata, name)) | 412 | if (sysfs_find_dirent(parent->d_fsdata, name)) |
386 | goto out_iput; | 413 | goto out_iput; |
387 | 414 | ||
388 | sysfs_instantiate(dentry, inode); | 415 | sysfs_instantiate(dentry, inode); |