[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250116084801.260460-1-suhui@nfschina.com>
Date: Thu, 16 Jan 2025 16:48:02 +0800
From: Su Hui <suhui@...china.com>
To: gregkh@...uxfoundation.org,
tj@...nel.org
Cc: Su Hui <suhui@...china.com>,
linux-kernel@...r.kernel.org,
kernel-janitors@...r.kernel.org
Subject: [PATCH] kernfs: Convert idr to xarray
IDR is deprecated. Use xarray instead.
Signed-off-by: Su Hui <suhui@...china.com>
---
fs/kernfs/dir.c | 34 ++++++++++++++--------------------
fs/kernfs/kernfs-internal.h | 3 ++-
2 files changed, 16 insertions(+), 21 deletions(-)
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 458519e416fe..8d0af0ae6c99 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -10,7 +10,7 @@
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/namei.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
#include <linux/slab.h>
#include <linux/security.h>
#include <linux/hash.h>
@@ -27,7 +27,6 @@ static DEFINE_RWLOCK(kernfs_rename_lock); /* kn->parent and ->name */
*/
static DEFINE_SPINLOCK(kernfs_pr_cont_lock);
static char kernfs_pr_cont_buf[PATH_MAX]; /* protected by pr_cont_lock */
-static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */
#define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb)
@@ -571,9 +570,7 @@ void kernfs_put(struct kernfs_node *kn)
if (kernfs_type(kn) == KERNFS_LINK)
kernfs_put(kn->symlink.target_kn);
- spin_lock(&kernfs_idr_lock);
- idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
- spin_unlock(&kernfs_idr_lock);
+ xa_erase(&root->ino_xa, (u32)kernfs_ino(kn));
call_rcu(&kn->rcu, kernfs_free_rcu);
@@ -583,7 +580,7 @@ void kernfs_put(struct kernfs_node *kn)
goto repeat;
} else {
/* just released the root kn, free @root too */
- idr_destroy(&root->ino_idr);
+ xa_destroy(&root->ino_xa);
kfree_rcu(root, rcu);
}
}
@@ -616,6 +613,7 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
struct kernfs_node *kn;
u32 id_highbits;
int ret;
+ u32 id;
name = kstrdup_const(name, GFP_KERNEL);
if (!name)
@@ -625,19 +623,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);
- ret = idr_alloc_cyclic(&root->ino_idr, kn, 1, 0, GFP_ATOMIC);
- if (ret >= 0 && ret < root->last_id_lowbits)
+ ret = xa_alloc_cyclic(&root->ino_xa, &id, kn, XA_LIMIT(1, INT_MAX),
+ &root->ino_xa_next_id, GFP_ATOMIC);
+ if (ret >= 0 && id < root->last_id_lowbits)
root->id_highbits++;
id_highbits = root->id_highbits;
- root->last_id_lowbits = ret;
- spin_unlock(&kernfs_idr_lock);
- idr_preload_end();
+ root->last_id_lowbits = id;
if (ret < 0)
goto err_out2;
- kn->id = (u64)id_highbits << 32 | ret;
+ kn->id = (u64)id_highbits << 32 | id;
atomic_set(&kn->count, 1);
atomic_set(&kn->active, KN_DEACTIVATED_BIAS);
@@ -668,9 +663,7 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
return kn;
err_out3:
- spin_lock(&kernfs_idr_lock);
- idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
- spin_unlock(&kernfs_idr_lock);
+ xa_erase(&root->ino_xa, (u32)kernfs_ino(kn));
err_out2:
kmem_cache_free(kernfs_node_cache, kn);
err_out1:
@@ -726,7 +719,7 @@ struct kernfs_node *kernfs_find_and_get_node_by_id(struct kernfs_root *root,
rcu_read_lock();
- kn = idr_find(&root->ino_idr, (u32)ino);
+ kn = xa_load(&root->ino_xa, (u32)ino);
if (!kn)
goto err_unlock;
@@ -968,11 +961,12 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
if (!root)
return ERR_PTR(-ENOMEM);
- idr_init(&root->ino_idr);
+ xa_init_flags(&root->ino_xa, XA_FLAGS_ALLOC1);
init_rwsem(&root->kernfs_rwsem);
init_rwsem(&root->kernfs_iattr_rwsem);
init_rwsem(&root->kernfs_supers_rwsem);
INIT_LIST_HEAD(&root->supers);
+ root->ino_xa_next_id = 1;
/*
* On 64bit ino setups, id is ino. On 32bit, low 32bits are ino.
@@ -989,7 +983,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
KERNFS_DIR);
if (!kn) {
- idr_destroy(&root->ino_idr);
+ xa_destroy(&root->ino_xa);
kfree(root);
return ERR_PTR(-ENOMEM);
}
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h
index b42ee6547cdc..1b77e1a6e5a1 100644
--- a/fs/kernfs/kernfs-internal.h
+++ b/fs/kernfs/kernfs-internal.h
@@ -37,7 +37,8 @@ struct kernfs_root {
unsigned int flags; /* KERNFS_ROOT_* flags */
/* private fields, do not use outside kernfs proper */
- struct idr ino_idr;
+ struct xarray ino_xa;
+ u32 ino_xa_next_id;
u32 last_id_lowbits;
u32 id_highbits;
struct kernfs_syscall_ops *syscall_ops;
--
2.30.2
Powered by blists - more mailing lists