Merge tag 'upstream-3.4-rc1' of git://git.infradead.org/linux-ubi
[firefly-linux-kernel-4.4.55.git] / fs / configfs / dir.c
index 5ddd7ebd9dcd2156ce6a206fc5ba24c47c1c308a..7e6c52d8a2074c651b116a39d56a1868d622f9f1 100644 (file)
@@ -264,11 +264,13 @@ static int init_symlink(struct inode * inode)
        return 0;
 }
 
-static int create_dir(struct config_item * k, struct dentry * p,
-                     struct dentry * d)
+static int create_dir(struct config_item *k, struct dentry *d)
 {
        int error;
        umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
+       struct dentry *p = d->d_parent;
+
+       BUG_ON(!k);
 
        error = configfs_dirent_exists(p->d_fsdata, d->d_name.name);
        if (!error)
@@ -304,19 +306,7 @@ static int create_dir(struct config_item * k, struct dentry * p,
 
 static int configfs_create_dir(struct config_item * item, struct dentry *dentry)
 {
-       struct dentry * parent;
-       int error = 0;
-
-       BUG_ON(!item);
-
-       if (item->ci_parent)
-               parent = item->ci_parent->ci_dentry;
-       else if (configfs_mount)
-               parent = configfs_mount->mnt_root;
-       else
-               return -EFAULT;
-
-       error = create_dir(item,parent,dentry);
+       int error = create_dir(item, dentry);
        if (!error)
                item->ci_dentry = dentry;
        return error;
@@ -1079,23 +1069,24 @@ int configfs_depend_item(struct configfs_subsystem *subsys,
        int ret;
        struct configfs_dirent *p, *root_sd, *subsys_sd = NULL;
        struct config_item *s_item = &subsys->su_group.cg_item;
+       struct dentry *root;
 
        /*
         * Pin the configfs filesystem.  This means we can safely access
         * the root of the configfs filesystem.
         */
-       ret = configfs_pin_fs();
-       if (ret)
-               return ret;
+       root = configfs_pin_fs();
+       if (IS_ERR(root))
+               return PTR_ERR(root);
 
        /*
         * Next, lock the root directory.  We're going to check that the
         * subsystem is really registered, and so we need to lock out
         * configfs_[un]register_subsystem().
         */
-       mutex_lock(&configfs_sb->s_root->d_inode->i_mutex);
+       mutex_lock(&root->d_inode->i_mutex);
 
-       root_sd = configfs_sb->s_root->d_fsdata;
+       root_sd = root->d_fsdata;
 
        list_for_each_entry(p, &root_sd->s_children, s_sibling) {
                if (p->s_type & CONFIGFS_DIR) {
@@ -1129,7 +1120,7 @@ int configfs_depend_item(struct configfs_subsystem *subsys,
 out_unlock_dirent_lock:
        spin_unlock(&configfs_dirent_lock);
 out_unlock_fs:
-       mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex);
+       mutex_unlock(&root->d_inode->i_mutex);
 
        /*
         * 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
        struct module *subsys_owner = NULL, *new_item_owner = NULL;
        char *name;
 
-       if (dentry->d_parent == configfs_sb->s_root) {
-               ret = -EPERM;
-               goto out;
-       }
-
        sd = dentry->d_parent->d_fsdata;
 
        /*
@@ -1359,9 +1345,6 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
        struct module *subsys_owner = NULL, *dead_item_owner = NULL;
        int ret;
 
-       if (dentry->d_parent == configfs_sb->s_root)
-               return -EPERM;
-
        sd = dentry->d_fsdata;
        if (sd->s_type & CONFIGFS_USET_DEFAULT)
                return -EPERM;
@@ -1459,6 +1442,11 @@ const struct inode_operations configfs_dir_inode_operations = {
        .setattr        = configfs_setattr,
 };
 
+const struct inode_operations configfs_root_inode_operations = {
+       .lookup         = configfs_lookup,
+       .setattr        = configfs_setattr,
+};
+
 #if 0
 int configfs_rename_dir(struct config_item * item, const char *new_name)
 {
@@ -1546,6 +1534,7 @@ static inline unsigned char dt_type(struct configfs_dirent *sd)
 static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
        struct dentry *dentry = filp->f_path.dentry;
+       struct super_block *sb = dentry->d_sb;
        struct configfs_dirent * parent_sd = dentry->d_fsdata;
        struct configfs_dirent *cursor = filp->private_data;
        struct list_head *p, *q = &cursor->s_sibling;
@@ -1608,7 +1597,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir
                                        ino = inode->i_ino;
                                spin_unlock(&configfs_dirent_lock);
                                if (!inode)
-                                       ino = iunique(configfs_sb, 2);
+                                       ino = iunique(sb, 2);
 
                                if (filldir(dirent, name, len, filp->f_pos, ino,
                                                 dt_type(next)) < 0)
@@ -1680,27 +1669,27 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
        struct config_group *group = &subsys->su_group;
        struct qstr name;
        struct dentry *dentry;
+       struct dentry *root;
        struct configfs_dirent *sd;
 
-       err = configfs_pin_fs();
-       if (err)
-               return err;
+       root = configfs_pin_fs();
+       if (IS_ERR(root))
+               return PTR_ERR(root);
 
        if (!group->cg_item.ci_name)
                group->cg_item.ci_name = group->cg_item.ci_namebuf;
 
-       sd = configfs_sb->s_root->d_fsdata;
+       sd = root->d_fsdata;
        link_group(to_config_group(sd->s_element), group);
 
-       mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex,
-                       I_MUTEX_PARENT);
+       mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT);
 
        name.name = group->cg_item.ci_name;
        name.len = strlen(name.name);
        name.hash = full_name_hash(name.name, name.len);
 
        err = -ENOMEM;
-       dentry = d_alloc(configfs_sb->s_root, &name);
+       dentry = d_alloc(root, &name);
        if (dentry) {
                d_add(dentry, NULL);
 
@@ -1717,7 +1706,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
                }
        }
 
-       mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex);
+       mutex_unlock(&root->d_inode->i_mutex);
 
        if (err) {
                unlink_group(group);
@@ -1731,13 +1720,14 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
 {
        struct config_group *group = &subsys->su_group;
        struct dentry *dentry = group->cg_item.ci_dentry;
+       struct dentry *root = dentry->d_sb->s_root;
 
-       if (dentry->d_parent != configfs_sb->s_root) {
+       if (dentry->d_parent != root) {
                printk(KERN_ERR "configfs: Tried to unregister non-subsystem!\n");
                return;
        }
 
-       mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex,
+       mutex_lock_nested(&root->d_inode->i_mutex,
                          I_MUTEX_PARENT);
        mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD);
        mutex_lock(&configfs_symlink_mutex);
@@ -1754,7 +1744,7 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
 
        d_delete(dentry);
 
-       mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex);
+       mutex_unlock(&root->d_inode->i_mutex);
 
        dput(dentry);