diff options
Diffstat (limited to 'fs/configfs/dir.c')
-rw-r--r-- | fs/configfs/dir.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index b0fbcbeb03ee..54c59a7e37ce 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -1079,6 +1079,7 @@ int configfs_depend_item(struct configfs_subsystem *subsys, | |||
1079 | int ret; | 1079 | int ret; |
1080 | struct configfs_dirent *p, *root_sd, *subsys_sd = NULL; | 1080 | struct configfs_dirent *p, *root_sd, *subsys_sd = NULL; |
1081 | struct config_item *s_item = &subsys->su_group.cg_item; | 1081 | struct config_item *s_item = &subsys->su_group.cg_item; |
1082 | struct dentry *root; | ||
1082 | 1083 | ||
1083 | /* | 1084 | /* |
1084 | * Pin the configfs filesystem. This means we can safely access | 1085 | * Pin the configfs filesystem. This means we can safely access |
@@ -1093,9 +1094,10 @@ int configfs_depend_item(struct configfs_subsystem *subsys, | |||
1093 | * subsystem is really registered, and so we need to lock out | 1094 | * subsystem is really registered, and so we need to lock out |
1094 | * configfs_[un]register_subsystem(). | 1095 | * configfs_[un]register_subsystem(). |
1095 | */ | 1096 | */ |
1096 | mutex_lock(&configfs_sb->s_root->d_inode->i_mutex); | 1097 | root = configfs_mount->mnt_root; |
1098 | mutex_lock(&root->d_inode->i_mutex); | ||
1097 | 1099 | ||
1098 | root_sd = configfs_sb->s_root->d_fsdata; | 1100 | root_sd = root->d_fsdata; |
1099 | 1101 | ||
1100 | list_for_each_entry(p, &root_sd->s_children, s_sibling) { | 1102 | list_for_each_entry(p, &root_sd->s_children, s_sibling) { |
1101 | if (p->s_type & CONFIGFS_DIR) { | 1103 | if (p->s_type & CONFIGFS_DIR) { |
@@ -1129,7 +1131,7 @@ int configfs_depend_item(struct configfs_subsystem *subsys, | |||
1129 | out_unlock_dirent_lock: | 1131 | out_unlock_dirent_lock: |
1130 | spin_unlock(&configfs_dirent_lock); | 1132 | spin_unlock(&configfs_dirent_lock); |
1131 | out_unlock_fs: | 1133 | out_unlock_fs: |
1132 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); | 1134 | mutex_unlock(&root->d_inode->i_mutex); |
1133 | 1135 | ||
1134 | /* | 1136 | /* |
1135 | * If we succeeded, the fs is pinned via other methods. If not, | 1137 | * If we succeeded, the fs is pinned via other methods. If not, |
@@ -1543,6 +1545,7 @@ static inline unsigned char dt_type(struct configfs_dirent *sd) | |||
1543 | static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | 1545 | static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir) |
1544 | { | 1546 | { |
1545 | struct dentry *dentry = filp->f_path.dentry; | 1547 | struct dentry *dentry = filp->f_path.dentry; |
1548 | struct super_block *sb = dentry->d_sb; | ||
1546 | struct configfs_dirent * parent_sd = dentry->d_fsdata; | 1549 | struct configfs_dirent * parent_sd = dentry->d_fsdata; |
1547 | struct configfs_dirent *cursor = filp->private_data; | 1550 | struct configfs_dirent *cursor = filp->private_data; |
1548 | struct list_head *p, *q = &cursor->s_sibling; | 1551 | struct list_head *p, *q = &cursor->s_sibling; |
@@ -1605,7 +1608,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir | |||
1605 | ino = inode->i_ino; | 1608 | ino = inode->i_ino; |
1606 | spin_unlock(&configfs_dirent_lock); | 1609 | spin_unlock(&configfs_dirent_lock); |
1607 | if (!inode) | 1610 | if (!inode) |
1608 | ino = iunique(configfs_sb, 2); | 1611 | ino = iunique(sb, 2); |
1609 | 1612 | ||
1610 | if (filldir(dirent, name, len, filp->f_pos, ino, | 1613 | if (filldir(dirent, name, len, filp->f_pos, ino, |
1611 | dt_type(next)) < 0) | 1614 | dt_type(next)) < 0) |
@@ -1677,6 +1680,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) | |||
1677 | struct config_group *group = &subsys->su_group; | 1680 | struct config_group *group = &subsys->su_group; |
1678 | struct qstr name; | 1681 | struct qstr name; |
1679 | struct dentry *dentry; | 1682 | struct dentry *dentry; |
1683 | struct dentry *root; | ||
1680 | struct configfs_dirent *sd; | 1684 | struct configfs_dirent *sd; |
1681 | 1685 | ||
1682 | err = configfs_pin_fs(); | 1686 | err = configfs_pin_fs(); |
@@ -1686,18 +1690,18 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) | |||
1686 | if (!group->cg_item.ci_name) | 1690 | if (!group->cg_item.ci_name) |
1687 | group->cg_item.ci_name = group->cg_item.ci_namebuf; | 1691 | group->cg_item.ci_name = group->cg_item.ci_namebuf; |
1688 | 1692 | ||
1689 | sd = configfs_sb->s_root->d_fsdata; | 1693 | root = configfs_mount->mnt_root; |
1694 | sd = root->d_fsdata; | ||
1690 | link_group(to_config_group(sd->s_element), group); | 1695 | link_group(to_config_group(sd->s_element), group); |
1691 | 1696 | ||
1692 | mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex, | 1697 | mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT); |
1693 | I_MUTEX_PARENT); | ||
1694 | 1698 | ||
1695 | name.name = group->cg_item.ci_name; | 1699 | name.name = group->cg_item.ci_name; |
1696 | name.len = strlen(name.name); | 1700 | name.len = strlen(name.name); |
1697 | name.hash = full_name_hash(name.name, name.len); | 1701 | name.hash = full_name_hash(name.name, name.len); |
1698 | 1702 | ||
1699 | err = -ENOMEM; | 1703 | err = -ENOMEM; |
1700 | dentry = d_alloc(configfs_sb->s_root, &name); | 1704 | dentry = d_alloc(root, &name); |
1701 | if (dentry) { | 1705 | if (dentry) { |
1702 | d_add(dentry, NULL); | 1706 | d_add(dentry, NULL); |
1703 | 1707 | ||
@@ -1714,7 +1718,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) | |||
1714 | } | 1718 | } |
1715 | } | 1719 | } |
1716 | 1720 | ||
1717 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); | 1721 | mutex_unlock(&root->d_inode->i_mutex); |
1718 | 1722 | ||
1719 | if (err) { | 1723 | if (err) { |
1720 | unlink_group(group); | 1724 | unlink_group(group); |
@@ -1728,13 +1732,14 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) | |||
1728 | { | 1732 | { |
1729 | struct config_group *group = &subsys->su_group; | 1733 | struct config_group *group = &subsys->su_group; |
1730 | struct dentry *dentry = group->cg_item.ci_dentry; | 1734 | struct dentry *dentry = group->cg_item.ci_dentry; |
1735 | struct dentry *root = dentry->d_sb->s_root; | ||
1731 | 1736 | ||
1732 | if (dentry->d_parent != configfs_sb->s_root) { | 1737 | if (dentry->d_parent != root) { |
1733 | printk(KERN_ERR "configfs: Tried to unregister non-subsystem!\n"); | 1738 | printk(KERN_ERR "configfs: Tried to unregister non-subsystem!\n"); |
1734 | return; | 1739 | return; |
1735 | } | 1740 | } |
1736 | 1741 | ||
1737 | mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex, | 1742 | mutex_lock_nested(&root->d_inode->i_mutex, |
1738 | I_MUTEX_PARENT); | 1743 | I_MUTEX_PARENT); |
1739 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); | 1744 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); |
1740 | mutex_lock(&configfs_symlink_mutex); | 1745 | mutex_lock(&configfs_symlink_mutex); |
@@ -1751,7 +1756,7 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) | |||
1751 | 1756 | ||
1752 | d_delete(dentry); | 1757 | d_delete(dentry); |
1753 | 1758 | ||
1754 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); | 1759 | mutex_unlock(&root->d_inode->i_mutex); |
1755 | 1760 | ||
1756 | dput(dentry); | 1761 | dput(dentry); |
1757 | 1762 | ||