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: Tejun Heo <htejun@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
996b73764e
commit
a26cd7226c
@@ -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,27 +102,27 @@ 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) {
|
||||||
|
sd->s_dentry = dentry;
|
||||||
|
dentry->d_fsdata = sysfs_get(sd);
|
||||||
|
dentry->d_op = &sysfs_dentry_ops;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent_sd)
|
||||||
list_add(&sd->s_sibling, &parent_sd->s_children);
|
list_add(&sd->s_sibling, &parent_sd->s_children);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Return -EEXIST if there is already a sysfs element with the same name for
|
* Return -EEXIST if there is already a sysfs element with the same name for
|
||||||
@@ -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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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
|
|||||||
{
|
{
|
||||||
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
|
|||||||
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 *));
|
|||||||
|
|
||||||
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);
|
||||||
|
Reference in New Issue
Block a user