Skip to content

Commit 73598a0

Browse files
neilbrownchucklever
authored andcommitted
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 <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent c9f10f8 commit 73598a0

File tree

5 files changed

+35
-94
lines changed

5 files changed

+35
-94
lines changed

fs/nfsd/cache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#define NFSCACHE_H
1111

1212
#include <linux/sunrpc/svc.h>
13-
#include "netns.h"
13+
#include "nfsd.h"
1414

1515
/*
1616
* Representation of a reply cache entry.

fs/nfsd/netns.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ struct nfsd_net {
152152
/*
153153
* Version information
154154
*/
155-
bool *nfsd_versions;
156-
bool *nfsd4_minorversions;
155+
bool nfsd_versions[NFSD_MAXVERS + 1];
156+
bool nfsd4_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1];
157157

158158
/*
159159
* Duplicate reply cache
@@ -219,8 +219,6 @@ struct nfsd_net {
219219
#define nfsd_netns_ready(nn) ((nn)->sessionid_hashtbl)
220220

221221
extern bool nfsd_support_version(int vers);
222-
extern void nfsd_netns_free_versions(struct nfsd_net *nn);
223-
224222
extern unsigned int nfsd_net_id;
225223

226224
void nfsd_copy_write_verifier(__be32 verf[2], struct nfsd_net *nn);

fs/nfsd/nfsctl.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,8 +2231,9 @@ int nfsd_nl_pool_mode_get_doit(struct sk_buff *skb, struct genl_info *info)
22312231
*/
22322232
static __net_init int nfsd_net_init(struct net *net)
22332233
{
2234-
int retval;
22352234
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
2235+
int retval;
2236+
int i;
22362237

22372238
retval = nfsd_export_init(net);
22382239
if (retval)
@@ -2246,8 +2247,10 @@ static __net_init int nfsd_net_init(struct net *net)
22462247
goto out_repcache_error;
22472248
memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats));
22482249
nn->nfsd_svcstats.program = &nfsd_program;
2249-
nn->nfsd_versions = NULL;
2250-
nn->nfsd4_minorversions = NULL;
2250+
for (i = 0; i < sizeof(nn->nfsd_versions); i++)
2251+
nn->nfsd_versions[i] = nfsd_support_version(i);
2252+
for (i = 0; i < sizeof(nn->nfsd4_minorversions); i++)
2253+
nn->nfsd4_minorversions[i] = nfsd_support_version(4);
22512254
nn->nfsd_info.mutex = &nfsd_mutex;
22522255
nn->nfsd_serv = NULL;
22532256
nfsd4_init_leases_net(nn);
@@ -2278,7 +2281,6 @@ static __net_exit void nfsd_net_exit(struct net *net)
22782281
percpu_counter_destroy_many(nn->counter, NFSD_STATS_COUNTERS_NUM);
22792282
nfsd_idmap_shutdown(net);
22802283
nfsd_export_shutdown(net);
2281-
nfsd_netns_free_versions(nn);
22822284
}
22832285

