]> git.dujemihanovic.xyz Git - linux.git/commitdiff
nfsd: don't allocate the versions array.
authorNeilBrown <neilb@suse.de>
Wed, 7 Aug 2024 01:11:32 +0000 (21:11 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Fri, 20 Sep 2024 23:29:23 +0000 (19:29 -0400)
Instead of using kmalloc to allocate an array for storing active version
info, just declare an array to the max size - it is only 5 or so.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/cache.h
fs/nfsd/netns.h
fs/nfsd/nfsctl.c
fs/nfsd/nfsd.h
fs/nfsd/nfssvc.c

index 66a05fefae98eacd29e227de6883ffe56998fb18..bb7addef4a31044454a10edd31f444a760575517 100644 (file)
@@ -10,7 +10,7 @@
 #define NFSCACHE_H
 
 #include <linux/sunrpc/svc.h>
-#include "netns.h"
+#include "nfsd.h"
 
 /*
  * Representation of a reply cache entry.
index 14ec15656320903b2bdc9b2426b462498050e7d1..238fc4e56e539715d437a0bd9034f1dbb8ecf77e 100644 (file)
@@ -152,8 +152,8 @@ struct nfsd_net {
        /*
         * Version information
         */
-       bool *nfsd_versions;
-       bool *nfsd4_minorversions;
+       bool nfsd_versions[NFSD_MAXVERS + 1];
+       bool nfsd4_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1];
 
        /*
         * Duplicate reply cache
@@ -219,8 +219,6 @@ struct nfsd_net {
 #define nfsd_netns_ready(nn) ((nn)->sessionid_hashtbl)
 
 extern bool nfsd_support_version(int vers);
-extern void nfsd_netns_free_versions(struct nfsd_net *nn);
-
 extern unsigned int nfsd_net_id;
 
 void nfsd_copy_write_verifier(__be32 verf[2], struct nfsd_net *nn);
index 97c8c76b241b7cc7a516cf58329eb24f963aa1ca..965519995aeb56154c67c52a133bd6d03e29395c 100644 (file)
@@ -2231,8 +2231,9 @@ err_free_msg:
  */
 static __net_init int nfsd_net_init(struct net *net)
 {
-       int retval;
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+       int retval;
+       int i;
 
        retval = nfsd_export_init(net);
        if (retval)
@@ -2246,8 +2247,10 @@ static __net_init int nfsd_net_init(struct net *net)
                goto out_repcache_error;
        memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats));
        nn->nfsd_svcstats.program = &nfsd_program;
-       nn->nfsd_versions = NULL;
-       nn->nfsd4_minorversions = NULL;
+       for (i = 0; i < sizeof(nn->nfsd_versions); i++)
+               nn->nfsd_versions[i] = nfsd_support_version(i);
+       for (i = 0; i < sizeof(nn->nfsd4_minorversions); i++)
+               nn->nfsd4_minorversions[i] = nfsd_support_version(4);
        nn->nfsd_info.mutex = &nfsd_mutex;
        nn->nfsd_serv = NULL;
        nfsd4_init_leases_net(nn);
@@ -2278,7 +2281,6 @@ static __net_exit void nfsd_net_exit(struct net *net)
        percpu_counter_destroy_many(nn->counter, NFSD_STATS_COUNTERS_NUM);
        nfsd_idmap_shutdown(net);
        nfsd_export_shutdown(net);
