diff options
Diffstat (limited to 'fs/configfs/dir.c')
-rw-r--r-- | fs/configfs/dir.c | 72 |
1 files changed, 31 insertions, 41 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 5ddd7ebd9dcd..7e6c52d8a207 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -264,11 +264,13 @@ static int init_symlink(struct inode * inode) | |||
264 | return 0; | 264 | return 0; |
265 | } | 265 | } |
266 | 266 | ||
267 | static int create_dir(struct config_item * k, struct dentry * p, | 267 | static int create_dir(struct config_item *k, struct dentry *d) |
268 | struct dentry * d) | ||
269 | { | 268 | { |
270 | int error; | 269 | int error; |
271 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; | 270 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; |
271 | struct dentry *p = d->d_parent; | ||
272 | |||
273 | BUG_ON(!k); | ||
272 | 274 | ||
273 | error = configfs_dirent_exists(p->d_fsdata, d->d_name.name); | 275 | error = configfs_dirent_exists(p->d_fsdata, d->d_name.name); |
274 | if (!error) | 276 | if (!error) |
@@ -304,19 +306,7 @@ static int create_dir(struct config_item * k, struct dentry * p, | |||
304 | 306 | ||
305 | static int configfs_create_dir(struct config_item * item, struct dentry *dentry) | 307 | static int configfs_create_dir(struct config_item * item, struct dentry *dentry) |
306 | { | 308 | { |
307 | struct dentry * parent; | 309 | int error = create_dir(item, dentry); |
308 | int error = 0; | ||
309 | |||
310 | BUG_ON(!item); | ||
311 | |||
312 | if (item->ci_parent) | ||
313 | parent = item->ci_parent->ci_dentry; | ||
314 | else if (configfs_mount) | ||
315 | parent = configfs_mount->mnt_root; | ||
316 | else | ||
317 | return -EFAULT; | ||
318 | |||
319 | error = create_dir(item,parent,dentry); | ||
320 | if (!error) | 310 | if (!error) |
321 | item->ci_dentry = dentry; | 311 | item->ci_dentry = dentry; |
322 | return error; | 312 | return error; |
@@ -1079,23 +1069,24 @@ int configfs_depend_item(struct configfs_subsystem *subsys, | |||
1079 | int ret; | 1069 | int ret; |
1080 | struct configfs_dirent *p, *root_sd, *subsys_sd = NULL; | 1070 | struct configfs_dirent *p, *root_sd, *subsys_sd = NULL; |
1081 | struct config_item *s_item = &subsys->su_group.cg_item; | 1071 | struct config_item *s_item = &subsys->su_group.cg_item; |
1072 | struct dentry *root; | ||
1082 | 1073 | ||
1083 | /* | 1074 | /* |
1084 | * Pin the configfs filesystem. This means we can safely access | 1075 | * Pin the configfs filesystem. This means we can safely access |
1085 | * the root of the configfs filesystem. | 1076 | * the root of the configfs filesystem. |
1086 | */ | 1077 | */ |
1087 | ret = configfs_pin_fs(); | 1078 | root = configfs_pin_fs(); |
1088 | if (ret) | 1079 | if (IS_ERR(root)) |
1089 | return ret; | 1080 | return PTR_ERR(root); |
1090 | 1081 | ||
1091 | /* | 1082 | /* |
1092 | * Next, lock the root directory. We're going to check that the | 1083 | * Next, lock the root directory. We're going to check that the |
1093 | * subsystem is really registered, and so we need to lock out | 1084 | * subsystem is really registered, and so we need to lock out |
1094 | * configfs_[un]register_subsystem(). | 1085 | * configfs_[un]register_subsystem(). |
1095 | */ | 1086 | */ |
1096 | mutex_lock(&configfs_sb->s_root->d_inode->i_mutex); | 1087 | mutex_lock(&root->d_inode->i_mutex); |
1097 | 1088 | ||
1098 | root_sd = configfs_sb->s_root->d_fsdata; | 1089 | root_sd = root->d_fsdata; |
1099 | 1090 | ||
1100 | list_for_each_entry(p, &root_sd->s_children, s_sibling) { | 1091 | list_for_each_entry(p, &root_sd->s_children, s_sibling) { |
1101 | if (p->s_type & CONFIGFS_DIR) { | 1092 | if (p->s_type & CONFIGFS_DIR) { |
@@ -1129,7 +1120,7 @@ int configfs_depend_item(struct configfs_subsystem *subsys, | |||
1129 | out_unlock_dirent_lock: | 1120 | out_unlock_dirent_lock: |
1130 | spin_unlock(&configfs_dirent_lock); | 1121 | spin_unlock(&configfs_dirent_lock); |
1131 | out_unlock_fs: | 1122 | out_unlock_fs: |
1132 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); | 1123 | mutex_unlock(&root->d_inode->i_mutex); |
1133 | 1124 | ||
1134 | /* | 1125 | /* |
1135 | * If we succeeded, the fs is pinned via other methods. If not, | 1126 | * If we succeeded, the fs is pinned via other methods. If not, |
@@ -1183,11 +1174,6 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode | |||
1183 | struct module *subsys_owner = NULL, *new_item_owner = NULL; | 1174 | struct module *subsys_owner = NULL, *new_item_owner = NULL; |
1184 | char *name; | 1175 | char *name; |
1185 | 1176 | ||
1186 | if (dentry->d_parent == configfs_sb->s_root) { | ||
1187 | ret = -EPERM; | ||
1188 | goto out; | ||
1189 | } | ||
1190 | |||
1191 | sd = dentry->d_parent->d_fsdata; | 1177 | sd = dentry->d_parent->d_fsdata; |
1192 | 1178 | ||
1193 | /* | 1179 | /* |
@@ -1359,9 +1345,6 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1359 | struct module *subsys_owner = NULL, *dead_item_owner = NULL; | 1345 | struct module *subsys_owner = NULL, *dead_item_owner = NULL; |
1360 | int ret; | 1346 | int ret; |
1361 | 1347 | ||
1362 | if (dentry->d_parent == configfs_sb->s_root) | ||
1363 | return -EPERM; | ||
1364 | |||
1365 | sd = dentry->d_fsdata; | 1348 | sd = dentry->d_fsdata; |
1366 | if (sd->s_type & CONFIGFS_USET_DEFAULT) | 1349 | if (sd->s_type & CONFIGFS_USET_DEFAULT) |
1367 | return -EPERM; | 1350 | return -EPERM; |
@@ -1459,6 +1442,11 @@ const struct inode_operations configfs_dir_inode_operations = { | |||
1459 | .setattr = configfs_setattr, | 1442 | .setattr = configfs_setattr, |
1460 | }; | 1443 | }; |
1461 | 1444 | ||
1445 | const struct inode_operations configfs_root_inode_operations = { | ||
1446 | .lookup = configfs_lookup, | ||
1447 | .setattr = configfs_setattr, | ||
1448 | }; | ||
1449 | |||
1462 | #if 0 | 1450 | #if 0 |
1463 | int configfs_rename_dir(struct config_item * item, const char *new_name) | 1451 | int configfs_rename_dir(struct config_item * item, const char *new_name) |
1464 | { | 1452 | { |
@@ -1546,6 +1534,7 @@ static inline unsigned char dt_type(struct configfs_dirent *sd) | |||
1546 | static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | 1534 | static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir) |
1547 | { | 1535 | { |
1548 | struct dentry *dentry = filp->f_path.dentry; | 1536 | struct dentry *dentry = filp->f_path.dentry; |
1537 | struct super_block *sb = dentry->d_sb; | ||
1549 | struct configfs_dirent * parent_sd = dentry->d_fsdata; | 1538 | struct configfs_dirent * parent_sd = dentry->d_fsdata; |
1550 | struct configfs_dirent *cursor = filp->private_data; | 1539 | struct configfs_dirent *cursor = filp->private_data; |
1551 | struct list_head *p, *q = &cursor->s_sibling; | 1540 | struct list_head *p, *q = &cursor->s_sibling; |
@@ -1608,7 +1597,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir | |||
1608 | ino = inode->i_ino; | 1597 | ino = inode->i_ino; |
1609 | spin_unlock(&configfs_dirent_lock); | 1598 | spin_unlock(&configfs_dirent_lock); |
1610 | if (!inode) | 1599 | if (!inode) |
1611 | ino = iunique(configfs_sb, 2); | 1600 | ino = iunique(sb, 2); |
1612 | 1601 | ||
1613 | if (filldir(dirent, name, len, filp->f_pos, ino, | 1602 | if (filldir(dirent, name, len, filp->f_pos, ino, |
1614 | dt_type(next)) < 0) | 1603 | dt_type(next)) < 0) |
@@ -1680,27 +1669,27 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) | |||
1680 | struct config_group *group = &subsys->su_group; | 1669 | struct config_group *group = &subsys->su_group; |
1681 | struct qstr name; | 1670 | struct qstr name; |
1682 | struct dentry *dentry; | 1671 | struct dentry *dentry; |
1672 | struct dentry *root; | ||
1683 | struct configfs_dirent *sd; | 1673 | struct configfs_dirent *sd; |
1684 | 1674 | ||
1685 | err = configfs_pin_fs(); | 1675 | root = configfs_pin_fs(); |
1686 | if (err) | 1676 | if (IS_ERR(root)) |
1687 | return err; | 1677 | return PTR_ERR(root); |
1688 | 1678 | ||
1689 | if (!group->cg_item.ci_name) | 1679 | if (!group->cg_item.ci_name) |
1690 | group->cg_item.ci_name = group->cg_item.ci_namebuf; | 1680 | group->cg_item.ci_name = group->cg_item.ci_namebuf; |
1691 | 1681 | ||
1692 | sd = configfs_sb->s_root->d_fsdata; | 1682 | sd = root->d_fsdata; |
1693 | link_group(to_config_group(sd->s_element), group); | 1683 | link_group(to_config_group(sd->s_element), group); |
1694 | 1684 | ||
1695 | mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex, | 1685 | mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT); |
1696 | I_MUTEX_PARENT); | ||
1697 | 1686 | ||
1698 | name.name = group->cg_item.ci_name; | 1687 | name.name = group->cg_item.ci_name; |
1699 | name.len = strlen(name.name); | 1688 | name.len = strlen(name.name); |
1700 | name.hash = full_name_hash(name.name, name.len); | 1689 | name.hash = full_name_hash(name.name, name.len); |
1701 | 1690 | ||
1702 | err = -ENOMEM; | 1691 | err = -ENOMEM; |
1703 | dentry = d_alloc(configfs_sb->s_root, &name); | 1692 | dentry = d_alloc(root, &name); |
1704 | if (dentry) { | 1693 | if (dentry) { |
1705 | d_add(dentry, NULL); | 1694 | d_add(dentry, NULL); |
1706 | 1695 | ||
@@ -1717,7 +1706,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) | |||
1717 | } | 1706 | } |
1718 | } | 1707 | } |
1719 | 1708 | ||
1720 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); | 1709 | mutex_unlock(&root->d_inode->i_mutex); |
1721 | 1710 | ||
1722 | if (err) { | 1711 | if (err) { |
1723 | unlink_group(group); | 1712 | unlink_group(group); |
@@ -1731,13 +1720,14 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) | |||
1731 | { | 1720 | { |
1732 | struct config_group *group = &subsys->su_group; | 1721 | struct config_group *group = &subsys->su_group; |
1733 | struct dentry *dentry = group->cg_item.ci_dentry; | 1722 | struct dentry *dentry = group->cg_item.ci_dentry; |
1723 | struct dentry *root = dentry->d_sb->s_root; | ||
1734 | 1724 | ||
1735 | if (dentry->d_parent != configfs_sb->s_root) { | 1725 | if (dentry->d_parent != root) { |
1736 | printk(KERN_ERR "configfs: Tried to unregister non-subsystem!\n"); | 1726 | printk(KERN_ERR "configfs: Tried to unregister non-subsystem!\n"); |
1737 | return; | 1727 | return; |
1738 | } | 1728 | } |
1739 | 1729 | ||
1740 | mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex, | 1730 | mutex_lock_nested(&root->d_inode->i_mutex, |
1741 | I_MUTEX_PARENT); | 1731 | I_MUTEX_PARENT); |
1742 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); | 1732 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); |
1743 | mutex_lock(&configfs_symlink_mutex); | 1733 | mutex_lock(&configfs_symlink_mutex); |
@@ -1754,7 +1744,7 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) | |||
1754 | 1744 | ||
1755 | d_delete(dentry); | 1745 | d_delete(dentry); |
1756 | 1746 | ||
1757 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); | 1747 | mutex_unlock(&root->d_inode->i_mutex); |
1758 | 1748 | ||
1759 | dput(dentry); | 1749 | dput(dentry); |
1760 | 1750 | ||