1 From 12dbb9402244cbc7a51b2ba6b2defcd50686f369 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Fri, 15 Jul 2022 16:54:52 -0700
4 Subject: NFSD: keep track of the number of v4 clients in the system
6 From: Dai Ngo <dai.ngo@oracle.com>
8 [ Upstream commit 0926c39515aa065a296e97dfc8790026f1e53f86 ]
10 Add counter nfs4_client_count to keep track of the total number
11 of v4 clients, including courtesy clients, in the system.
13 Signed-off-by: Dai Ngo <dai.ngo@oracle.com>
14 Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
16 fs/nfsd/netns.h | 2 ++
17 fs/nfsd/nfs4state.c | 10 ++++++++--
18 2 files changed, 10 insertions(+), 2 deletions(-)
20 diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
21 index 1b1a962a18041..ce864f001a3ee 100644
24 @@ -189,6 +189,8 @@ struct nfsd_net {
25 struct nfsd_fcache_disposal *fcache_disposal;
27 siphash_key_t siphash_key;
29 + atomic_t nfs4_client_count;
32 /* Simple check to find out if a given net was properly initialized */
33 diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
34 index a75f3f7c94d50..3d5ef021632b9 100644
35 --- a/fs/nfsd/nfs4state.c
36 +++ b/fs/nfsd/nfs4state.c
37 @@ -2066,7 +2066,8 @@ STALE_CLIENTID(clientid_t *clid, struct nfsd_net *nn)
38 * This type of memory management is somewhat inefficient, but we use it
39 * anyway since SETCLIENTID is not a common operation.
41 -static struct nfs4_client *alloc_client(struct xdr_netobj name)
42 +static struct nfs4_client *alloc_client(struct xdr_netobj name,
43 + struct nfsd_net *nn)
45 struct nfs4_client *clp;
47 @@ -2089,6 +2090,7 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
48 atomic_set(&clp->cl_rpc_users, 0);
49 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
50 clp->cl_state = NFSD4_ACTIVE;
51 + atomic_inc(&nn->nfs4_client_count);
52 atomic_set(&clp->cl_delegs_in_recall, 0);
53 INIT_LIST_HEAD(&clp->cl_idhash);
54 INIT_LIST_HEAD(&clp->cl_openowners);
55 @@ -2196,6 +2198,7 @@ static __be32 mark_client_expired_locked(struct nfs4_client *clp)
57 __destroy_client(struct nfs4_client *clp)
59 + struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
61 struct nfs4_openowner *oo;
62 struct nfs4_delegation *dp;
63 @@ -2239,6 +2242,7 @@ __destroy_client(struct nfs4_client *clp)
64 nfsd4_shutdown_callback(clp);
65 if (clp->cl_cb_conn.cb_xprt)
66 svc_xprt_put(clp->cl_cb_conn.cb_xprt);
67 + atomic_add_unless(&nn->nfs4_client_count, -1, 0);
69 wake_up_all(&expiry_wq);
71 @@ -2865,7 +2869,7 @@ static struct nfs4_client *create_client(struct xdr_netobj name,
72 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
73 struct dentry *dentries[ARRAY_SIZE(client_files)];
75 - clp = alloc_client(name);
76 + clp = alloc_client(name, nn);
80 @@ -4357,6 +4361,8 @@ void nfsd4_init_leases_net(struct nfsd_net *nn)
81 nn->clientid_base = prandom_u32();
82 nn->clientid_counter = nn->clientid_base + 1;
83 nn->s2s_cp_cl_id = nn->clientid_counter++;
85 + atomic_set(&nn->nfs4_client_count, 0);
88 static void init_nfs4_replay(struct nfs4_replay *rp)