diff options
Diffstat (limited to 'fs/configfs/dir.c')
-rw-r--r-- | fs/configfs/dir.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index b668ec61527e..ca60e3abef45 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -72,7 +72,7 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare | |||
72 | { | 72 | { |
73 | struct configfs_dirent * sd; | 73 | struct configfs_dirent * sd; |
74 | 74 | ||
75 | sd = kmalloc(sizeof(*sd), GFP_KERNEL); | 75 | sd = kmem_cache_alloc(configfs_dir_cachep, GFP_KERNEL); |
76 | if (!sd) | 76 | if (!sd) |
77 | return NULL; | 77 | return NULL; |
78 | 78 | ||
@@ -136,13 +136,19 @@ static int create_dir(struct config_item * k, struct dentry * p, | |||
136 | int error; | 136 | int error; |
137 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; | 137 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; |
138 | 138 | ||
139 | error = configfs_create(d, mode, init_dir); | 139 | error = configfs_make_dirent(p->d_fsdata, d, k, mode, |
140 | CONFIGFS_DIR); | ||
140 | if (!error) { | 141 | if (!error) { |
141 | error = configfs_make_dirent(p->d_fsdata, d, k, mode, | 142 | error = configfs_create(d, mode, init_dir); |
142 | CONFIGFS_DIR); | ||
143 | if (!error) { | 143 | if (!error) { |
144 | p->d_inode->i_nlink++; | 144 | p->d_inode->i_nlink++; |
145 | (d)->d_op = &configfs_dentry_ops; | 145 | (d)->d_op = &configfs_dentry_ops; |
146 | } else { | ||
147 | struct configfs_dirent *sd = d->d_fsdata; | ||
148 | if (sd) { | ||
149 | list_del_init(&sd->s_sibling); | ||
150 | configfs_put(sd); | ||
151 | } | ||
146 | } | 152 | } |
147 | } | 153 | } |
148 | return error; | 154 | return error; |
@@ -182,12 +188,19 @@ int configfs_create_link(struct configfs_symlink *sl, | |||
182 | int err = 0; | 188 | int err = 0; |
183 | umode_t mode = S_IFLNK | S_IRWXUGO; | 189 | umode_t mode = S_IFLNK | S_IRWXUGO; |
184 | 190 | ||
185 | err = configfs_create(dentry, mode, init_symlink); | 191 | err = configfs_make_dirent(parent->d_fsdata, dentry, sl, mode, |
192 | CONFIGFS_ITEM_LINK); | ||
186 | if (!err) { | 193 | if (!err) { |
187 | err = configfs_make_dirent(parent->d_fsdata, dentry, sl, | 194 | err = configfs_create(dentry, mode, init_symlink); |
188 | mode, CONFIGFS_ITEM_LINK); | ||
189 | if (!err) | 195 | if (!err) |
190 | dentry->d_op = &configfs_dentry_ops; | 196 | dentry->d_op = &configfs_dentry_ops; |
197 | else { | ||
198 | struct configfs_dirent *sd = dentry->d_fsdata; | ||
199 | if (sd) { | ||
200 | list_del_init(&sd->s_sibling); | ||
201 | configfs_put(sd); | ||
202 | } | ||
203 | } | ||
191 | } | 204 | } |
192 | return err; | 205 | return err; |
193 | } | 206 | } |
@@ -241,13 +254,15 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den | |||
241 | struct configfs_attribute * attr = sd->s_element; | 254 | struct configfs_attribute * attr = sd->s_element; |
242 | int error; | 255 | int error; |
243 | 256 | ||
257 | dentry->d_fsdata = configfs_get(sd); | ||
258 | sd->s_dentry = dentry; | ||
244 | error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, init_file); | 259 | error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, init_file); |
245 | if (error) | 260 | if (error) { |
261 | configfs_put(sd); | ||
246 | return error; | 262 | return error; |
263 | } | ||
247 | 264 | ||
248 | dentry->d_op = &configfs_dentry_ops; | 265 | dentry->d_op = &configfs_dentry_ops; |
249 | dentry->d_fsdata = configfs_get(sd); | ||
250 | sd->s_dentry = dentry; | ||
251 | d_rehash(dentry); | 266 | d_rehash(dentry); |
252 | 267 | ||
253 | return 0; | 268 | return 0; |
@@ -839,6 +854,7 @@ struct inode_operations configfs_dir_inode_operations = { | |||
839 | .symlink = configfs_symlink, | 854 | .symlink = configfs_symlink, |
840 | .unlink = configfs_unlink, | 855 | .unlink = configfs_unlink, |
841 | .lookup = configfs_lookup, | 856 | .lookup = configfs_lookup, |
857 | .setattr = configfs_setattr, | ||
842 | }; | 858 | }; |
843 | 859 | ||
844 | #if 0 | 860 | #if 0 |