diff options
Diffstat (limited to 'fs/configfs')
-rw-r--r-- | fs/configfs/configfs_internal.h | 3 | ||||
-rw-r--r-- | fs/configfs/dir.c | 72 | ||||
-rw-r--r-- | fs/configfs/file.c | 28 | ||||
-rw-r--r-- | fs/configfs/inode.c | 12 |
4 files changed, 46 insertions, 69 deletions
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index a315677e44d3..b65d1ef532d5 100644 --- a/fs/configfs/configfs_internal.h +++ b/fs/configfs/configfs_internal.h | |||
@@ -69,14 +69,13 @@ extern struct kmem_cache *configfs_dir_cachep; | |||
69 | extern int configfs_is_root(struct config_item *item); | 69 | extern int configfs_is_root(struct config_item *item); |
70 | 70 | ||
71 | extern struct inode * configfs_new_inode(umode_t mode, struct configfs_dirent *, struct super_block *); | 71 | extern struct inode * configfs_new_inode(umode_t mode, struct configfs_dirent *, struct super_block *); |
72 | extern int configfs_create(struct dentry *, umode_t mode, int (*init)(struct inode *)); | 72 | extern int configfs_create(struct dentry *, umode_t mode, void (*init)(struct inode *)); |
73 | 73 | ||
74 | extern int configfs_create_file(struct config_item *, const struct configfs_attribute *); | 74 | extern int configfs_create_file(struct config_item *, const struct configfs_attribute *); |
75 | extern int configfs_make_dirent(struct configfs_dirent *, | 75 | extern int configfs_make_dirent(struct configfs_dirent *, |
76 | struct dentry *, void *, umode_t, int); | 76 | struct dentry *, void *, umode_t, int); |
77 | extern int configfs_dirent_is_ready(struct configfs_dirent *); | 77 | extern int configfs_dirent_is_ready(struct configfs_dirent *); |
78 | 78 | ||
79 | extern int configfs_add_file(struct dentry *, const struct configfs_attribute *, int); | ||
80 | extern void configfs_hash_and_remove(struct dentry * dir, const char * name); | 79 | extern void configfs_hash_and_remove(struct dentry * dir, const char * name); |
81 | 80 | ||
82 | extern const unsigned char * configfs_get_name(struct configfs_dirent *sd); | 81 | extern const unsigned char * configfs_get_name(struct configfs_dirent *sd); |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index c9c298bd3058..cf0db005d2f5 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -240,60 +240,26 @@ int configfs_make_dirent(struct configfs_dirent * parent_sd, | |||
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
242 | 242 | ||
243 | static int init_dir(struct inode * inode) | 243 | static void init_dir(struct inode * inode) |
244 | { | 244 | { |
245 | inode->i_op = &configfs_dir_inode_operations; | 245 | inode->i_op = &configfs_dir_inode_operations; |
246 | inode->i_fop = &configfs_dir_operations; | 246 | inode->i_fop = &configfs_dir_operations; |
247 | 247 | ||
248 | /* directory inodes start off with i_nlink == 2 (for "." entry) */ | 248 | /* directory inodes start off with i_nlink == 2 (for "." entry) */ |
249 | inc_nlink(inode); | 249 | inc_nlink(inode); |
250 | return 0; | ||
251 | } | 250 | } |
252 | 251 | ||
253 | static int configfs_init_file(struct inode * inode) | 252 | static void configfs_init_file(struct inode * inode) |
254 | { | 253 | { |
255 | inode->i_size = PAGE_SIZE; | 254 | inode->i_size = PAGE_SIZE; |
256 | inode->i_fop = &configfs_file_operations; | 255 | inode->i_fop = &configfs_file_operations; |
257 | return 0; | ||
258 | } | 256 | } |
259 | 257 | ||
260 | static int init_symlink(struct inode * inode) | 258 | static void init_symlink(struct inode * inode) |
261 | { | 259 | { |
262 | inode->i_op = &configfs_symlink_inode_operations; | 260 | inode->i_op = &configfs_symlink_inode_operations; |
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int create_dir(struct config_item *k, struct dentry *d) | ||
267 | { | ||
268 | int error; | ||
269 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; | ||
270 | struct dentry *p = d->d_parent; | ||
271 | |||
272 | BUG_ON(!k); | ||
273 | |||
274 | error = configfs_dirent_exists(p->d_fsdata, d->d_name.name); | ||
275 | if (!error) | ||
276 | error = configfs_make_dirent(p->d_fsdata, d, k, mode, | ||
277 | CONFIGFS_DIR | CONFIGFS_USET_CREATING); | ||
278 | if (!error) { | ||
279 | configfs_set_dir_dirent_depth(p->d_fsdata, d->d_fsdata); | ||
280 | error = configfs_create(d, mode, init_dir); | ||
281 | if (!error) { | ||
282 | inc_nlink(p->d_inode); | ||
283 | } else { | ||
284 | struct configfs_dirent *sd = d->d_fsdata; | ||
285 | if (sd) { | ||
286 | spin_lock(&configfs_dirent_lock); | ||
287 | list_del_init(&sd->s_sibling); | ||
288 | spin_unlock(&configfs_dirent_lock); | ||
289 | configfs_put(sd); | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | return error; | ||
294 | } | 261 | } |
295 | 262 | ||
296 | |||
297 | /** | 263 | /** |
298 | * configfs_create_dir - create a directory for an config_item. | 264 | * configfs_create_dir - create a directory for an config_item. |
299 | * @item: config_itemwe're creating directory for. | 265 | * @item: config_itemwe're creating directory for. |
@@ -303,11 +269,37 @@ static int create_dir(struct config_item *k, struct dentry *d) | |||
303 | * until it is validated by configfs_dir_set_ready() | 269 | * until it is validated by configfs_dir_set_ready() |
304 | */ | 270 | */ |
305 | 271 | ||
306 | static int configfs_create_dir(struct config_item * item, struct dentry *dentry) | 272 | static int configfs_create_dir(struct config_item *item, struct dentry *dentry) |
307 | { | 273 | { |
308 | int error = create_dir(item, dentry); | 274 | int error; |
309 | if (!error) | 275 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; |
276 | struct dentry *p = dentry->d_parent; | ||
277 | |||
278 | BUG_ON(!item); | ||
279 | |||
280 | error = configfs_dirent_exists(p->d_fsdata, dentry->d_name.name); | ||
281 | if (unlikely(error)) | ||
282 | return error; | ||
283 | |||
284 | error = configfs_make_dirent(p->d_fsdata, dentry, item, mode, | ||
285 | CONFIGFS_DIR | CONFIGFS_USET_CREATING); | ||
286 | if (unlikely(error)) | ||
287 | return error; | ||
288 | |||
289 | configfs_set_dir_dirent_depth(p->d_fsdata, dentry->d_fsdata); | ||
290 | error = configfs_create(dentry, mode, init_dir); | ||
291 | if (!error) { | ||
292 | inc_nlink(p->d_inode); | ||
310 | item->ci_dentry = dentry; | 293 | item->ci_dentry = dentry; |
294 | } else { | ||
295 | struct configfs_dirent *sd = dentry->d_fsdata; | ||
296 | if (sd) { | ||
297 | spin_lock(&configfs_dirent_lock); | ||
298 | list_del_init(&sd->s_sibling); | ||
299 | spin_unlock(&configfs_dirent_lock); | ||
300 | configfs_put(sd); | ||
301 | } | ||
302 | } | ||
311 | return error; | 303 | return error; |
312 | } | 304 | } |
313 | 305 | ||
diff --git a/fs/configfs/file.c b/fs/configfs/file.c index 1d1c41f1014d..56d2cdc9ae0a 100644 --- a/fs/configfs/file.c +++ b/fs/configfs/file.c | |||
@@ -313,21 +313,6 @@ const struct file_operations configfs_file_operations = { | |||
313 | .release = configfs_release, | 313 | .release = configfs_release, |
314 | }; | 314 | }; |
315 | 315 | ||
316 | |||
317 | int configfs_add_file(struct dentry * dir, const struct configfs_attribute * attr, int type) | ||
318 | { | ||
319 | struct configfs_dirent * parent_sd = dir->d_fsdata; | ||
320 | umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG; | ||
321 | int error = 0; | ||
322 | |||
323 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_NORMAL); | ||
324 | error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type); | ||
325 | mutex_unlock(&dir->d_inode->i_mutex); | ||
326 | |||
327 | return error; | ||
328 | } | ||
329 | |||
330 | |||
331 | /** | 316 | /** |
332 | * configfs_create_file - create an attribute file for an item. | 317 | * configfs_create_file - create an attribute file for an item. |
333 | * @item: item we're creating for. | 318 | * @item: item we're creating for. |
@@ -336,9 +321,16 @@ int configfs_add_file(struct dentry * dir, const struct configfs_attribute * att | |||
336 | 321 | ||
337 | int configfs_create_file(struct config_item * item, const struct configfs_attribute * attr) | 322 | int configfs_create_file(struct config_item * item, const struct configfs_attribute * attr) |
338 | { | 323 | { |
339 | BUG_ON(!item || !item->ci_dentry || !attr); | 324 | struct dentry *dir = item->ci_dentry; |
325 | struct configfs_dirent *parent_sd = dir->d_fsdata; | ||
326 | umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG; | ||
327 | int error = 0; | ||
340 | 328 | ||
341 | return configfs_add_file(item->ci_dentry, attr, | 329 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_NORMAL); |
342 | CONFIGFS_ITEM_ATTR); | 330 | error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode, |
331 | CONFIGFS_ITEM_ATTR); | ||
332 | mutex_unlock(&dir->d_inode->i_mutex); | ||
333 | |||
334 | return error; | ||
343 | } | 335 | } |
344 | 336 | ||
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index 65af86147154..5423a6a6ecc8 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c | |||
@@ -176,7 +176,7 @@ static void configfs_set_inode_lock_class(struct configfs_dirent *sd, | |||
176 | 176 | ||
177 | #endif /* CONFIG_LOCKDEP */ | 177 | #endif /* CONFIG_LOCKDEP */ |
178 | 178 | ||
179 | int configfs_create(struct dentry * dentry, umode_t mode, int (*init)(struct inode *)) | 179 | int configfs_create(struct dentry * dentry, umode_t mode, void (*init)(struct inode *)) |
180 | { | 180 | { |
181 | int error = 0; | 181 | int error = 0; |
182 | struct inode *inode = NULL; | 182 | struct inode *inode = NULL; |
@@ -198,13 +198,7 @@ int configfs_create(struct dentry * dentry, umode_t mode, int (*init)(struct ino | |||
198 | p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; | 198 | p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; |
199 | configfs_set_inode_lock_class(sd, inode); | 199 | configfs_set_inode_lock_class(sd, inode); |
200 | 200 | ||
201 | if (init) { | 201 | init(inode); |
202 | error = init(inode); | ||
203 | if (error) { | ||
204 | iput(inode); | ||
205 | return error; | ||
206 | } | ||
207 | } | ||
208 | d_instantiate(dentry, inode); | 202 | d_instantiate(dentry, inode); |
209 | if (S_ISDIR(mode) || S_ISLNK(mode)) | 203 | if (S_ISDIR(mode) || S_ISLNK(mode)) |
210 | dget(dentry); /* pin link and directory dentries in core */ | 204 | dget(dentry); /* pin link and directory dentries in core */ |
@@ -242,7 +236,7 @@ void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent) | |||
242 | 236 | ||
243 | if (dentry) { | 237 | if (dentry) { |
244 | spin_lock(&dentry->d_lock); | 238 | spin_lock(&dentry->d_lock); |
245 | if (!(d_unhashed(dentry) && dentry->d_inode)) { | 239 | if (!d_unhashed(dentry) && dentry->d_inode) { |
246 | dget_dlock(dentry); | 240 | dget_dlock(dentry); |
247 | __d_drop(dentry); | 241 | __d_drop(dentry); |
248 | spin_unlock(&dentry->d_lock); | 242 | spin_unlock(&dentry->d_lock); |