| From htejun@gmail.com Sun Apr 8 21:18:59 2007 |
| From: Tejun Heo <htejun@gmail.com> |
| Date: Mon, 9 Apr 2007 13:18:47 +0900 |
| Subject: sysfs: consolidate sysfs_dirent creation functions |
| To: gregkh@suse.de, maneesh@in.ibm.com, dmitry.torokhov@gmail.com, cornelia.huck@de.ibm.com, oneukum@suse.de, rpurdie@rpsys.net, James.Bottomley@SteelEye.com, stern@rowland.harvard.edu, linux-kernel@vger.kernel.org, htejun@gmail.com |
| Cc: Tejun Heo <htejun@gmail.com> |
| Message-ID: <1176092327668-git-send-email-htejun@gmail.com> |
| |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| 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(-) |
| |
| --- a/fs/sysfs/dir.c |
| +++ b/fs/sysfs/dir.c |
| @@ -42,10 +42,7 @@ static struct dentry_operations sysfs_de |
| .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; |
| |
| @@ -57,25 +54,25 @@ static struct sysfs_dirent * __sysfs_new |
| 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); |
| } |
| |
| /* |
| @@ -103,39 +100,6 @@ int sysfs_dirent_exist(struct sysfs_dire |
| 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; |
| @@ -179,10 +143,11 @@ static int create_dir(struct kobject *ko |
| 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) |
| @@ -197,7 +162,6 @@ static int create_dir(struct kobject *ko |
| goto out_dput; |
| |
| out_sput: |
| - sd = dentry->d_fsdata; |
| list_del_init(&sd->s_sibling); |
| sysfs_put(sd); |
| out_drop: |
| @@ -494,13 +458,16 @@ static int sysfs_dir_open(struct inode * |
| { |
| 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) |
| @@ -673,9 +640,10 @@ struct dentry *sysfs_create_shadow_dir(s |
| 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); |
| --- a/fs/sysfs/file.c |
| +++ b/fs/sysfs/file.c |
| @@ -474,14 +474,25 @@ int sysfs_add_file(struct dentry * dir, |
| { |
| 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; |
| } |
| |
| --- a/fs/sysfs/symlink.c |
| +++ b/fs/sysfs/symlink.c |
| @@ -49,6 +49,7 @@ static int sysfs_add_link(struct dentry |
| { |
| 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 |
| 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; |
| |
| --- a/fs/sysfs/sysfs.h |
| +++ b/fs/sysfs/sysfs.h |
| @@ -19,8 +19,11 @@ extern int sysfs_create(struct 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); |