diff options
Diffstat (limited to 'fs/configfs/dir.c')
-rw-r--r-- | fs/configfs/dir.c | 137 |
1 files changed, 55 insertions, 82 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 7aabc6ad4e9b..277bd1be21fd 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -387,7 +387,7 @@ static void remove_dir(struct dentry * d) | |||
387 | if (d->d_inode) | 387 | if (d->d_inode) |
388 | simple_rmdir(parent->d_inode,d); | 388 | simple_rmdir(parent->d_inode,d); |
389 | 389 | ||
390 | pr_debug(" o %s removing done (%d)\n",d->d_name.name, d->d_count); | 390 | pr_debug(" o %s removing done (%d)\n",d->d_name.name, d_count(d)); |
391 | 391 | ||
392 | dput(parent); | 392 | dput(parent); |
393 | } | 393 | } |
@@ -660,19 +660,15 @@ static int create_default_group(struct config_group *parent_group, | |||
660 | struct config_group *group) | 660 | struct config_group *group) |
661 | { | 661 | { |
662 | int ret; | 662 | int ret; |
663 | struct qstr name; | ||
664 | struct configfs_dirent *sd; | 663 | struct configfs_dirent *sd; |
665 | /* We trust the caller holds a reference to parent */ | 664 | /* We trust the caller holds a reference to parent */ |
666 | struct dentry *child, *parent = parent_group->cg_item.ci_dentry; | 665 | struct dentry *child, *parent = parent_group->cg_item.ci_dentry; |
667 | 666 | ||
668 | if (!group->cg_item.ci_name) | 667 | if (!group->cg_item.ci_name) |
669 | group->cg_item.ci_name = group->cg_item.ci_namebuf; | 668 | group->cg_item.ci_name = group->cg_item.ci_namebuf; |
670 | name.name = group->cg_item.ci_name; | ||
671 | name.len = strlen(name.name); | ||
672 | name.hash = full_name_hash(name.name, name.len); | ||
673 | 669 | ||
674 | ret = -ENOMEM; | 670 | ret = -ENOMEM; |
675 | child = d_alloc(parent, &name); | 671 | child = d_alloc_name(parent, group->cg_item.ci_name); |
676 | if (child) { | 672 | if (child) { |
677 | d_add(child, NULL); | 673 | d_add(child, NULL); |
678 | 674 | ||
@@ -1532,84 +1528,66 @@ static inline unsigned char dt_type(struct configfs_dirent *sd) | |||
1532 | return (sd->s_mode >> 12) & 15; | 1528 | return (sd->s_mode >> 12) & 15; |
1533 | } | 1529 | } |
1534 | 1530 | ||
1535 | static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | 1531 | static int configfs_readdir(struct file *file, struct dir_context *ctx) |
1536 | { | 1532 | { |
1537 | struct dentry *dentry = filp->f_path.dentry; | 1533 | struct dentry *dentry = file->f_path.dentry; |
1538 | struct super_block *sb = dentry->d_sb; | 1534 | struct super_block *sb = dentry->d_sb; |
1539 | struct configfs_dirent * parent_sd = dentry->d_fsdata; | 1535 | struct configfs_dirent * parent_sd = dentry->d_fsdata; |
1540 | struct configfs_dirent *cursor = filp->private_data; | 1536 | struct configfs_dirent *cursor = file->private_data; |
1541 | struct list_head *p, *q = &cursor->s_sibling; | 1537 | struct list_head *p, *q = &cursor->s_sibling; |
1542 | ino_t ino = 0; | 1538 | ino_t ino = 0; |
1543 | int i = filp->f_pos; | ||
1544 | 1539 | ||
1545 | switch (i) { | 1540 | if (!dir_emit_dots(file, ctx)) |
1546 | case 0: | 1541 | return 0; |
1547 | ino = dentry->d_inode->i_ino; | 1542 | if (ctx->pos == 2) { |
1548 | if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) | 1543 | spin_lock(&configfs_dirent_lock); |
1549 | break; | 1544 | list_move(q, &parent_sd->s_children); |
1550 | filp->f_pos++; | 1545 | spin_unlock(&configfs_dirent_lock); |
1551 | i++; | 1546 | } |
1552 | /* fallthrough */ | 1547 | for (p = q->next; p != &parent_sd->s_children; p = p->next) { |
1553 | case 1: | 1548 | struct configfs_dirent *next; |
1554 | ino = parent_ino(dentry); | 1549 | const char *name; |
1555 | if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) | 1550 | int len; |
1556 | break; | 1551 | struct inode *inode = NULL; |
1557 | filp->f_pos++; | 1552 | |
1558 | i++; | 1553 | next = list_entry(p, struct configfs_dirent, s_sibling); |
1559 | /* fallthrough */ | 1554 | if (!next->s_element) |
1560 | default: | 1555 | continue; |
1561 | if (filp->f_pos == 2) { | ||
1562 | spin_lock(&configfs_dirent_lock); | ||
1563 | list_move(q, &parent_sd->s_children); | ||
1564 | spin_unlock(&configfs_dirent_lock); | ||
1565 | } | ||
1566 | for (p=q->next; p!= &parent_sd->s_children; p=p->next) { | ||
1567 | struct configfs_dirent *next; | ||
1568 | const char * name; | ||
1569 | int len; | ||
1570 | struct inode *inode = NULL; | ||
1571 | 1556 | ||
1572 | next = list_entry(p, struct configfs_dirent, | 1557 | name = configfs_get_name(next); |
1573 | s_sibling); | 1558 | len = strlen(name); |
1574 | if (!next->s_element) | ||
1575 | continue; | ||
1576 | |||
1577 | name = configfs_get_name(next); | ||
1578 | len = strlen(name); | ||
1579 | |||
1580 | /* | ||
1581 | * We'll have a dentry and an inode for | ||
1582 | * PINNED items and for open attribute | ||
1583 | * files. We lock here to prevent a race | ||
1584 | * with configfs_d_iput() clearing | ||
1585 | * s_dentry before calling iput(). | ||
1586 | * | ||
1587 | * Why do we go to the trouble? If | ||
1588 | * someone has an attribute file open, | ||
1589 | * the inode number should match until | ||
1590 | * they close it. Beyond that, we don't | ||
1591 | * care. | ||
1592 | */ | ||
1593 | spin_lock(&configfs_dirent_lock); | ||
1594 | dentry = next->s_dentry; | ||
1595 | if (dentry) | ||
1596 | inode = dentry->d_inode; | ||
1597 | if (inode) | ||
1598 | ino = inode->i_ino; | ||
1599 | spin_unlock(&configfs_dirent_lock); | ||
1600 | if (!inode) | ||
1601 | ino = iunique(sb, 2); | ||
1602 | 1559 | ||
1603 | if (filldir(dirent, name, len, filp->f_pos, ino, | 1560 | /* |
1604 | dt_type(next)) < 0) | 1561 | * We'll have a dentry and an inode for |
1605 | return 0; | 1562 | * PINNED items and for open attribute |
1563 | * files. We lock here to prevent a race | ||
1564 | * with configfs_d_iput() clearing | ||
1565 | * s_dentry before calling iput(). | ||
1566 | * | ||
1567 | * Why do we go to the trouble? If | ||
1568 | * someone has an attribute file open, | ||
1569 | * the inode number should match until | ||
1570 | * they close it. Beyond that, we don't | ||
1571 | * care. | ||
1572 | */ | ||
1573 | spin_lock(&configfs_dirent_lock); | ||
1574 | dentry = next->s_dentry; | ||
1575 | if (dentry) | ||
1576 | inode = dentry->d_inode; | ||
1577 | if (inode) | ||
1578 | ino = inode->i_ino; | ||
1579 | spin_unlock(&configfs_dirent_lock); | ||
1580 | if (!inode) | ||
1581 | ino = iunique(sb, 2); | ||
1606 | 1582 | ||
1607 | spin_lock(&configfs_dirent_lock); | 1583 | if (!dir_emit(ctx, name, len, ino, dt_type(next))) |
1608 | list_move(q, p); | 1584 | return 0; |
1609 | spin_unlock(&configfs_dirent_lock); | 1585 | |
1610 | p = q; | 1586 | spin_lock(&configfs_dirent_lock); |
1611 | filp->f_pos++; | 1587 | list_move(q, p); |
1612 | } | 1588 | spin_unlock(&configfs_dirent_lock); |
1589 | p = q; | ||
1590 | ctx->pos++; | ||
1613 | } | 1591 | } |
1614 | return 0; | 1592 | return 0; |
1615 | } | 1593 | } |
@@ -1661,14 +1639,13 @@ const struct file_operations configfs_dir_operations = { | |||
1661 | .release = configfs_dir_close, | 1639 | .release = configfs_dir_close, |
1662 | .llseek = configfs_dir_lseek, | 1640 | .llseek = configfs_dir_lseek, |
1663 | .read = generic_read_dir, | 1641 | .read = generic_read_dir, |
1664 | .readdir = configfs_readdir, | 1642 | .iterate = configfs_readdir, |
1665 | }; | 1643 | }; |
1666 | 1644 | ||
1667 | int configfs_register_subsystem(struct configfs_subsystem *subsys) | 1645 | int configfs_register_subsystem(struct configfs_subsystem *subsys) |
1668 | { | 1646 | { |
1669 | int err; | 1647 | int err; |
1670 | struct config_group *group = &subsys->su_group; | 1648 | struct config_group *group = &subsys->su_group; |
1671 | struct qstr name; | ||
1672 | struct dentry *dentry; | 1649 | struct dentry *dentry; |
1673 | struct dentry *root; | 1650 | struct dentry *root; |
1674 | struct configfs_dirent *sd; | 1651 | struct configfs_dirent *sd; |
@@ -1685,12 +1662,8 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) | |||
1685 | 1662 | ||
1686 | mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT); | 1663 | mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT); |
1687 | 1664 | ||
1688 | name.name = group->cg_item.ci_name; | ||
1689 | name.len = strlen(name.name); | ||
1690 | name.hash = full_name_hash(name.name, name.len); | ||
1691 | |||
1692 | err = -ENOMEM; | 1665 | err = -ENOMEM; |
1693 | dentry = d_alloc(root, &name); | 1666 | dentry = d_alloc_name(root, group->cg_item.ci_name); |
1694 | if (dentry) { | 1667 | if (dentry) { |
1695 | d_add(dentry, NULL); | 1668 | d_add(dentry, NULL); |
1696 | 1669 | ||