aboutsummaryrefslogtreecommitdiff
path: root/fs/sysfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs')
-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 f2ea00683ec..4762a9aa0b2 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -317,28 +317,55 @@ void sysfs_attach_dirent(struct sysfs_dirent *sd,
}
}
-/*
+/**
+ * sysfs_find_dirent - find sysfs_dirent with the given name
+ * @parent_sd: sysfs_dirent to search under
+ * @name: name to look for
*
- * Return -EEXIST if there is already a sysfs element with the same name for
- * the same parent.
+ * Look for sysfs_dirent with name @name under @parent_sd.
*
- * called with parent inode's i_mutex held
+ * LOCKING:
+ * mutex_lock(parent->i_mutex)
+ *
+ * RETURNS:
+ * Pointer to sysfs_dirent if found, NULL if not.
*/
-int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
- const unsigned char *new)
+struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
+ const unsigned char *name)
{
- struct sysfs_dirent * sd;
+ struct sysfs_dirent *sd;
- for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) {
- if (sysfs_type(sd)) {
- if (strcmp(sd->s_name, new))
- continue;
- else
- return -EEXIST;
- }
- }
+ for (sd = parent_sd->s_children; sd; sd = sd->s_sibling)
+ if (sysfs_type(sd) && !strcmp(sd->s_name, name))
+ return sd;
+ return NULL;
+}
- return 0;
+/**
+ * sysfs_get_dirent - find and get sysfs_dirent with the given name
+ * @parent_sd: sysfs_dirent to search under
+ * @name: name to look for
+ *
+ * Look for sysfs_dirent with name @name under @parent_sd and get
+ * it if found.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * Pointer to sysfs_dirent if found, NULL if not.
+ */
+struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+ const unsigned char *name)
+{
+ struct sysfs_dirent *sd;
+
+ mutex_lock(&parent_sd->s_dentry->d_inode->i_mutex);
+ sd = sysfs_find_dirent(parent_sd, name);
+ sysfs_get(sd);
+ mutex_unlock(&parent_sd->s_dentry->d_inode->i_mutex);
+
+ return sd;
}
static int create_dir(struct kobject *kobj, struct dentry *parent,
@@ -382,7 +409,7 @@ static int create_dir(struct kobject *kobj, struct dentry *parent,
/* link in */
error = -EEXIST;
- if (sysfs_dirent_exist(parent->d_fsdata, name))
+ if (sysfs_find_dirent(parent->d_fsdata, name))
goto out_iput;
sysfs_instantiate(dentry, inode);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index a84b734f7b2..e448b88e313 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)
mutex_lock(&dir->d_inode->i_mutex);
- if (sysfs_dirent_exist(parent_sd, attr->name)) {
+ if (sysfs_find_dirent(parent_sd, attr->name)) {
error = -EEXIST;
goto out_unlock;
}
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index ff605d3f4d3..45b62e22962 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
return -ENOENT;
mutex_lock(&dentry->d_inode->i_mutex);
- if (!sysfs_dirent_exist(dentry->d_fsdata, name))
+ if (!sysfs_find_dirent(dentry->d_fsdata, name))
error = sysfs_add_link(parent_sd, name, target_sd);
mutex_unlock(&dentry->d_inode->i_mutex);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 06b5085804a..f1629b4520a 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);
extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode);
extern void release_sysfs_dirent(struct sysfs_dirent * sd);
-extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
+extern struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
+ const unsigned char *name);
+extern struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+ const unsigned char *name);
extern struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode,
int type);
extern void sysfs_attach_dirent(struct sysfs_dirent *sd,