22842286
static struct pernet_operations nfsd_net_ops = {

fs/nfsd/nfsd.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323

2424
#include <uapi/linux/nfsd/debug.h>
2525

26-
#include "netns.h"
2726
#include "export.h"
28-
#include "stats.h"
2927

3028
#undef ifdebug
3129
#ifdef CONFIG_SUNRPC_DEBUG
@@ -37,7 +35,14 @@
3735
/*
3836
* nfsd version
3937
*/
38+
#define NFSD_MINVERS 2
39+
#define NFSD_MAXVERS 4
4040
#define NFSD_SUPPORTED_MINOR_VERSION 2
41+
bool nfsd_support_version(int vers);
42+
43+
#include "netns.h"
44+
#include "stats.h"
45+
4146
/*
4247
* Maximum blocksizes supported by daemon under various circumstances.
4348
*/

fs/nfsd/nfssvc.c

Lines changed: 19 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static struct svc_program nfsd_acl_program = {
106106

107107
#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
108108

109-
static const struct svc_version *nfsd_version[] = {
109+
static const struct svc_version *nfsd_version[NFSD_MAXVERS+1] = {
110110
#if defined(CONFIG_NFSD_V2)
111111
[2] = &nfsd_version2,
112112
#endif
@@ -116,15 +116,12 @@ static const struct svc_version *nfsd_version[] = {
116116
#endif
117117
};
118118

119-
#define NFSD_MINVERS 2
120-
#define NFSD_NRVERS ARRAY_SIZE(nfsd_version)
121-
122119
struct svc_program nfsd_program = {
123120
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
124121
.pg_next = &nfsd_acl_program,
125122
#endif
126123
.pg_prog = NFS_PROGRAM, /* program number */
127-
.pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */
124+
.pg_nvers = NFSD_MAXVERS+1, /* nr of entries in nfsd_version */
128125
.pg_vers = nfsd_version, /* version table */
129126
.pg_name = "nfsd", /* program name */
130127
.pg_class = "nfsd", /* authentication class */
@@ -135,78 +132,24 @@ struct svc_program nfsd_program = {
135132

136133
bool nfsd_support_version(int vers)
137134
{
138-
if (vers >= NFSD_MINVERS && vers < NFSD_NRVERS)
135+
if (vers >= NFSD_MINVERS && vers <= NFSD_MAXVERS)
139136
return nfsd_version[vers] != NULL;
140137
return false;
141138
}
142139

143-
static bool *
144-
nfsd_alloc_versions(void)
145-
{
146-
bool *vers = kmalloc_array(NFSD_NRVERS, sizeof(bool), GFP_KERNEL);
147-
unsigned i;
148-
149-
if (vers) {
150-
/* All compiled versions are enabled by default */
151-
for (i = 0; i < NFSD_NRVERS; i++)
152-
vers[i] = nfsd_support_version(i);
153-
}
154-
return vers;
155-
}
156-
157-
static bool *
158-
nfsd_alloc_minorversions(void)
159-
{
160-
bool *vers = kmalloc_array(NFSD_SUPPORTED_MINOR_VERSION + 1,
161-
sizeof(bool), GFP_KERNEL);
162-
unsigned i;
163-
164-
if (vers) {
165-
/* All minor versions are enabled by default */
166-
for (i = 0; i <= NFSD_SUPPORTED_MINOR_VERSION; i++)
167-
vers[i] = nfsd_support_version(4);
168-
}
169-
return vers;
170-
}
171-
172-
void
173-
nfsd_netns_free_versions(struct nfsd_net *nn)
174-
{
175-
kfree(nn->nfsd_versions);
176-
kfree(nn->nfsd4_minorversions);
177-
nn->nfsd_versions = NULL;
178-
nn->nfsd4_minorversions = NULL;
179-
}
180-
181-
static void
182-
nfsd_netns_init_versions(struct nfsd_net *nn)
183-
{
184-
if (!nn->nfsd_versions) {
185-
nn->nfsd_versions = nfsd_alloc_versions();
186-
nn->nfsd4_minorversions = nfsd_alloc_minorversions();
187-
if (!nn->nfsd_versions || !nn->nfsd4_minorversions)
188-
nfsd_netns_free_versions(nn);
189-
}
190-
}
191-
192140
int nfsd_vers(struct nfsd_net *nn, int vers, enum vers_op change)
193141
{
194-
if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
142+
if (vers < NFSD_MINVERS || vers > NFSD_MAXVERS)
195143
return 0;
196144
switch(change) {
197145
case NFSD_SET:
198-
if (nn->nfsd_versions)
199-
nn->nfsd_versions[vers] = nfsd_support_version(vers);
146+
nn->nfsd_versions[vers] = nfsd_support_version(vers);
200147
break;
201148
case NFSD_CLEAR:
202-
nfsd_netns_init_versions(nn);
203-
if (nn->nfsd_versions)
204-
nn->nfsd_versions[vers] = false;
149+
nn->nfsd_versions[vers] = false;
205150
break;
206151
case NFSD_TEST:
207-
if (nn->nfsd_versions)
208-
return nn->nfsd_versions[vers];
209-
fallthrough;
152+
return nn->nfsd_versions[vers];
210153
case NFSD_AVAIL:
211154
return nfsd_support_version(vers);
212155
}
@@ -233,23 +176,16 @@ int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change
233176

234177
switch(change) {
235178
case NFSD_SET:
236-
if (nn->nfsd4_minorversions) {
237-
nfsd_vers(nn, 4, NFSD_SET);
238-
nn->nfsd4_minorversions[minorversion] =
239-
nfsd_vers(nn, 4, NFSD_TEST);
240-
}
179+
nfsd_vers(nn, 4, NFSD_SET);
180+
nn->nfsd4_minorversions[minorversion] =
181+
nfsd_vers(nn, 4, NFSD_TEST);
241182
break;
242183
case NFSD_CLEAR:
243-
nfsd_netns_init_versions(nn);
244-
if (nn->nfsd4_minorversions) {
245-
nn->nfsd4_minorversions[minorversion] = false;
246-
nfsd_adjust_nfsd_versions4(nn);
247-
}
184+
nn->nfsd4_minorversions[minorversion] = false;
185+
nfsd_adjust_nfsd_versions4(nn);
248186
break;
249187
case NFSD_TEST:
250-
if (nn->nfsd4_minorversions)
251-
return nn->nfsd4_minorversions[minorversion];
252-
return nfsd_vers(nn, 4, NFSD_TEST);
188+
return nn->nfsd4_minorversions[minorversion];
253189
case NFSD_AVAIL:
254190
return minorversion <= NFSD_SUPPORTED_MINOR_VERSION &&
255191
nfsd_vers(nn, 4, NFSD_AVAIL);
@@ -568,11 +504,11 @@ void nfsd_reset_versions(struct nfsd_net *nn)
568504
{
569505
int i;
570506

571-
for (i = 0; i < NFSD_NRVERS; i++)
507+
for (i = 0; i <= NFSD_MAXVERS; i++)
572508
if (nfsd_vers(nn, i, NFSD_TEST))
573509
return;
574510

575-
for (i = 0; i < NFSD_NRVERS; i++)
511+
for (i = 0; i <= NFSD_MAXVERS; i++)
576512
if (i != 4)
577513
nfsd_vers(nn, i, NFSD_SET);
578514
else {
@@ -905,17 +841,17 @@ nfsd_init_request(struct svc_rqst *rqstp,
905841
if (likely(nfsd_vers(nn, rqstp->rq_vers, NFSD_TEST)))
906842
return svc_generic_init_request(rqstp, progp, ret);
907843

908-
ret->mismatch.lovers = NFSD_NRVERS;
909-
for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
844+
ret->mismatch.lovers = NFSD_MAXVERS + 1;
845+
for (i = NFSD_MINVERS; i <= NFSD_MAXVERS; i++) {
910846
if (nfsd_vers(nn, i, NFSD_TEST)) {
911847
ret->mismatch.lovers = i;
912848
break;
913849
}
914850
}
915-
if (ret->mismatch.lovers == NFSD_NRVERS)
851+
if (ret->mismatch.lovers > NFSD_MAXVERS)
916852
return rpc_prog_unavail;
917853
ret->mismatch.hivers = NFSD_MINVERS;
918-
for (i = NFSD_NRVERS - 1; i >= NFSD_MINVERS; i--) {
854+
for (i = NFSD_MAXVERS; i >= NFSD_MINVERS; i--) {
919855
if (nfsd_vers(nn, i, NFSD_TEST)) {
920856
ret->mismatch.hivers = i;
921857
break;

0 commit comments

Comments
 (0)