[PATCH 05/14] sysfs: consolidate sysfs_dirent creation functions

Tejun Heo
2007-04-07T08:25:27Z

Currently there are four functions to create sysfs_dirent -
__sysfs_new_dirent(), sysfs_new_dirent(), __sysfs_make_dirent() and
sysfs_make_dirent(). Other than sysfs_make_dirent(), no function has
two users if calls to implement other functions are excluded.

This patch consolidates sysfs_dirent creation functions into the
following two.

* sysfs_new_dirent() : allocate and initialize
* sysfs_attach_dirent() : attach to sysfs_dirent hierarchy and/or
associate with dentry

This simplifies interface and gives callers more flexibility. This is
in preparation of object reference simplification.

Signed-off-by: Tejun Heo <htejun@gmail.com>
---
fs/sysfs/dir.c | 82 ++++++++++++++++------------------------------------
fs/sysfs/file.c | 21 ++++++++++---
fs/sysfs/symlink.c | 7 ++--
fs/sysfs/sysfs.h | 7 +++-
4 files changed, 50 insertions(+), 67 deletions(-)

diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 99a0ba1..653c23c 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -60,10 +60,7 @@ static struct dentry_operations sysfs_dentry_ops = {
.d_iput = sysfs_d_iput,
};

-/*
- * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent
- */
-static struct sysfs_dirent * __sysfs_new_dirent(void * element)
+struct sysfs_dirent *sysfs_new_dirent(void *element, umode_t mode, int type)
{
struct sysfs_dirent * sd;

@@ -75,25 +72,25 @@ static struct sysfs_dirent * __sysfs_new_dirent(void * element)
atomic_set(&sd->s_event, 1);
INIT_LIST_HEAD(&sd->s_children);
INIT_LIST_HEAD(&sd->s_sibling);
+
sd->s_element = element;
+ sd->s_mode = mode;
+ sd->s_type = type;

return sd;
}

-static void __sysfs_list_dirent(struct sysfs_dirent *parent_sd,
- struct sysfs_dirent *sd)
+void sysfs_attach_dirent(struct sysfs_dirent *sd,
+ struct sysfs_dirent *parent_sd, struct dentry *dentry)
{
- if (sd)
- list_add(&sd->s_sibling, &parent_sd->s_children);
-}
+ if (dentry) {
+ sd->s_dentry = dentry;
+ dentry->d_fsdata = sysfs_get(sd);
+ dentry->d_op = &sysfs_dentry_ops;
+ }

-static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent *parent_sd,
- void * element)
-{
- struct sysfs_dirent *sd;
- sd = __sysfs_new_dirent(element);
- __sysfs_list_dirent(parent_sd, sd);
- return sd;
+ if (parent_sd)
+ list_add(&sd->s_sibling, &parent_sd->s_children);
}

