]> www.infradead.org Git - users/willy/xarray.git/commitdiff
nfs: Convert cb_ident_idr to XArray
authorMatthew Wilcox <willy@infradead.org>
Sat, 3 Nov 2018 16:14:05 +0000 (12:14 -0400)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 8 Aug 2019 14:29:40 +0000 (10:29 -0400)
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 <willy@infradead.org>
fs/nfs/client.c
fs/nfs/netns.h
fs/nfs/nfs4client.c

index 30838304a0bf2393c214f822c868df07d4945490..b2560df4d081ef34b9f0241dd9405e0a7fbb1653 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/inet.h>
 #include <linux/in6.h>
 #include <linux/slab.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
 #include <net/ipv6.h>
 #include <linux/nfs_xdr.h>
 #include <linux/sunrpc/bc_xprt.h>
@@ -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));
 }
index c8374f74dce1142289ed717c5281b4600a2a44e5..bfb44770bf5244b376c311ef5f65942f90416474 100644 (file)
@@ -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];
index 616393a01c062ba99c79dd202166ef63691ece19..d2fa962710bf14552e43990ec753d3bfcee34ade 100644 (file)
  * 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;
 }