-       nfsd_netns_free_versions(nn);
 }
 
 static struct pernet_operations nfsd_net_ops = {
index 39e109a7d56dca7a76f959ce4ab700fd9d471905..369c3b3ce53e77ab67152fe65a936f54322c310a 100644 (file)
@@ -23,9 +23,7 @@
 
 #include <uapi/linux/nfsd/debug.h>
 
-#include "netns.h"
 #include "export.h"
-#include "stats.h"
 
 #undef ifdebug
 #ifdef CONFIG_SUNRPC_DEBUG
 /*
  * nfsd version
  */
+#define NFSD_MINVERS                   2
+#define        NFSD_MAXVERS                    4
 #define NFSD_SUPPORTED_MINOR_VERSION   2
+bool nfsd_support_version(int vers);
+
+#include "netns.h"
+#include "stats.h"
+
 /*
  * Maximum blocksizes supported by daemon under various circumstances.
  */
index f25b26bc5670db380b5c055a2dc5a8fcd2f5449c..5bc4dc60ea4c2e5acc3323b864cae91406476688 100644 (file)
@@ -106,7 +106,7 @@ static struct svc_program   nfsd_acl_program = {
 
 #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
 
-static const struct svc_version *nfsd_version[] = {
+static const struct svc_version *nfsd_version[NFSD_MAXVERS+1] = {
 #if defined(CONFIG_NFSD_V2)
        [2] = &nfsd_version2,
 #endif
@@ -116,15 +116,12 @@ static const struct svc_version *nfsd_version[] = {
 #endif
 };
 
-#define NFSD_MINVERS           2
-#define NFSD_NRVERS            ARRAY_SIZE(nfsd_version)
-
 struct svc_program             nfsd_program = {
 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
        .pg_next                = &nfsd_acl_program,
 #endif
        .pg_prog                = NFS_PROGRAM,          /* program number */
-       .pg_nvers               = NFSD_NRVERS,          /* nr of entries in nfsd_version */
+       .pg_nvers               = NFSD_MAXVERS+1,       /* nr of entries in nfsd_version */
        .pg_vers                = nfsd_version,         /* version table */
        .pg_name                = "nfsd",               /* program name */
        .pg_class               = "nfsd",               /* authentication class */
@@ -135,78 +132,24 @@ struct svc_program                nfsd_program = {
 
 bool nfsd_support_version(int vers)
 {
-       if (vers >= NFSD_MINVERS && vers < NFSD_NRVERS)
+       if (vers >= NFSD_MINVERS && vers <= NFSD_MAXVERS)
                return nfsd_version[vers] != NULL;
        return false;
 }
 
-static bool *
-nfsd_alloc_versions(void)
-{
-       bool *vers = kmalloc_array(NFSD_NRVERS, sizeof(bool), GFP_KERNEL);
-       unsigned i;
-
-       if (vers) {
-               /* All compiled versions are enabled by default */
-               for (i = 0; i < NFSD_NRVERS; i++)
-                       vers[i] = nfsd_support_version(i);
-       }
-       return vers;
-}
-
-static bool *
-nfsd_alloc_minorversions(void)
-{
-       bool *vers = kmalloc_array(NFSD_SUPPORTED_MINOR_VERSION + 1,
-                       sizeof(bool), GFP_KERNEL);
-       unsigned i;
-
-       if (vers) {
-               /* All minor versions are enabled by default */
-               for (i = 0; i <= NFSD_SUPPORTED_MINOR_VERSION; i++)
-                       vers[i] = nfsd_support_version(4);
-       }
-       return vers;
-}
-
-void
-nfsd_netns_free_versions(struct nfsd_net *nn)
-{
-       kfree(nn->nfsd_versions);
-       kfree(nn->nfsd4_minorversions);
-       nn->nfsd_versions = NULL;
-       nn->nfsd4_minorversions = NULL;
-}
-
-static void
-nfsd_netns_init_versions(struct nfsd_net *nn)
-{
-       if (!nn->nfsd_versions) {
-               nn->nfsd_versions = nfsd_alloc_versions();
-               nn->nfsd4_minorversions = nfsd_alloc_minorversions();
-               if (!nn->nfsd_versions || !nn->nfsd4_minorversions)
-                       nfsd_netns_free_versions(nn);
-       }
-}
-
 int nfsd_vers(struct nfsd_net *nn, int vers, enum vers_op change)
 {
-       if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
+       if (vers < NFSD_MINVERS || vers > NFSD_MAXVERS)
                return 0;
        switch(change) {
        case NFSD_SET:
-               if (nn->nfsd_versions)
-                       nn->nfsd_versions[vers] = nfsd_support_version(vers);
+               nn->nfsd_versions[vers] = nfsd_support_version(vers);
                break;
        case NFSD_CLEAR:
-               nfsd_netns_init_versions(nn);
-               if (nn->nfsd_versions)
-                       nn->nfsd_versions[vers] = false;
+               nn->nfsd_versions[vers] = false;
                break;
        case NFSD_TEST:
-               if (nn->nfsd_versions)
-                       return nn->nfsd_versions[vers];
-               fallthrough;
+               return nn->nfsd_versions[vers];
        case NFSD_AVAIL:
                return nfsd_support_version(vers);
        }
@@ -233,23 +176,16 @@ int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change
 
        switch(change) {
        case NFSD_SET:
-               if (nn->nfsd4_minorversions) {
-                       nfsd_vers(nn, 4, NFSD_SET);
-                       nn->nfsd4_minorversions[minorversion] =
-                               nfsd_vers(nn, 4, NFSD_TEST);
-               }
+               nfsd_vers(nn, 4, NFSD_SET);
+               nn->nfsd4_minorversions[minorversion] =
+                       nfsd_vers(nn, 4, NFSD_TEST);
                break;
        case NFSD_CLEAR:
-               nfsd_netns_init_versions(nn);
-               if (nn->nfsd4_minorversions) {
-                       nn->nfsd4_minorversions[minorversion] = false;
-                       nfsd_adjust_nfsd_versions4(nn);
-               }
+               nn->nfsd4_minorversions[minorversion] = false;
+               nfsd_adjust_nfsd_versions4(nn);
                break;
        case NFSD_TEST:
-               if (nn->nfsd4_minorversions)
-                       return nn->nfsd4_minorversions[minorversion];
-               return nfsd_vers(nn, 4, NFSD_TEST);
+               return nn->nfsd4_minorversions[minorversion];
        case NFSD_AVAIL:
                return minorversion <= NFSD_SUPPORTED_MINOR_VERSION &&
                        nfsd_vers(nn, 4, NFSD_AVAIL);
@@ -568,11 +504,11 @@ void nfsd_reset_versions(struct nfsd_net *nn)
 {
        int i;
 
-       for (i = 0; i < NFSD_NRVERS; i++)
+       for (i = 0; i <= NFSD_MAXVERS; i++)
                if (nfsd_vers(nn, i, NFSD_TEST))
                        return;
 
-       for (i = 0; i < NFSD_NRVERS; i++)
+       for (i = 0; i <= NFSD_MAXVERS; i++)
                if (i != 4)
                        nfsd_vers(nn, i, NFSD_SET);
                else {
@@ -905,17 +841,17 @@ nfsd_init_request(struct svc_rqst *rqstp,
        if (likely(nfsd_vers(nn, rqstp->rq_vers, NFSD_TEST)))
                return svc_generic_init_request(rqstp, progp, ret);
 
-       ret->mismatch.lovers = NFSD_NRVERS;
-       for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+       ret->mismatch.lovers = NFSD_MAXVERS + 1;
+       for (i = NFSD_MINVERS; i <= NFSD_MAXVERS; i++) {
                if (nfsd_vers(nn, i, NFSD_TEST)) {
                        ret->mismatch.lovers = i;
                        break;
                }
        }
-       if (ret->mismatch.lovers == NFSD_NRVERS)
+       if (ret->mismatch.lovers > NFSD_MAXVERS)
                return rpc_prog_unavail;
        ret->mismatch.hivers = NFSD_MINVERS;
-       for (i = NFSD_NRVERS - 1; i >= NFSD_MINVERS; i--) {
+       for (i = NFSD_MAXVERS; i >= NFSD_MINVERS; i--) {
                if (nfsd_vers(nn, i, NFSD_TEST)) {
                        ret->mismatch.hivers = i;
                        break;