mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
nfsd: don't allocate the versions array.
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>
This commit is contained in:
parent
c9f10f811c
commit
73598a0cfb
@ -10,7 +10,7 @@
|
||||
#define NFSCACHE_H
|
||||
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include "netns.h"
|
||||
#include "nfsd.h"
|
||||
|
||||
/*
|
||||
* Representation of a reply cache entry.
|
||||
|
@ -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);
|
||||
|
@ -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 = {
|
||||
|
@ -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
|
||||
@ -37,7 +35,14 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
102
fs/nfsd/nfssvc.c
102
fs/nfsd/nfssvc.c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user