]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
nfsd: Don't fail OP_SETCLIENTID when there are too many clients.
authorNeilBrown <neilb@suse.de>
Wed, 23 Oct 2024 22:10:42 +0000 (09:10 +1100)
committerChuck Lever <chuck.lever@oracle.com>
Tue, 19 Nov 2024 01:23:07 +0000 (20:23 -0500)
Failing OP_SETCLIENTID or OP_EXCHANGE_ID should only happen if there is
memory allocation failure.  Putting a hard limit on the number of
clients is not really helpful as it will either happen too early and
prevent clients that the server can easily handle, or too late and
allow clients when the server is swamped.

The calculated limit is still useful for expiring courtesy clients where
there are "too many" clients, but it shouldn't prevent the creation of
active clients.

Testing of lots of clients against small-mem servers reports repeated
NFS4ERR_DELAY responses which doesn't seem helpful.  There may have been
reports of similar problems in production use.

Also remove an outdated comment - we do use a slab cache.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/nfs4state.c

index 133117b6c7ccd2d896f09b5db6da48d606a79832..ddca893a88044d7483da4fda0999d25ddb17fe7f 100644 (file)
@@ -2231,21 +2231,16 @@ STALE_CLIENTID(clientid_t *clid, struct nfsd_net *nn)
        return 1;
 }
 
-/* 
- * XXX Should we use a slab cache ?
- * This type of memory management is somewhat inefficient, but we use it
- * anyway since SETCLIENTID is not a common operation.
- */
 static struct nfs4_client *alloc_client(struct xdr_netobj name,
                                struct nfsd_net *nn)
 {
        struct nfs4_client *clp;
        int i;
 
-       if (atomic_read(&nn->nfs4_client_count) >= nn->nfs4_max_clients) {
+       if (atomic_read(&nn->nfs4_client_count) >= nn->nfs4_max_clients &&
+           atomic_read(&nn->nfsd_courtesy_clients) > 0)
                mod_delayed_work(laundry_wq, &nn->laundromat_work, 0);
-               return NULL;
-       }
+
        clp = kmem_cache_zalloc(client_slab, GFP_KERNEL);
        if (clp == NULL)
                return NULL;