Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+25 −57
Original line number Diff line number Diff line
@@ -85,10 +85,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;

@@ -105,25 +102,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);
}

/*
@@ -151,39 +148,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;
@@ -227,10 +191,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)
@@ -245,7 +210,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:
@@ -557,13 +521,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)
@@ -736,9 +703,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);
+16 −5
Original line number Diff line number Diff line
@@ -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;
	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;
}

+4 −3
Original line number Diff line number Diff line
@@ -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;

+5 −2
Original line number Diff line number Diff line
@@ -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 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);