diff options
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r-- | fs/sysfs/dir.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index fe198210bc2d..59734ba1ee60 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/mount.h> | 8 | #include <linux/mount.h> |
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/kobject.h> | 10 | #include <linux/kobject.h> |
11 | #include <linux/namei.h> | ||
11 | #include "sysfs.h" | 12 | #include "sysfs.h" |
12 | 13 | ||
13 | DECLARE_RWSEM(sysfs_rename_sem); | 14 | DECLARE_RWSEM(sysfs_rename_sem); |
@@ -99,20 +100,21 @@ static int create_dir(struct kobject * k, struct dentry * p, | |||
99 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; | 100 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; |
100 | 101 | ||
101 | down(&p->d_inode->i_sem); | 102 | down(&p->d_inode->i_sem); |
102 | *d = sysfs_get_dentry(p,n); | 103 | *d = lookup_one_len(n, p, strlen(n)); |
103 | if (!IS_ERR(*d)) { | 104 | if (!IS_ERR(*d)) { |
104 | error = sysfs_create(*d, mode, init_dir); | 105 | error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR); |
105 | if (!error) { | 106 | if (!error) { |
106 | error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, | 107 | error = sysfs_create(*d, mode, init_dir); |
107 | SYSFS_DIR); | ||
108 | if (!error) { | 108 | if (!error) { |
109 | p->d_inode->i_nlink++; | 109 | p->d_inode->i_nlink++; |
110 | (*d)->d_op = &sysfs_dentry_ops; | 110 | (*d)->d_op = &sysfs_dentry_ops; |
111 | d_rehash(*d); | 111 | d_rehash(*d); |
112 | } | 112 | } |
113 | } | 113 | } |
114 | if (error && (error != -EEXIST)) | 114 | if (error && (error != -EEXIST)) { |
115 | sysfs_put((*d)->d_fsdata); | ||
115 | d_drop(*d); | 116 | d_drop(*d); |
117 | } | ||
116 | dput(*d); | 118 | dput(*d); |
117 | } else | 119 | } else |
118 | error = PTR_ERR(*d); | 120 | error = PTR_ERR(*d); |
@@ -171,17 +173,19 @@ static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry) | |||
171 | init = init_file; | 173 | init = init_file; |
172 | } | 174 | } |
173 | 175 | ||
176 | dentry->d_fsdata = sysfs_get(sd); | ||
177 | sd->s_dentry = dentry; | ||
174 | error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init); | 178 | error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init); |
175 | if (error) | 179 | if (error) { |
180 | sysfs_put(sd); | ||
176 | return error; | 181 | return error; |
182 | } | ||
177 | 183 | ||
178 | if (bin_attr) { | 184 | if (bin_attr) { |
179 | dentry->d_inode->i_size = bin_attr->size; | 185 | dentry->d_inode->i_size = bin_attr->size; |
180 | dentry->d_inode->i_fop = &bin_fops; | 186 | dentry->d_inode->i_fop = &bin_fops; |
181 | } | 187 | } |
182 | dentry->d_op = &sysfs_dentry_ops; | 188 | dentry->d_op = &sysfs_dentry_ops; |
183 | dentry->d_fsdata = sysfs_get(sd); | ||
184 | sd->s_dentry = dentry; | ||
185 | d_rehash(dentry); | 189 | d_rehash(dentry); |
186 | 190 | ||
187 | return 0; | 191 | return 0; |
@@ -191,13 +195,15 @@ static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry) | |||
191 | { | 195 | { |
192 | int err = 0; | 196 | int err = 0; |
193 | 197 | ||
198 | dentry->d_fsdata = sysfs_get(sd); | ||
199 | sd->s_dentry = dentry; | ||
194 | err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink); | 200 | err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink); |
195 | if (!err) { | 201 | if (!err) { |
196 | dentry->d_op = &sysfs_dentry_ops; | 202 | dentry->d_op = &sysfs_dentry_ops; |
197 | dentry->d_fsdata = sysfs_get(sd); | ||
198 | sd->s_dentry = dentry; | ||
199 | d_rehash(dentry); | 203 | d_rehash(dentry); |
200 | } | 204 | } else |
205 | sysfs_put(sd); | ||
206 | |||
201 | return err; | 207 | return err; |
202 | } | 208 | } |
203 | 209 | ||
@@ -228,6 +234,7 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | |||
228 | 234 | ||
229 | struct inode_operations sysfs_dir_inode_operations = { | 235 | struct inode_operations sysfs_dir_inode_operations = { |
230 | .lookup = sysfs_lookup, | 236 | .lookup = sysfs_lookup, |
237 | .setattr = sysfs_setattr, | ||
231 | }; | 238 | }; |
232 | 239 | ||
233 | static void remove_dir(struct dentry * d) | 240 | static void remove_dir(struct dentry * d) |
@@ -309,7 +316,7 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name) | |||
309 | 316 | ||
310 | down(&parent->d_inode->i_sem); | 317 | down(&parent->d_inode->i_sem); |
311 | 318 | ||
312 | new_dentry = sysfs_get_dentry(parent, new_name); | 319 | new_dentry = lookup_one_len(new_name, parent, strlen(new_name)); |
313 | if (!IS_ERR(new_dentry)) { | 320 | if (!IS_ERR(new_dentry)) { |
314 | if (!new_dentry->d_inode) { | 321 | if (!new_dentry->d_inode) { |
315 | error = kobject_set_name(kobj, "%s", new_name); | 322 | error = kobject_set_name(kobj, "%s", new_name); |