aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/sysfs/dir.c61
-rw-r--r--fs/sysfs/file.c2
-rw-r--r--fs/sysfs/symlink.c2
-rw-r--r--fs/sysfs/sysfs.h5
4 files changed, 50 insertions, 20 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 */
327int sysfs_dirent_exist(struct sysfs_dirent *parent_sd, 333struct 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 */
358struct 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
344static int create_dir(struct kobject *kobj, struct dentry *parent, 371static 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);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index a84b734f7b29..e448b88e313e 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -421,7 +421,7 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
421 421
422 mutex_lock(&dir->d_inode->i_mutex); 422 mutex_lock(&dir->d_inode->i_mutex);
423 423
424 if (sysfs_dirent_exist(parent_sd, attr->name)) { 424 if (sysfs_find_dirent(parent_sd, attr->name)) {
425 error = -EEXIST; 425 error = -EEXIST;
426 goto out_unlock; 426 goto out_unlock;
427 } 427 }
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index ff605d3f4d33..45b62e229627 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -95,7 +95,7 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
95 return -ENOENT; 95 return -ENOENT;
96 96
97 mutex_lock(&dentry->d_inode->i_mutex); 97 mutex_lock(&dentry->d_inode->i_mutex);
98 if (!sysfs_dirent_exist(dentry->d_fsdata, name)) 98 if (!sysfs_find_dirent(dentry->d_fsdata, name))
99 error = sysfs_add_link(parent_sd, name, target_sd); 99 error = sysfs_add_link(parent_sd, name, target_sd);
100 mutex_unlock(&dentry->d_inode->i_mutex); 100 mutex_unlock(&dentry->d_inode->i_mutex);
101 101
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 06b5085804a1..f1629b4520aa 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -59,7 +59,10 @@ extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd);
59extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode); 59extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode);
60 60
61extern void release_sysfs_dirent(struct sysfs_dirent * sd); 61extern void release_sysfs_dirent(struct sysfs_dirent * sd);
62extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *); 62extern struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
63 const unsigned char *name);
64extern struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
65 const unsigned char *name);
63extern struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, 66extern struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode,
64 int type); 67 int type);
65extern void sysfs_attach_dirent(struct sysfs_dirent *sd, 68extern void sysfs_attach_dirent(struct sysfs_dirent *sd,