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: Tejun Heo <htejun@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 6e8d6f5..0791226 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -52,11 +52,8 @@
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 @@
.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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);