#define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb)
 
-static DEFINE_SPINLOCK(sysfs_ino_lock);
-static DEFINE_IDA(sysfs_ino_ida);
-
 /**
  *     sysfs_name_hash
  *     @name: Null terminated string to hash
        rwsem_release(&sd->dep_map, 1, _RET_IP_);
 }
 
-static int sysfs_alloc_ino(unsigned int *pino)
-{
-       int ino, rc;
-
- retry:
-       spin_lock(&sysfs_ino_lock);
-       rc = ida_get_new_above(&sysfs_ino_ida, 1, &ino);
-       spin_unlock(&sysfs_ino_lock);
-
-       if (rc == -EAGAIN) {
-               if (ida_pre_get(&sysfs_ino_ida, GFP_KERNEL))
-                       goto retry;
-               rc = -ENOMEM;
-       }
-
-       *pino = ino;
-       return rc;
-}
-
-static void sysfs_free_ino(unsigned int ino)
-{
-       spin_lock(&sysfs_ino_lock);
-       ida_remove(&sysfs_ino_ida, ino);
-       spin_unlock(&sysfs_ino_lock);
-}
-
 /**
  * kernfs_get - get a reference count on a sysfs_dirent
  * @sd: the target sysfs_dirent
                security_release_secctx(sd->s_iattr->ia_secdata,
                                        sd->s_iattr->ia_secdata_len);
        kfree(sd->s_iattr);
-       sysfs_free_ino(sd->s_ino);
+       ida_simple_remove(&root->ino_ida, sd->s_ino);
        kmem_cache_free(sysfs_dir_cachep, sd);
 
        sd = parent_sd;
                        goto repeat;
        } else {
                /* just released the root sd, free @root too */
+               ida_destroy(&root->ino_ida);
                kfree(root);
        }
 }
        .d_release      = sysfs_dentry_release,
 };
 
-struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
+struct sysfs_dirent *sysfs_new_dirent(struct kernfs_root *root,
+                                     const char *name, umode_t mode, int type)
 {
        char *dup_name = NULL;
        struct sysfs_dirent *sd;
+       int ret;
 
        if (type & SYSFS_COPY_NAME) {
                name = dup_name = kstrdup(name, GFP_KERNEL);
        if (!sd)
                goto err_out1;
 
-       if (sysfs_alloc_ino(&sd->s_ino))
+       ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL);
+       if (ret < 0)
                goto err_out2;
+       sd->s_ino = ret;
 
        atomic_set(&sd->s_count, 1);
        atomic_set(&sd->s_active, 0);
        if (!root)
                return ERR_PTR(-ENOMEM);
 
-       sd = sysfs_new_dirent("", S_IFDIR | S_IRUGO | S_IXUGO, SYSFS_DIR);
+       ida_init(&root->ino_ida);
+
+       sd = sysfs_new_dirent(root, "", S_IFDIR | S_IRUGO | S_IXUGO, SYSFS_DIR);
        if (!sd) {
+               ida_destroy(&root->ino_ida);
                kfree(root);
                return ERR_PTR(-ENOMEM);
        }
        int rc;
 
        /* allocate */
-       sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
+       sd = sysfs_new_dirent(kernfs_root(parent), name, mode, SYSFS_DIR);
        if (!sd)
                return ERR_PTR(-ENOMEM);