/*
@@ -121,39 +118,6 @@ int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
return 0;
}

-
-static struct sysfs_dirent *
-__sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type)
-{
- struct sysfs_dirent * sd;
-
- sd = __sysfs_new_dirent(element);
- if (!sd)
- goto out;
-
- sd->s_mode = mode;
- sd->s_type = type;
- sd->s_dentry = dentry;
- if (dentry) {
- dentry->d_fsdata = sysfs_get(sd);
- dentry->d_op = &sysfs_dentry_ops;
- }
-
-out:
- return sd;
-}
-
-int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
- void * element, umode_t mode, int type)
-{
- struct sysfs_dirent *sd;
-
- sd = __sysfs_make_dirent(dentry, element, mode, type);
- __sysfs_list_dirent(parent_sd, sd);
-
- return sd ? 0 : -ENOMEM;
-}
-
static int init_dir(struct inode * inode)
{
inode->i_op = &sysfs_dir_inode_operations;
@@ -197,10 +161,11 @@ static int create_dir(struct kobject *kobj, struct dentry *parent,
if (sysfs_dirent_exist(parent->d_fsdata, name))
goto out_dput;

- error = sysfs_make_dirent(parent->d_fsdata, dentry, kobj, mode,
- SYSFS_DIR);
- if (error)
+ error = -ENOMEM;
+ sd = sysfs_new_dirent(kobj, mode, SYSFS_DIR);
+ if (!sd)
goto out_drop;
+ sysfs_attach_dirent(sd, parent->d_fsdata, dentry);

error = sysfs_create(dentry, mode, init_dir);
if (error)
@@ -215,7 +180,6 @@ static int create_dir(struct kobject *kobj, struct dentry *parent,
goto out_dput;

out_sput:
- sd = dentry->d_fsdata;
list_del_init(&sd->s_sibling);
sysfs_put(sd);
out_drop:
@@ -512,13 +476,16 @@ static int sysfs_dir_open(struct inode *inode, struct file *file)
{
struct dentry * dentry = file->f_path.dentry;
struct sysfs_dirent * parent_sd = dentry->d_fsdata;
+ struct sysfs_dirent * sd;

mutex_lock(&dentry->d_inode->i_mutex);
- file->private_data = sysfs_new_dirent(parent_sd, NULL);
+ sd = sysfs_new_dirent(NULL, 0, 0);
+ if (sd)
+ sysfs_attach_dirent(sd, parent_sd, NULL);
mutex_unlock(&dentry->d_inode->i_mutex);

- return file->private_data ? 0 : -ENOMEM;
-
+ file->private_data = sd;
+ return sd ? 0 : -ENOMEM;
}

static int sysfs_dir_close(struct inode *inode, struct file *file)
@@ -691,9 +658,10 @@ struct dentry *sysfs_create_shadow_dir(struct kobject *kobj)
if (!shadow)
goto nomem;

- sd = __sysfs_make_dirent(shadow, kobj, inode->i_mode, SYSFS_DIR);
+ sd = sysfs_new_dirent(kobj, inode->i_mode, SYSFS_DIR);
if (!sd)
goto nomem;
+ sysfs_attach_dirent(sd, NULL, shadow);

d_instantiate(shadow, igrab(inode));
inc_nlink(inode);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index fc46333..f6b86a8 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -474,14 +474,25 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
{
struct sysfs_dirent * parent_sd = dir->d_fsdata;
umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;
- int error = -EEXIST;
+ struct sysfs_dirent *sd;
+ int error = 0;

mutex_lock(&dir->d_inode->i_mutex);
- if (!sysfs_dirent_exist(parent_sd, attr->name))
- error = sysfs_make_dirent(parent_sd, NULL, (void *)attr,
- mode, type);
- mutex_unlock(&dir->d_inode->i_mutex);

+ if (sysfs_dirent_exist(parent_sd, attr->name)) {
+ error = -EEXIST;
+ goto out_unlock;
+ }
+
+ sd = sysfs_new_dirent((void *)attr, mode, type);
+ if (!sd) {
+ error = -ENOMEM;
+ goto out_unlock;
+ }
+ sysfs_attach_dirent(sd, parent_sd, NULL);
+
+ out_unlock:
+ mutex_unlock(&dir->d_inode->i_mutex);
return error;
}

diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index b463f17..d96bb9c 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -49,6 +49,7 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj
{
struct sysfs_dirent * parent_sd = parent->d_fsdata;
struct sysfs_symlink * sl;
+ struct sysfs_dirent * sd;
int error;

error = -ENOMEM;
@@ -63,10 +64,10 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj
strcpy(sl->link_name, name);
sl->target_kobj = kobject_get(target);

- error = sysfs_make_dirent(parent_sd, NULL, sl, S_IFLNK|S_IRWXUGO,
- SYSFS_KOBJ_LINK);
- if (error)
+ sd = sysfs_new_dirent(sl, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
+ if (!sd)
goto err_out;
+ sysfs_attach_dirent(sd, parent_sd, NULL);

return 0;

diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 812c8c3..104649c 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -20,8 +20,11 @@ extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
extern struct kobject *sysfs_get_kobject(struct dentry *dentry);
extern void release_sysfs_dirent(struct sysfs_dirent * sd);
extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
-extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
- umode_t, int);
+extern struct sysfs_dirent *sysfs_new_dirent(void *element, umode_t mode,
+ int type);
+extern void sysfs_attach_dirent(struct sysfs_dirent *sd,
+ struct sysfs_dirent *parent_sd,
+ struct dentry *dentry);

extern int sysfs_add_file(struct dentry *, const struct attribute *, int);
extern int sysfs_hash_and_remove(struct dentry * dir, const char * name);
--
1.5.0.3