Commit a26cd722 authored by Tejun Heo's avatar Tejun Heo Committed by Greg Kroah-Hartman

sysfs: consolidate sysfs_dirent creation functions

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: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 996b7376
...@@ -85,10 +85,7 @@ static struct dentry_operations sysfs_dentry_ops = { ...@@ -85,10 +85,7 @@ static struct dentry_operations sysfs_dentry_ops = {
.d_iput = sysfs_d_iput, .d_iput = sysfs_d_iput,
}; };
/* struct sysfs_dirent *sysfs_new_dirent(void *element, umode_t mode, int type)
* 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 * sd; struct sysfs_dirent * sd;
...@@ -105,25 +102,25 @@ static struct sysfs_dirent * __sysfs_new_dirent(void * element) ...@@ -105,25 +102,25 @@ static struct sysfs_dirent * __sysfs_new_dirent(void * element)
atomic_set(&sd->s_event, 1); atomic_set(&sd->s_event, 1);
INIT_LIST_HEAD(&sd->s_children); INIT_LIST_HEAD(&sd->s_children);
INIT_LIST_HEAD(&sd->s_sibling); INIT_LIST_HEAD(&sd->s_sibling);
sd->s_element = element; sd->s_element = element;
sd->s_mode = mode;
sd->s_type = type;
return sd; return sd;
} }
static void __sysfs_list_dirent(struct sysfs_dirent *parent_sd, void sysfs_attach_dirent(struct sysfs_dirent *sd,
struct sysfs_dirent *sd) struct sysfs_dirent *parent_sd, struct dentry *dentry)
{ {
if (sd) if (dentry) {
list_add(&sd->s_sibling, &parent_sd->s_children); 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, if (parent_sd)
void * element) list_add(&sd->s_sibling, &parent_sd->s_children);
{
struct sysfs_dirent *sd;
sd = __sysfs_new_dirent(element);
__sysfs_list_dirent(parent_sd, sd);
return sd;
} }
/* /*
...@@ -151,39 +148,6 @@ int sysfs_dirent_exist(struct sysfs_dirent *parent_sd, ...@@ -151,39 +148,6 @@ int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
return 0; 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) static int init_dir(struct inode * inode)
{ {
inode->i_op = &sysfs_dir_inode_operations; inode->i_op = &sysfs_dir_inode_operations;
...@@ -227,10 +191,11 @@ static int create_dir(struct kobject *kobj, struct dentry *parent, ...@@ -227,10 +191,11 @@ static int create_dir(struct kobject *kobj, struct dentry *parent,
if (sysfs_dirent_exist(parent->d_fsdata, name)) if (sysfs_dirent_exist(parent->d_fsdata, name))
goto out_dput; goto out_dput;
error = sysfs_make_dirent(parent->d_fsdata, dentry, kobj, mode, error = -ENOMEM;
SYSFS_DIR); sd = sysfs_new_dirent(kobj, mode, SYSFS_DIR);
if (error) if (!sd)
goto out_drop; goto out_drop;
sysfs_attach_dirent(sd, parent->d_fsdata, dentry);
error = sysfs_create(dentry, mode, init_dir); error = sysfs_create(dentry, mode, init_dir);
if (error) if (error)
...@@ -245,7 +210,6 @@ static int create_dir(struct kobject *kobj, struct dentry *parent, ...@@ -245,7 +210,6 @@ static int create_dir(struct kobject *kobj, struct dentry *parent,
goto out_dput; goto out_dput;
out_sput: out_sput:
sd = dentry->d_fsdata;
list_del_init(&sd->s_sibling); list_del_init(&sd->s_sibling);
sysfs_put(sd); sysfs_put(sd);
out_drop: out_drop:
...@@ -557,13 +521,16 @@ static int sysfs_dir_open(struct inode *inode, struct file *file) ...@@ -557,13 +521,16 @@ static int sysfs_dir_open(struct inode *inode, struct file *file)
{ {
struct dentry * dentry = file->f_path.dentry; struct dentry * dentry = file->f_path.dentry;
struct sysfs_dirent * parent_sd = dentry->d_fsdata; struct sysfs_dirent * parent_sd = dentry->d_fsdata;
struct sysfs_dirent * sd;
mutex_lock(&dentry->d_inode->i_mutex); 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); 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) static int sysfs_dir_close(struct inode *inode, struct file *file)
...@@ -736,9 +703,10 @@ struct dentry *sysfs_create_shadow_dir(struct kobject *kobj) ...@@ -736,9 +703,10 @@ struct dentry *sysfs_create_shadow_dir(struct kobject *kobj)
if (!shadow) if (!shadow)
goto nomem; 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) if (!sd)
goto nomem; goto nomem;
sysfs_attach_dirent(sd, NULL, shadow);
d_instantiate(shadow, igrab(inode)); d_instantiate(shadow, igrab(inode));
inc_nlink(inode); inc_nlink(inode);
......
...@@ -444,14 +444,25 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type) ...@@ -444,14 +444,25 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
{ {
struct sysfs_dirent * parent_sd = dir->d_fsdata; struct sysfs_dirent * parent_sd = dir->d_fsdata;
umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG; 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); 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; return error;
} }
......
...@@ -49,6 +49,7 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj ...@@ -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_dirent * parent_sd = parent->d_fsdata;
struct sysfs_symlink * sl; struct sysfs_symlink * sl;
struct sysfs_dirent * sd;
int error; int error;
error = -ENOMEM; error = -ENOMEM;
...@@ -63,10 +64,10 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj ...@@ -63,10 +64,10 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj
strcpy(sl->link_name, name); strcpy(sl->link_name, name);
sl->target_kobj = kobject_get(target); sl->target_kobj = kobject_get(target);
error = sysfs_make_dirent(parent_sd, NULL, sl, S_IFLNK|S_IRWXUGO, sd = sysfs_new_dirent(sl, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
SYSFS_KOBJ_LINK); if (!sd)
if (error)
goto err_out; goto err_out;
sysfs_attach_dirent(sd, parent_sd, NULL);
return 0; return 0;
......
...@@ -20,8 +20,11 @@ extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); ...@@ -20,8 +20,11 @@ extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
extern void release_sysfs_dirent(struct sysfs_dirent * sd); extern void release_sysfs_dirent(struct sysfs_dirent * sd);
extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *); extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, extern struct sysfs_dirent *sysfs_new_dirent(void *element, umode_t mode,
umode_t, int); 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_add_file(struct dentry *, const struct attribute *, int);
extern int sysfs_hash_and_remove(struct dentry * dir, const char * name); extern int sysfs_hash_and_remove(struct dentry * dir, const char * name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment