aboutsummaryrefslogtreecommitdiffstats
path: root/fs/configfs/dir.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/configfs/dir.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'fs/configfs/dir.c')
-rw-r--r--fs/configfs/dir.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 0b502f80c691..9a37a9b6de3a 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -53,11 +53,14 @@ DEFINE_SPINLOCK(configfs_dirent_lock);
53static void configfs_d_iput(struct dentry * dentry, 53static void configfs_d_iput(struct dentry * dentry,
54 struct inode * inode) 54 struct inode * inode)
55{ 55{
56 struct configfs_dirent * sd = dentry->d_fsdata; 56 struct configfs_dirent *sd = dentry->d_fsdata;
57 57
58 if (sd) { 58 if (sd) {
59 BUG_ON(sd->s_dentry != dentry); 59 BUG_ON(sd->s_dentry != dentry);
60 /* Coordinate with configfs_readdir */
61 spin_lock(&configfs_dirent_lock);
60 sd->s_dentry = NULL; 62 sd->s_dentry = NULL;
63 spin_unlock(&configfs_dirent_lock);
61 configfs_put(sd); 64 configfs_put(sd);
62 } 65 }
63 iput(inode); 66 iput(inode);
@@ -67,12 +70,12 @@ static void configfs_d_iput(struct dentry * dentry,
67 * We _must_ delete our dentries on last dput, as the chain-to-parent 70 * We _must_ delete our dentries on last dput, as the chain-to-parent
68 * behavior is required to clear the parents of default_groups. 71 * behavior is required to clear the parents of default_groups.
69 */ 72 */
70static int configfs_d_delete(struct dentry *dentry) 73static int configfs_d_delete(const struct dentry *dentry)
71{ 74{
72 return 1; 75 return 1;
73} 76}
74 77
75static const struct dentry_operations configfs_dentry_ops = { 78const struct dentry_operations configfs_dentry_ops = {
76 .d_iput = configfs_d_iput, 79 .d_iput = configfs_d_iput,
77 /* simple_delete_dentry() isn't exported */ 80 /* simple_delete_dentry() isn't exported */
78 .d_delete = configfs_d_delete, 81 .d_delete = configfs_d_delete,
@@ -232,10 +235,8 @@ int configfs_make_dirent(struct configfs_dirent * parent_sd,
232 235
233 sd->s_mode = mode; 236 sd->s_mode = mode;
234 sd->s_dentry = dentry; 237 sd->s_dentry = dentry;
235 if (dentry) { 238 if (dentry)
236 dentry->d_fsdata = configfs_get(sd); 239 dentry->d_fsdata = configfs_get(sd);
237 dentry->d_op = &configfs_dentry_ops;
238 }
239 240
240 return 0; 241 return 0;
241} 242}
@@ -278,7 +279,6 @@ static int create_dir(struct config_item * k, struct dentry * p,
278 error = configfs_create(d, mode, init_dir); 279 error = configfs_create(d, mode, init_dir);
279 if (!error) { 280 if (!error) {
280 inc_nlink(p->d_inode); 281 inc_nlink(p->d_inode);
281 (d)->d_op = &configfs_dentry_ops;
282 } else { 282 } else {
283 struct configfs_dirent *sd = d->d_fsdata; 283 struct configfs_dirent *sd = d->d_fsdata;
284 if (sd) { 284 if (sd) {
@@ -371,9 +371,7 @@ int configfs_create_link(struct configfs_symlink *sl,
371 CONFIGFS_ITEM_LINK); 371 CONFIGFS_ITEM_LINK);
372 if (!err) { 372 if (!err) {
373 err = configfs_create(dentry, mode, init_symlink); 373 err = configfs_create(dentry, mode, init_symlink);
374 if (!err) 374 if (err) {
375 dentry->d_op = &configfs_dentry_ops;
376 else {
377 struct configfs_dirent *sd = dentry->d_fsdata; 375 struct configfs_dirent *sd = dentry->d_fsdata;
378 if (sd) { 376 if (sd) {
379 spin_lock(&configfs_dirent_lock); 377 spin_lock(&configfs_dirent_lock);
@@ -399,8 +397,7 @@ static void remove_dir(struct dentry * d)
399 if (d->d_inode) 397 if (d->d_inode)
400 simple_rmdir(parent->d_inode,d); 398 simple_rmdir(parent->d_inode,d);
401 399
402 pr_debug(" o %s removing done (%d)\n",d->d_name.name, 400 pr_debug(" o %s removing done (%d)\n",d->d_name.name, d->d_count);
403 atomic_read(&d->d_count));
404 401
405 dput(parent); 402 dput(parent);
406} 403}
@@ -448,7 +445,6 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den
448 return error; 445 return error;
449 } 446 }
450 447
451 dentry->d_op = &configfs_dentry_ops;
452 d_rehash(dentry); 448 d_rehash(dentry);
453 449
454 return 0; 450 return 0;
@@ -493,7 +489,10 @@ static struct dentry * configfs_lookup(struct inode *dir,
493 * If it doesn't exist and it isn't a NOT_PINNED item, 489 * If it doesn't exist and it isn't a NOT_PINNED item,
494 * it must be negative. 490 * it must be negative.
495 */ 491 */
496 return simple_lookup(dir, dentry, nd); 492 if (dentry->d_name.len > NAME_MAX)
493 return ERR_PTR(-ENAMETOOLONG);
494 d_add(dentry, NULL);
495 return NULL;
497 } 496 }
498 497
499out: 498out:
@@ -693,7 +692,8 @@ static int create_default_group(struct config_group *parent_group,
693 sd = child->d_fsdata; 692 sd = child->d_fsdata;
694 sd->s_type |= CONFIGFS_USET_DEFAULT; 693 sd->s_type |= CONFIGFS_USET_DEFAULT;
695 } else { 694 } else {
696 d_delete(child); 695 BUG_ON(child->d_inode);
696 d_drop(child);
697 dput(child); 697 dput(child);
698 } 698 }
699 } 699 }
@@ -994,7 +994,7 @@ static int configfs_dump(struct configfs_dirent *sd, int level)
994 * This describes these functions and their helpers. 994 * This describes these functions and their helpers.
995 * 995 *
996 * Allow another kernel system to depend on a config_item. If this 996 * Allow another kernel system to depend on a config_item. If this
997 * happens, the item cannot go away until the dependant can live without 997 * happens, the item cannot go away until the dependent can live without
998 * it. The idea is to give client modules as simple an interface as 998 * it. The idea is to give client modules as simple an interface as
999 * possible. When a system asks them to depend on an item, they just 999 * possible. When a system asks them to depend on an item, they just
1000 * call configfs_depend_item(). If the item is live and the client 1000 * call configfs_depend_item(). If the item is live and the client
@@ -1549,7 +1549,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir
1549 struct configfs_dirent * parent_sd = dentry->d_fsdata; 1549 struct configfs_dirent * parent_sd = dentry->d_fsdata;
1550 struct configfs_dirent *cursor = filp->private_data; 1550 struct configfs_dirent *cursor = filp->private_data;
1551 struct list_head *p, *q = &cursor->s_sibling; 1551 struct list_head *p, *q = &cursor->s_sibling;
1552 ino_t ino; 1552 ino_t ino = 0;
1553 int i = filp->f_pos; 1553 int i = filp->f_pos;
1554 1554
1555 switch (i) { 1555 switch (i) {
@@ -1577,6 +1577,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir
1577 struct configfs_dirent *next; 1577 struct configfs_dirent *next;
1578 const char * name; 1578 const char * name;
1579 int len; 1579 int len;
1580 struct inode *inode = NULL;
1580 1581
1581 next = list_entry(p, struct configfs_dirent, 1582 next = list_entry(p, struct configfs_dirent,
1582 s_sibling); 1583 s_sibling);
@@ -1585,9 +1586,28 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir
1585 1586
1586 name = configfs_get_name(next); 1587 name = configfs_get_name(next);
1587 len = strlen(name); 1588 len = strlen(name);
1588 if (next->s_dentry) 1589
1589 ino = next->s_dentry->d_inode->i_ino; 1590 /*
1590 else 1591 * We'll have a dentry and an inode for
1592 * PINNED items and for open attribute
1593 * files. We lock here to prevent a race
1594 * with configfs_d_iput() clearing
1595 * s_dentry before calling iput().
1596 *
1597 * Why do we go to the trouble? If
1598 * someone has an attribute file open,
1599 * the inode number should match until
1600 * they close it. Beyond that, we don't
1601 * care.
1602 */
1603 spin_lock(&configfs_dirent_lock);
1604 dentry = next->s_dentry;
1605 if (dentry)
1606 inode = dentry->d_inode;
1607 if (inode)
1608 ino = inode->i_ino;
1609 spin_unlock(&configfs_dirent_lock);
1610 if (!inode)
1591 ino = iunique(configfs_sb, 2); 1611 ino = iunique(configfs_sb, 2);
1592 1612
1593 if (filldir(dirent, name, len, filp->f_pos, ino, 1613 if (filldir(dirent, name, len, filp->f_pos, ino,
@@ -1687,7 +1707,8 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
1687 err = configfs_attach_group(sd->s_element, &group->cg_item, 1707 err = configfs_attach_group(sd->s_element, &group->cg_item,
1688 dentry); 1708 dentry);
1689 if (err) { 1709 if (err) {
1690 d_delete(dentry); 1710 BUG_ON(dentry->d_inode);
1711 d_drop(dentry);
1691 dput(dentry); 1712 dput(dentry);
1692 } else { 1713 } else {
1693 spin_lock(&configfs_dirent_lock); 1714 spin_lock(&configfs_dirent_lock);