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

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

sysfs: make sysfs_dirent->s_element a union



Make sd->s_element a union of sysfs_elem_{dir|symlink|attr|bin_attr}
and rename it to s_elem.  This is to achieve...

* some level of type checking : changing symlink to point to
  sysfs_dirent instead of kobject is much safer and less painful now.
* easier / standardized dereferencing
* allow sysfs_elem_* to contain more than one entry

Where possible, pointer is obtained by directly deferencing from sd
instead of going through other entities.  This reduces dependencies to
dentry, inode and kobject.  to_attr() and to_bin_attr() are unused now
and removed.

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 0c096b50
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@
static int
fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count)
{
	struct bin_attribute * attr = to_bin_attr(dentry);
	struct sysfs_dirent *attr_sd = dentry->d_fsdata;
	struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
	struct kobject * kobj = to_kobj(dentry->d_parent);

	if (!attr->read)
@@ -65,7 +66,8 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
static int
flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count)
{
	struct bin_attribute *attr = to_bin_attr(dentry);
	struct sysfs_dirent *attr_sd = dentry->d_fsdata;
	struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
	struct kobject *kobj = to_kobj(dentry->d_parent);

	if (!attr->write)
@@ -101,9 +103,9 @@ static ssize_t write(struct file *file, const char __user *userbuf,

static int mmap(struct file *file, struct vm_area_struct *vma)
{
	struct dentry *dentry = file->f_path.dentry;
	struct bin_attribute *attr = to_bin_attr(dentry);
	struct kobject *kobj = to_kobj(dentry->d_parent);
	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
	struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
	struct kobject *kobj = to_kobj(file->f_path.dentry->d_parent);

	if (!attr->mmap)
		return -EINVAL;
@@ -114,7 +116,8 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
static int open(struct inode * inode, struct file * file)
{
	struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent);
	struct bin_attribute * attr = to_bin_attr(file->f_path.dentry);
	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
	struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
	int error = -EINVAL;

	if (!kobj || !attr)
@@ -150,7 +153,8 @@ static int open(struct inode * inode, struct file * file)
static int release(struct inode * inode, struct file * file)
{
	struct kobject * kobj = to_kobj(file->f_path.dentry->d_parent);
	struct bin_attribute * attr = to_bin_attr(file->f_path.dentry);
	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
	struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
	u8 * buffer = file->private_data;

	kobject_put(kobj);
+14 −17
Original line number Diff line number Diff line
@@ -52,11 +52,8 @@ void release_sysfs_dirent(struct sysfs_dirent * sd)
 repeat:
	parent_sd = sd->s_parent;

	if (sd->s_type & SYSFS_KOBJ_LINK) {
		struct sysfs_symlink * sl = sd->s_element;
		kobject_put(sl->target_kobj);
		kfree(sl);
	}
	if (sd->s_type & SYSFS_KOBJ_LINK)
		kobject_put(sd->s_elem.symlink.target_kobj);
	if (sd->s_type & SYSFS_COPY_NAME)
		kfree(sd->s_name);
	kfree(sd->s_iattr);
@@ -95,8 +92,7 @@ static struct dentry_operations sysfs_dentry_ops = {
	.d_iput		= sysfs_d_iput,
};

struct sysfs_dirent *sysfs_new_dirent(const char *name, void *element,
				      umode_t mode, int type)
struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
{
	char *dup_name = NULL;
	struct sysfs_dirent *sd = NULL;
@@ -120,7 +116,6 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, void *element,
	INIT_LIST_HEAD(&sd->s_sibling);

	sd->s_name = name;
	sd->s_element = element;
	sd->s_mode = mode;
	sd->s_type = type;

@@ -160,7 +155,7 @@ int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
	struct sysfs_dirent * sd;

	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
		if (sd->s_element) {
		if (sd->s_type) {
			if (strcmp(sd->s_name, new))
				continue;
			else
@@ -215,9 +210,10 @@ static int create_dir(struct kobject *kobj, struct dentry *parent,
		goto out_dput;

	error = -ENOMEM;
	sd = sysfs_new_dirent(name, kobj, mode, SYSFS_DIR);
	sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
	if (!sd)
		goto out_drop;
	sd->s_elem.dir.kobj = kobj;
	sysfs_attach_dirent(sd, parent->d_fsdata, dentry);

	error = sysfs_create(dentry, mode, init_dir);
@@ -290,10 +286,10 @@ static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry)
	int error = 0;

        if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) {
                bin_attr = sd->s_element;
                bin_attr = sd->s_elem.bin_attr.bin_attr;
                attr = &bin_attr->attr;
        } else {
                attr = sd->s_element;
                attr = sd->s_elem.attr.attr;
                init = init_file;
        }

@@ -404,7 +400,7 @@ static void __sysfs_remove_dir(struct dentry *dentry)
	mutex_lock(&dentry->d_inode->i_mutex);
	parent_sd = dentry->d_fsdata;
	list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
		if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED))
		if (!sd->s_type || !(sd->s_type & SYSFS_NOT_PINNED))
			continue;
		list_del_init(&sd->s_sibling);
		sysfs_drop_dentry(sd, dentry);
@@ -556,7 +552,7 @@ static int sysfs_dir_open(struct inode *inode, struct file *file)
	struct sysfs_dirent * sd;

	mutex_lock(&dentry->d_inode->i_mutex);
	sd = sysfs_new_dirent("_DIR_", NULL, 0, 0);
	sd = sysfs_new_dirent("_DIR_", 0, 0);
	if (sd)
		sysfs_attach_dirent(sd, parent_sd, NULL);
	mutex_unlock(&dentry->d_inode->i_mutex);
@@ -623,7 +619,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)

				next = list_entry(p, struct sysfs_dirent,
						   s_sibling);
				if (!next->s_element)
				if (!next->s_type)
					continue;

				name = next->s_name;
@@ -671,7 +667,7 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
				struct sysfs_dirent *next;
				next = list_entry(p, struct sysfs_dirent,
						   s_sibling);
				if (next->s_element)
				if (next->s_type)
					n--;
				p = p->next;
			}
@@ -738,9 +734,10 @@ struct dentry *sysfs_create_shadow_dir(struct kobject *kobj)
	if (!shadow)
		goto nomem;

	sd = sysfs_new_dirent("_SHADOW_", kobj, inode->i_mode, SYSFS_DIR);
	sd = sysfs_new_dirent("_SHADOW_", inode->i_mode, SYSFS_DIR);
	if (!sd)
		goto nomem;
	sd->s_elem.dir.kobj = kobj;
	/* point to parent_sd but don't attach to it */
	sd->s_parent = sysfs_get(parent_sd);
	sysfs_attach_dirent(sd, NULL, shadow);
+10 −9
Original line number Diff line number Diff line
@@ -88,7 +88,6 @@ remove_from_collection(struct sysfs_buffer *buffer, struct inode *node)
static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer)
{
	struct sysfs_dirent * sd = dentry->d_fsdata;
	struct attribute * attr = to_attr(dentry);
	struct kobject * kobj = to_kobj(dentry->d_parent);
	struct sysfs_ops * ops = buffer->ops;
	int ret = 0;
@@ -100,7 +99,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
		return -ENOMEM;

	buffer->event = atomic_read(&sd->s_event);
	count = ops->show(kobj,attr,buffer->page);
	count = ops->show(kobj, sd->s_elem.attr.attr, buffer->page);
	BUG_ON(count > (ssize_t)PAGE_SIZE);
	if (count >= 0) {
		buffer->needs_read_fill = 0;
@@ -199,11 +198,11 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t
static int 
flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t count)
{
	struct attribute * attr = to_attr(dentry);
	struct sysfs_dirent *attr_sd = dentry->d_fsdata;
	struct kobject * kobj = to_kobj(dentry->d_parent);
	struct sysfs_ops * ops = buffer->ops;

	return ops->store(kobj,attr,buffer->page,count);
	return ops->store(kobj, attr_sd->s_elem.attr.attr, buffer->page, count);
}


@@ -248,7 +247,8 @@ out:
static int sysfs_open_file(struct inode *inode, struct file *file)
{
	struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent);
	struct attribute * attr = to_attr(file->f_path.dentry);
	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
	struct attribute *attr = attr_sd->s_elem.attr.attr;
	struct sysfs_buffer_collection *set;
	struct sysfs_buffer * buffer;
	struct sysfs_ops * ops = NULL;
@@ -341,15 +341,15 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
static int sysfs_release(struct inode * inode, struct file * filp)
{
	struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent);
	struct attribute * attr = to_attr(filp->f_path.dentry);
	struct module * owner = attr->owner;
	struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
	struct attribute *attr = attr_sd->s_elem.attr.attr;
	struct sysfs_buffer * buffer = filp->private_data;

	if (buffer)
		remove_from_collection(buffer, inode);
	kobject_put(kobj);
	/* After this point, attr should not be accessed. */
	module_put(owner);
	module_put(attr->owner);

	if (buffer) {
		if (buffer->page)
@@ -454,11 +454,12 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
		goto out_unlock;
	}

	sd = sysfs_new_dirent(attr->name, (void *)attr, mode, type);
	sd = sysfs_new_dirent(attr->name, mode, type);
	if (!sd) {
		error = -ENOMEM;
		goto out_unlock;
	}
	sd->s_elem.attr.attr = (void *)attr;
	sysfs_attach_dirent(sd, parent_sd, NULL);

 out_unlock:
+1 −1
Original line number Diff line number Diff line
@@ -272,7 +272,7 @@ int sysfs_hash_and_remove(struct dentry * dir, const char * name)
	parent_sd = dir->d_fsdata;
	mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
		if (!sd->s_element)
		if (!sd->s_type)
			continue;
		if (!strcmp(sd->s_name, name)) {
			list_del_init(&sd->s_sibling);
+0 −1
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ static struct sysfs_dirent sysfs_root = {
	.s_count	= ATOMIC_INIT(1),
	.s_sibling	= LIST_HEAD_INIT(sysfs_root.s_sibling),
	.s_children	= LIST_HEAD_INIT(sysfs_root.s_children),
	.s_element	= NULL,
	.s_type		= SYSFS_ROOT,
	.s_iattr	= NULL,
	.s_ino		= 1,
Loading