From d77da3a1609f0415559057a8af1976f408cca54f Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sat, 3 Nov 2018 12:14:05 -0400 Subject: [PATCH] nfs: Convert cb_ident_idr to XArray Rename it to cb_ids. The XArray does not need a 'destroy' function to be called, so remove all trace of nfs_cleanup_cb_ident_idr(). Pass the nfs_net parameter to nfs_cb_id_remove_locked() so it doesn't have to look that up again. Signed-off-by: Matthew Wilcox --- fs/nfs/client.c | 25 ++++++++++--------------- fs/nfs/netns.h | 2 +- fs/nfs/nfs4client.c | 34 ++++++++++++---------------------- 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 30838304a0bf..b2560df4d081 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include @@ -194,20 +194,15 @@ error_0: EXPORT_SYMBOL_GPL(nfs_alloc_client); #if IS_ENABLED(CONFIG_NFS_V4) -static void nfs_cleanup_cb_ident_idr(struct net *net) +static void nfs_cleanup_cb_ident(struct nfs_net *nn) { - struct nfs_net *nn = net_generic(net, nfs_net_id); - - idr_destroy(&nn->cb_ident_idr); + xa_destroy(&nn->cb_ids); } -/* nfs_client_lock held */ -static void nfs_cb_idr_remove_locked(struct nfs_client *clp) +static void nfs_cb_id_remove_locked(struct nfs_net *nn, struct nfs_client *clp) { - struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id); - if (clp->cl_cb_ident) - idr_remove(&nn->cb_ident_idr, clp->cl_cb_ident); + xa_erase(&nn->cb_ids, clp->cl_cb_ident); } static void pnfs_init_server(struct nfs_server *server) @@ -216,11 +211,11 @@ static void pnfs_init_server(struct nfs_server *server) } #else -static void nfs_cleanup_cb_ident_idr(struct net *net) +static void nfs_cleanup_cb_ident(struct nfs_net *nn) { } -static void nfs_cb_idr_remove_locked(struct nfs_client *clp) +static void nfs_cb_id_remove_locked(struct nfs_net *nn, struct nfs_client *clp) { } @@ -263,7 +258,7 @@ void nfs_put_client(struct nfs_client *clp) if (refcount_dec_and_lock(&clp->cl_count, &nn->nfs_client_lock)) { list_del(&clp->cl_share_link); - nfs_cb_idr_remove_locked(clp); + nfs_cb_id_remove_locked(nn, clp); spin_unlock(&nn->nfs_client_lock); WARN_ON_ONCE(!list_empty(&clp->cl_superblocks)); @@ -1072,7 +1067,7 @@ void nfs_clients_init(struct net *net) INIT_LIST_HEAD(&nn->nfs_client_list); INIT_LIST_HEAD(&nn->nfs_volume_list); #if IS_ENABLED(CONFIG_NFS_V4) - idr_init(&nn->cb_ident_idr); + xa_init_flags(&nn->cb_ids, XA_FLAGS_ALLOC1); #endif spin_lock_init(&nn->nfs_client_lock); nn->boot_time = ktime_get_real(); @@ -1085,7 +1080,7 @@ void nfs_clients_exit(struct net *net) struct nfs_net *nn = net_generic(net, nfs_net_id); nfs_netns_sysfs_destroy(nn); - nfs_cleanup_cb_ident_idr(net); + nfs_cleanup_cb_ident(nn); WARN_ON_ONCE(!list_empty(&nn->nfs_client_list)); WARN_ON_ONCE(!list_empty(&nn->nfs_volume_list)); } diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h index c8374f74dce1..bfb44770bf52 100644 --- a/fs/nfs/netns.h +++ b/fs/nfs/netns.h @@ -26,7 +26,7 @@ struct nfs_net { struct list_head nfs_client_list; struct list_head nfs_volume_list; #if IS_ENABLED(CONFIG_NFS_V4) - struct idr cb_ident_idr; /* Protected by nfs_client_lock */ + struct xarray cb_ids; unsigned short nfs_callback_tcpport; unsigned short nfs_callback_tcpport6; int cb_users[NFS4_MAX_MINOR_VERSION + 1]; diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 616393a01c06..d2fa962710bf 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -25,21 +25,14 @@ * Get a unique NFSv4.0 callback identifier which will be used * by the V4.0 callback service to lookup the nfs_client struct */ -static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion) +static int nfs_get_cb_ident(struct nfs_client *clp, int minorversion) { - int ret = 0; struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id); if (clp->rpc_ops->version != 4 || minorversion != 0) - return ret; - idr_preload(GFP_KERNEL); - spin_lock(&nn->nfs_client_lock); - ret = idr_alloc(&nn->cb_ident_idr, clp, 1, 0, GFP_NOWAIT); - if (ret >= 0) - clp->cl_cb_ident = ret; - spin_unlock(&nn->nfs_client_lock); - idr_preload_end(); - return ret < 0 ? ret : 0; + return 0; + return xa_alloc(&nn->cb_ids, &clp->cl_cb_ident, clp, xa_limit_32b, + GFP_KERNEL); } #ifdef CONFIG_NFS_V4_1 @@ -202,7 +195,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) if (IS_ERR(clp)) return clp; - err = nfs_get_cb_ident_idr(clp, cl_init->minorversion); + err = nfs_get_cb_ident(clp, cl_init->minorversion); if (err) goto error; @@ -466,15 +459,12 @@ static void nfs4_swap_callback_idents(struct nfs_client *keep, dprintk("%s: keeping callback ident %u and dropping ident %u\n", __func__, keep->cl_cb_ident, drop->cl_cb_ident); - spin_lock(&nn->nfs_client_lock); - - idr_replace(&nn->cb_ident_idr, keep, drop->cl_cb_ident); + xa_lock(&nn->cb_ids); + __xa_store(&nn->cb_ids, drop->cl_cb_ident, keep, 0); keep->cl_cb_ident = drop->cl_cb_ident; - - idr_replace(&nn->cb_ident_idr, drop, save); + __xa_store(&nn->cb_ids, save, drop, 0); drop->cl_cb_ident = save; - - spin_unlock(&nn->nfs_client_lock); + xa_unlock(&nn->cb_ids); } static bool nfs4_match_client_owner_id(const struct nfs_client *clp1, @@ -774,11 +764,11 @@ nfs4_find_client_ident(struct net *net, int cb_ident) struct nfs_client *clp; struct nfs_net *nn = net_generic(net, nfs_net_id); - spin_lock(&nn->nfs_client_lock); - clp = idr_find(&nn->cb_ident_idr, cb_ident); + xa_lock(&nn->cb_ids); + clp = xa_load(&nn->cb_ids, cb_ident); if (clp) refcount_inc(&clp->cl_count); - spin_unlock(&nn->nfs_client_lock); + xa_unlock(&nn->cb_ids); return clp; } -- 2.50.1