diff options
author | Tejun Heo <htejun@gmail.com> | 2007-06-13 14:45:15 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-11 19:09:04 -0400 |
commit | 3e5190380ebef77f2b015c9e7a4ca225a3d75021 (patch) | |
tree | 08d17cd0562acf5101063e93c649f5f71f80b3b9 /fs/sysfs/dir.c | |
parent | 0c096b507f15397da890051ee73de4266d3941fb (diff) |
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>
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r-- | fs/sysfs/dir.c | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 6e8d6f54f082..079122695675 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -52,11 +52,8 @@ void release_sysfs_dirent(struct sysfs_dirent * sd) | |||
52 | repeat: | 52 | repeat: |
53 | parent_sd = sd->s_parent; | 53 | parent_sd = sd->s_parent; |
54 | 54 | ||
55 | if (sd->s_type & SYSFS_KOBJ_LINK) { | 55 | if (sd->s_type & SYSFS_KOBJ_LINK) |
56 | struct sysfs_symlink * sl = sd->s_element; | 56 | kobject_put(sd->s_elem.symlink.target_kobj); |
57 | kobject_put(sl->target_kobj); | ||
58 | kfree(sl); | ||
59 | } | ||
60 | if (sd->s_type & SYSFS_COPY_NAME) | 57 | if (sd->s_type & SYSFS_COPY_NAME) |
61 | kfree(sd->s_name); | 58 | kfree(sd->s_name); |
62 | kfree(sd->s_iattr); | 59 | kfree(sd->s_iattr); |
@@ -95,8 +92,7 @@ static struct dentry_operations sysfs_dentry_ops = { | |||
95 | .d_iput = sysfs_d_iput, | 92 | .d_iput = sysfs_d_iput, |
96 | }; | 93 | }; |
97 | 94 | ||
98 | struct sysfs_dirent *sysfs_new_dirent(const char *name, void *element, | 95 | struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) |
99 | umode_t mode, int type) | ||
100 | { | 96 | { |
101 | char *dup_name = NULL; | 97 | char *dup_name = NULL; |
102 | struct sysfs_dirent *sd = NULL; | 98 | struct sysfs_dirent *sd = NULL; |
@@ -120,7 +116,6 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, void *element, | |||
120 | INIT_LIST_HEAD(&sd->s_sibling); | 116 | INIT_LIST_HEAD(&sd->s_sibling); |
121 | 117 | ||
122 | sd->s_name = name; | 118 | sd->s_name = name; |
123 | sd->s_element = element; | ||
124 | sd->s_mode = mode; | 119 | sd->s_mode = mode; |
125 | sd->s_type = type; | 120 | sd->s_type = type; |
126 | 121 | ||
@@ -160,7 +155,7 @@ int sysfs_dirent_exist(struct sysfs_dirent *parent_sd, | |||
160 | struct sysfs_dirent * sd; | 155 | struct sysfs_dirent * sd; |
161 | 156 | ||
162 | list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { | 157 | list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { |
163 | if (sd->s_element) { | 158 | if (sd->s_type) { |
164 | if (strcmp(sd->s_name, new)) | 159 | if (strcmp(sd->s_name, new)) |
165 | continue; | 160 | continue; |
166 | else | 161 | else |
@@ -215,9 +210,10 @@ static int create_dir(struct kobject *kobj, struct dentry *parent, | |||
215 | goto out_dput; | 210 | goto out_dput; |
216 | 211 | ||
217 | error = -ENOMEM; | 212 | error = -ENOMEM; |
218 | sd = sysfs_new_dirent(name, kobj, mode, SYSFS_DIR); | 213 | sd = sysfs_new_dirent(name, mode, SYSFS_DIR); |
219 | if (!sd) | 214 | if (!sd) |
220 | goto out_drop; | 215 | goto out_drop; |
216 | sd->s_elem.dir.kobj = kobj; | ||
221 | sysfs_attach_dirent(sd, parent->d_fsdata, dentry); | 217 | sysfs_attach_dirent(sd, parent->d_fsdata, dentry); |
222 | 218 | ||
223 | error = sysfs_create(dentry, mode, init_dir); | 219 | error = sysfs_create(dentry, mode, init_dir); |
@@ -290,10 +286,10 @@ static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry) | |||
290 | int error = 0; | 286 | int error = 0; |
291 | 287 | ||
292 | if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) { | 288 | if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) { |
293 | bin_attr = sd->s_element; | 289 | bin_attr = sd->s_elem.bin_attr.bin_attr; |
294 | attr = &bin_attr->attr; | 290 | attr = &bin_attr->attr; |
295 | } else { | 291 | } else { |
296 | attr = sd->s_element; | 292 | attr = sd->s_elem.attr.attr; |
297 | init = init_file; | 293 | init = init_file; |
298 | } | 294 | } |
299 | 295 | ||
@@ -404,7 +400,7 @@ static void __sysfs_remove_dir(struct dentry *dentry) | |||
404 | mutex_lock(&dentry->d_inode->i_mutex); | 400 | mutex_lock(&dentry->d_inode->i_mutex); |
405 | parent_sd = dentry->d_fsdata; | 401 | parent_sd = dentry->d_fsdata; |
406 | list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { | 402 | list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { |
407 | if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED)) | 403 | if (!sd->s_type || !(sd->s_type & SYSFS_NOT_PINNED)) |
408 | continue; | 404 | continue; |
409 | list_del_init(&sd->s_sibling); | 405 | list_del_init(&sd->s_sibling); |
410 | sysfs_drop_dentry(sd, dentry); | 406 | sysfs_drop_dentry(sd, dentry); |
@@ -556,7 +552,7 @@ static int sysfs_dir_open(struct inode *inode, struct file *file) | |||
556 | struct sysfs_dirent * sd; | 552 | struct sysfs_dirent * sd; |
557 | 553 | ||
558 | mutex_lock(&dentry->d_inode->i_mutex); | 554 | mutex_lock(&dentry->d_inode->i_mutex); |
559 | sd = sysfs_new_dirent("_DIR_", NULL, 0, 0); | 555 | sd = sysfs_new_dirent("_DIR_", 0, 0); |
560 | if (sd) | 556 | if (sd) |
561 | sysfs_attach_dirent(sd, parent_sd, NULL); | 557 | sysfs_attach_dirent(sd, parent_sd, NULL); |
562 | mutex_unlock(&dentry->d_inode->i_mutex); | 558 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -623,7 +619,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
623 | 619 | ||
624 | next = list_entry(p, struct sysfs_dirent, | 620 | next = list_entry(p, struct sysfs_dirent, |
625 | s_sibling); | 621 | s_sibling); |
626 | if (!next->s_element) | 622 | if (!next->s_type) |
627 | continue; | 623 | continue; |
628 | 624 | ||
629 | name = next->s_name; | 625 | name = next->s_name; |
@@ -671,7 +667,7 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) | |||
671 | struct sysfs_dirent *next; | 667 | struct sysfs_dirent *next; |
672 | next = list_entry(p, struct sysfs_dirent, | 668 | next = list_entry(p, struct sysfs_dirent, |
673 | s_sibling); | 669 | s_sibling); |
674 | if (next->s_element) | 670 | if (next->s_type) |
675 | n--; | 671 | n--; |
676 | p = p->next; | 672 | p = p->next; |
677 | } | 673 | } |
@@ -738,9 +734,10 @@ struct dentry *sysfs_create_shadow_dir(struct kobject *kobj) | |||
738 | if (!shadow) | 734 | if (!shadow) |
739 | goto nomem; | 735 | goto nomem; |
740 | 736 | ||
741 | sd = sysfs_new_dirent("_SHADOW_", kobj, inode->i_mode, SYSFS_DIR); | 737 | sd = sysfs_new_dirent("_SHADOW_", inode->i_mode, SYSFS_DIR); |
742 | if (!sd) | 738 | if (!sd) |
743 | goto nomem; | 739 | goto nomem; |
740 | sd->s_elem.dir.kobj = kobj; | ||
744 | /* point to parent_sd but don't attach to it */ | 741 | /* point to parent_sd but don't attach to it */ |
745 | sd->s_parent = sysfs_get(parent_sd); | 742 | sd->s_parent = sysfs_get(parent_sd); |
746 | sysfs_attach_dirent(sd, NULL, shadow); | 743 | sysfs_attach_dirent(sd, NULL, shadow); |