mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +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
|
#define NFSCACHE_H
|
||||||
|
|
||||||
#include <linux/sunrpc/svc.h>
|
#include <linux/sunrpc/svc.h>
|
||||||
#include "netns.h"
|
#include "nfsd.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Representation of a reply cache entry.
|
* Representation of a reply cache entry.
|
||||||
|
@ -152,8 +152,8 @@ struct nfsd_net {
|
|||||||
/*
|
/*
|
||||||
* Version information
|
* Version information
|
||||||
*/
|
*/
|
||||||
bool *nfsd_versions;
|
bool nfsd_versions[NFSD_MAXVERS + 1];
|
||||||
bool *nfsd4_minorversions;
|
bool nfsd4_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Duplicate reply cache
|
* Duplicate reply cache
|
||||||
@ -219,8 +219,6 @@ struct nfsd_net {
|
|||||||
#define nfsd_netns_ready(nn) ((nn)->sessionid_hashtbl)
|
#define nfsd_netns_ready(nn) ((nn)->sessionid_hashtbl)
|
||||||
|
|
||||||
extern bool nfsd_support_version(int vers);
|
extern bool nfsd_support_version(int vers);
|
||||||
extern void nfsd_netns_free_versions(struct nfsd_net *nn);
|
|
||||||
|
|
||||||
extern unsigned int nfsd_net_id;
|
extern unsigned int nfsd_net_id;
|
||||||
|
|
||||||
void nfsd_copy_write_verifier(__be32 verf[2], struct nfsd_net *nn);
|
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)
|
static __net_init int nfsd_net_init(struct net *net)
|
||||||
{
|
{
|
||||||
int retval;
|
|
||||||
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
|
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
|
||||||
|
int retval;
|
||||||
|
int i;
|
||||||
|
|
||||||
retval = nfsd_export_init(net);
|
retval = nfsd_export_init(net);
|
||||||
if (retval)
|
if (retval)
|
||||||
@ -2246,8 +2247,10 @@ static __net_init int nfsd_net_init(struct net *net)
|
|||||||
goto out_repcache_error;
|
goto out_repcache_error;
|
||||||
memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats));
|
memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats));
|
||||||
nn->nfsd_svcstats.program = &nfsd_program;
|
nn->nfsd_svcstats.program = &nfsd_program;
|
||||||
nn->nfsd_versions = NULL;
|
for (i = 0; i < sizeof(nn->nfsd_versions); i++)
|
||||||
nn->nfsd4_minorversions = NULL;
|
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_info.mutex = &nfsd_mutex;
|
||||||
nn->nfsd_serv = NULL;
|
nn->nfsd_serv = NULL;
|
||||||
nfsd4_init_leases_net(nn);
|
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);
|
percpu_counter_destroy_many(nn->counter, NFSD_STATS_COUNTERS_NUM);
|
||||||
nfsd_idmap_shutdown(net);
|
nfsd_idmap_shutdown(net);
|
||||||
nfsd_export_shutdown(net);
|
nfsd_export_shutdown(net);
|
||||||
nfsd_netns_free_versions(nn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pernet_operations nfsd_net_ops = {
|
static struct pernet_operations nfsd_net_ops = {
|
||||||
|
@ -23,9 +23,7 @@
|
|||||||
|
|
||||||
#include <uapi/linux/nfsd/debug.h>
|
#include <uapi/linux/nfsd/debug.h>
|
||||||
|
|
||||||
#include "netns.h"
|
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
#include "stats.h"
|
|
||||||
|
|
||||||
#undef ifdebug
|
#undef ifdebug
|
||||||
#ifdef CONFIG_SUNRPC_DEBUG
|
#ifdef CONFIG_SUNRPC_DEBUG
|
||||||
@ -37,7 +35,14 @@
|
|||||||
/*
|
/*
|
||||||
* nfsd version
|
* nfsd version
|
||||||
*/
|
*/
|
||||||
|
#define NFSD_MINVERS 2
|
||||||
|
#define NFSD_MAXVERS 4
|
||||||
#define NFSD_SUPPORTED_MINOR_VERSION 2
|
#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.
|
* 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) */
|
#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)
|
#if defined(CONFIG_NFSD_V2)
|
||||||
[2] = &nfsd_version2,
|
[2] = &nfsd_version2,
|
||||||
#endif
|
#endif
|
||||||
@ -116,15 +116,12 @@ static const struct svc_version *nfsd_version[] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NFSD_MINVERS 2
|
|
||||||
#define NFSD_NRVERS ARRAY_SIZE(nfsd_version)
|
|
||||||
|
|
||||||
struct svc_program nfsd_program = {
|
struct svc_program nfsd_program = {
|
||||||
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
|
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
|
||||||
.pg_next = &nfsd_acl_program,
|
.pg_next = &nfsd_acl_program,
|
||||||
#endif
|
#endif
|
||||||
.pg_prog = NFS_PROGRAM, /* program number */
|
.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_vers = nfsd_version, /* version table */
|
||||||
.pg_name = "nfsd", /* program name */
|
.pg_name = "nfsd", /* program name */
|
||||||
.pg_class = "nfsd", /* authentication class */
|
.pg_class = "nfsd", /* authentication class */
|
||||||
@ -135,78 +132,24 @@ struct svc_program nfsd_program = {
|
|||||||
|
|
||||||
bool nfsd_support_version(int vers)
|
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 nfsd_version[vers] != NULL;
|
||||||
return false;
|
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)
|
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;
|
return 0;
|
||||||
switch(change) {
|
switch(change) {
|
||||||
case NFSD_SET:
|
case NFSD_SET:
|
||||||
if (nn->nfsd_versions)
|
nn->nfsd_versions[vers] = nfsd_support_version(vers);
|
||||||
nn->nfsd_versions[vers] = nfsd_support_version(vers);
|
|
||||||
break;
|
break;
|
||||||
case NFSD_CLEAR:
|
case NFSD_CLEAR:
|
||||||
nfsd_netns_init_versions(nn);
|
nn->nfsd_versions[vers] = false;
|
||||||
if (nn->nfsd_versions)
|
|
||||||
nn->nfsd_versions[vers] = false;
|
|
||||||
break;
|
break;
|
||||||
case NFSD_TEST:
|
case NFSD_TEST:
|
||||||
if (nn->nfsd_versions)
|
return nn->nfsd_versions[vers];
|
||||||
return nn->nfsd_versions[vers];
|
|
||||||
fallthrough;
|
|
||||||
case NFSD_AVAIL:
|
case NFSD_AVAIL:
|
||||||
return nfsd_support_version(vers);
|
return nfsd_support_version(vers);
|
||||||
}
|
}
|
||||||
@ -233,23 +176,16 @@ int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change
|
|||||||
|
|
||||||
switch(change) {
|
switch(change) {
|
||||||
case NFSD_SET:
|
case NFSD_SET:
|
||||||
if (nn->nfsd4_minorversions) {
|
nfsd_vers(nn, 4, NFSD_SET);
|
||||||
nfsd_vers(nn, 4, NFSD_SET);
|
nn->nfsd4_minorversions[minorversion] =
|
||||||
nn->nfsd4_minorversions[minorversion] =
|
nfsd_vers(nn, 4, NFSD_TEST);
|
||||||
nfsd_vers(nn, 4, NFSD_TEST);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case NFSD_CLEAR:
|
case NFSD_CLEAR:
|
||||||
nfsd_netns_init_versions(nn);
|
nn->nfsd4_minorversions[minorversion] = false;
|
||||||
if (nn->nfsd4_minorversions) {
|
nfsd_adjust_nfsd_versions4(nn);
|
||||||
nn->nfsd4_minorversions[minorversion] = false;
|
|
||||||
nfsd_adjust_nfsd_versions4(nn);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case NFSD_TEST:
|
case NFSD_TEST:
|
||||||
if (nn->nfsd4_minorversions)
|
return nn->nfsd4_minorversions[minorversion];
|
||||||
return nn->nfsd4_minorversions[minorversion];
|
|
||||||
return nfsd_vers(nn, 4, NFSD_TEST);
|
|
||||||
case NFSD_AVAIL:
|
case NFSD_AVAIL:
|
||||||
return minorversion <= NFSD_SUPPORTED_MINOR_VERSION &&
|
return minorversion <= NFSD_SUPPORTED_MINOR_VERSION &&
|
||||||
nfsd_vers(nn, 4, NFSD_AVAIL);
|
nfsd_vers(nn, 4, NFSD_AVAIL);
|
||||||
@ -568,11 +504,11 @@ void nfsd_reset_versions(struct nfsd_net *nn)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NFSD_NRVERS; i++)
|
for (i = 0; i <= NFSD_MAXVERS; i++)
|
||||||
if (nfsd_vers(nn, i, NFSD_TEST))
|
if (nfsd_vers(nn, i, NFSD_TEST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < NFSD_NRVERS; i++)
|
for (i = 0; i <= NFSD_MAXVERS; i++)
|
||||||
if (i != 4)
|
if (i != 4)
|
||||||
nfsd_vers(nn, i, NFSD_SET);
|
nfsd_vers(nn, i, NFSD_SET);
|
||||||
else {
|
else {
|
||||||
@ -905,17 +841,17 @@ nfsd_init_request(struct svc_rqst *rqstp,
|
|||||||
if (likely(nfsd_vers(nn, rqstp->rq_vers, NFSD_TEST)))
|
if (likely(nfsd_vers(nn, rqstp->rq_vers, NFSD_TEST)))
|
||||||
return svc_generic_init_request(rqstp, progp, ret);
|
return svc_generic_init_request(rqstp, progp, ret);
|
||||||
|
|
||||||
ret->mismatch.lovers = NFSD_NRVERS;
|
ret->mismatch.lovers = NFSD_MAXVERS + 1;
|
||||||
for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
|
for (i = NFSD_MINVERS; i <= NFSD_MAXVERS; i++) {
|
||||||
if (nfsd_vers(nn, i, NFSD_TEST)) {
|
if (nfsd_vers(nn, i, NFSD_TEST)) {
|
||||||
ret->mismatch.lovers = i;
|
ret->mismatch.lovers = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret->mismatch.lovers == NFSD_NRVERS)
|
if (ret->mismatch.lovers > NFSD_MAXVERS)
|
||||||
return rpc_prog_unavail;
|
return rpc_prog_unavail;
|
||||||
ret->mismatch.hivers = NFSD_MINVERS;
|
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)) {
|
if (nfsd_vers(nn, i, NFSD_TEST)) {
|
||||||
ret->mismatch.hivers = i;
|
ret->mismatch.hivers = i;
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user