aboutsummaryrefslogtreecommitdiffstats
path: root/fs/configfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/configfs')
-rw-r--r--fs/configfs/configfs_internal.h3
-rw-r--r--fs/configfs/dir.c72
-rw-r--r--fs/configfs/file.c28
-rw-r--r--fs/configfs/inode.c12
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;
69extern int configfs_is_root(struct config_item *item); 69extern int configfs_is_root(struct config_item *item);
70 70
71extern struct inode * configfs_new_inode(umode_t mode, struct configfs_dirent *, struct super_block *); 71extern struct inode * configfs_new_inode(umode_t mode, struct configfs_dirent *, struct super_block *);
72extern int configfs_create(struct dentry *, umode_t mode, int (*init)(struct inode *)); 72extern int configfs_create(struct dentry *, umode_t mode, void (*init)(struct inode *));
73 73
74extern int configfs_create_file(struct config_item *, const struct configfs_attribute *); 74extern int configfs_create_file(struct config_item *, const struct configfs_attribute *);
75extern int configfs_make_dirent(struct configfs_dirent *, 75extern int configfs_make_dirent(struct configfs_dirent *,
76 struct dentry *, void *, umode_t, int); 76 struct dentry *, void *, umode_t, int);
77extern int configfs_dirent_is_ready(struct configfs_dirent *); 77extern int configfs_dirent_is_ready(struct configfs_dirent *);
78 78
79extern int configfs_add_file(struct dentry *, const struct configfs_attribute *, int);
80extern void configfs_hash_and_remove(struct dentry * dir, const char * name); 79extern void configfs_hash_and_remove(struct dentry * dir, const char * name);
81 80
82extern const unsigned char * configfs_get_name(struct configfs_dirent *sd); 81extern 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
243static int init_dir(struct inode * inode) 243static 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
253static int configfs_init_file(struct inode * inode) 252static 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
260static int init_symlink(struct inode * inode) 258static 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
266static 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
306static int configfs_create_dir(struct config_item * item, struct dentry *dentry) 272static 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
317int 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
337int configfs_create_file(struct config_item * item, const struct configfs_attribute * attr) 322int 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
179int configfs_create(struct dentry * dentry, umode_t mode, int (*init)(struct inode *)) 179int 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);