From: Su Hui <suhui@nfschina.com>
To: gregkh@linuxfoundation.org, tj@kernel.org
Cc: Su Hui <suhui@nfschina.com>,
linux-kernel@vger.kernel.org, kernel-janitors@vger.kernel.org
Subject: [PATCH] kernfs: Convert idr to xarray
Date: Thu, 16 Jan 2025 16:48:02 +0800 [thread overview]
Message-ID: <20250116084801.260460-1-suhui@nfschina.com> (raw)
IDR is deprecated. Use xarray instead.
Signed-off-by: Su Hui <suhui@nfschina.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
next reply other threads:[~2025-01-16 8:48 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-16 8:48 Su Hui [this message]
2025-01-16 9:54 ` Greg KH
2025-01-16 10:12 ` Su Hui
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250116084801.260460-1-suhui@nfschina.com \
--to=suhui@nfschina.com \
--cc=gregkh@linuxfoundation.org \
--cc=kernel-janitors@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®