]> www.infradead.org Git - users/willy/xarray.git/commitdiff
kernfs: Convert to XArray
authorMatthew Wilcox <willy@infradead.org>
Wed, 9 Jan 2019 18:00:22 +0000 (13:00 -0500)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 8 Aug 2019 14:29:40 +0000 (10:29 -0400)
Signed-off-by: Matthew Wilcox <willy@infradead.org>
fs/kernfs/dir.c
include/linux/kernfs.h

index a387534c9577855b6ea6d8e2868e4f85c52551b4..a0d6fd2e4d7998aa81444a67b043b594fd6d9d93 100644 (file)
@@ -20,7 +20,6 @@
 DEFINE_MUTEX(kernfs_mutex);
 static DEFINE_SPINLOCK(kernfs_rename_lock);    /* kn->parent and ->name */
 static char kernfs_pr_cont_buf[PATH_MAX];      /* protected by rename_lock */
-static DEFINE_SPINLOCK(kernfs_idr_lock);       /* root->ino_idr */
 
 #define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb)
 
@@ -534,9 +533,7 @@ void kernfs_put(struct kernfs_node *kn)
                simple_xattrs_free(&kn->iattr->xattrs);
                kmem_cache_free(kernfs_iattrs_cache, kn->iattr);
        }
-       spin_lock(&kernfs_idr_lock);
-       idr_remove(&root->ino_idr, kn->id.ino);
-       spin_unlock(&kernfs_idr_lock);
+       xa_erase(&root->inodes, kn->id.ino);
        kmem_cache_free(kernfs_node_cache, kn);
 
        kn = parent;
@@ -545,7 +542,6 @@ void kernfs_put(struct kernfs_node *kn)
                        goto repeat;
        } else {
                /* just released the root kn, free @root too */
-               idr_destroy(&root->ino_idr);
                kfree(root);
        }
 }
@@ -620,8 +616,6 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
                                             unsigned flags)
 {
        struct kernfs_node *kn;
-       u32 gen;
-       int cursor;
        int ret;
 
        name = kstrdup_const(name, GFP_KERNEL);
@@ -632,19 +626,16 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
        if (!kn)
                goto err_out1;
 
-       idr_preload(GFP_KERNEL);
-       spin_lock(&kernfs_idr_lock);
-       cursor = idr_get_cursor(&root->ino_idr);
-       ret = idr_alloc_cyclic(&root->ino_idr, kn, 1, 0, GFP_ATOMIC);
-       if (ret >= 0 && ret < cursor)
+       xa_lock(&root->inodes);
+       ret = __xa_alloc_cyclic(&root->inodes, &kn->id.ino, kn, xa_limit_32b,
+                       &root->inode_next, GFP_KERNEL);
+       if (ret == 1)
                root->next_generation++;
-       gen = root->next_generation;
-       spin_unlock(&kernfs_idr_lock);
-       idr_preload_end();
+       kn->id.generation = root->next_generation;
+       xa_unlock(&root->inodes);
+
        if (ret < 0)
                goto err_out2;
-       kn->id.ino = ret;
-       kn->id.generation = gen;
 
        /*
         * set ino first. This RELEASE is paired with atomic_inc_not_zero in
@@ -679,7 +670,7 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
        return kn;
 
  err_out3:
-       idr_remove(&root->ino_idr, kn->id.ino);
+       xa_erase(&root->inodes, kn->id.ino);
  err_out2:
        kmem_cache_free(kernfs_node_cache, kn);
  err_out1:
@@ -717,7 +708,7 @@ struct kernfs_node *kernfs_find_and_get_node_by_ino(struct kernfs_root *root,
        struct kernfs_node *kn;
 
        rcu_read_lock();
-       kn = idr_find(&root->ino_idr, ino);
+       kn = xa_load(&root->inodes, ino);
        if (!kn)
                goto out;
 
@@ -959,15 +950,14 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
        if (!root)
                return ERR_PTR(-ENOMEM);
 
-       idr_init(&root->ino_idr);
-       INIT_LIST_HEAD(&root->supers);
+       xa_init_flags(&root->inodes, XA_FLAGS_ALLOC1);
        root->next_generation = 1;
+       INIT_LIST_HEAD(&root->supers);
 
        kn = __kernfs_new_node(root, NULL, "", S_IFDIR | S_IRUGO | S_IXUGO,
                               GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
                               KERNFS_DIR);
        if (!kn) {
-               idr_destroy(&root->ino_idr);
                kfree(root);
                return ERR_PTR(-ENOMEM);
        }
index 936b61bd504e45848444ae67bc218466379e8b7a..62a901ddc146577b72292fce5123fdb66690ebdc 100644 (file)
 #include <linux/err.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
-#include <linux/idr.h>
+#include <linux/idr.h> /* No longer used here, but depended on by dozens */
 #include <linux/lockdep.h>
 #include <linux/rbtree.h>
 #include <linux/atomic.h>
 #include <linux/uidgid.h>
 #include <linux/wait.h>
+#include <linux/xarray.h>
 
 struct file;
 struct dentry;
@@ -186,7 +187,8 @@ struct kernfs_root {
        unsigned int            flags;  /* KERNFS_ROOT_* flags */
 
        /* private fields, do not use outside kernfs proper */
-       struct idr              ino_idr;
+       struct xarray           inodes;
+       u32                     inode_next;
        u32                     next_generation;
        struct kernfs_syscall_ops *syscall_ops;