On Sat, 03 Aug 2024, NeilBrown wrote: > On Sat, 03 Aug 2024, Mike Snitzer wrote: > > On Mon, Jul 15, 2024 at 05:14:17PM +1000, NeilBrown wrote: > > > Instead of using kmalloc to allocate an array for storing active version > > > info, just declare and array to the max size - it is only 5 or so. > > > > > > Signed-off-by: NeilBrown <neilb@xxxxxxx> > > > --- > > > fs/nfs/nfs4state.c | 2 + > > > fs/nfsd/cache.h | 2 +- > > > fs/nfsd/netns.h | 6 +-- > > > fs/nfsd/nfsctl.c | 10 +++-- > > > fs/nfsd/nfsd.h | 9 +++- > > > fs/nfsd/nfssvc.c | 100 ++++++++------------------------------------- > > > 6 files changed, 36 insertions(+), 93 deletions(-) > > > > > > diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c > > > index 5b452411e8fd..68c663626480 100644 > > > --- a/fs/nfs/nfs4state.c > > > +++ b/fs/nfs/nfs4state.c > > > @@ -1953,6 +1953,8 @@ static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recov > > > if (lost_locks) > > > pr_warn("NFS: %s: lost %d locks\n", > > > clp->cl_hostname, lost_locks); > > > + nfs4_free_state_owners(&freeme); > > > + > > > set_bit(ops->owner_flag_bit, &sp->so_flags); > > > nfs4_put_state_owner(sp); > > > status = nfs4_recovery_handle_error(clp, status); > > > > Hey Neil, > > > > This call to nfs4_free_state_owners() feels out of place given the > > rest of this patch. Was it meant to be folded into a different > > patch? > > I think I was writing a different patch (there is a case where the > lost-locks warning can be incorrect) and I got half way and stopped for > some reason. Then later I wanted to do this patch and did "git stash" > but I hadn't saved all my work. So when I later did a "save all > buffers" that change went into the wrong patch. > > I'll follow up on Monday - thanks for noticing and letting me know! Chuck / Jeff - could you please just remove the change to fs/nfs/ from this patch - that is probably easier than me sending an incremental patch or a revised version. Thanks, NeilBrown > > NeilBrown > > > > > > Thanks, > > Mike > > > > > > > diff --git a/fs/nfsd/cache.h b/fs/nfsd/cache.h > > > index 66a05fefae98..bb7addef4a31 100644 > > > --- a/fs/nfsd/cache.h > > > +++ b/fs/nfsd/cache.h > > > @@ -10,7 +10,7 @@ > > > #define NFSCACHE_H > > > > > > #include <linux/sunrpc/svc.h> > > > -#include "netns.h" > > > +#include "nfsd.h" > > > > > > /* > > > * Representation of a reply cache entry. > > > diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h > > > index 14ec15656320..238fc4e56e53 100644 > > > --- a/fs/nfsd/netns.h > > > +++ b/fs/nfsd/netns.h > > > @@ -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); > > > diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c > > > index 9b47723fc110..5b0f2e0d7ccf 100644 > > > --- a/fs/nfsd/nfsctl.c > > > +++ b/fs/nfsd/nfsctl.c > > > @@ -2232,8 +2232,9 @@ int nfsd_nl_pool_mode_get_doit(struct sk_buff *skb, struct genl_info *info) > > > */ > > > 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) > > > @@ -2247,8 +2248,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); > > > @@ -2279,7 +2282,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 = { > > > diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h > > > index 39e109a7d56d..369c3b3ce53e 100644 > > > --- a/fs/nfsd/nfsd.h > > > +++ b/fs/nfsd/nfsd.h > > > @@ -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. > > > */ > > > diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c > > > index f25b26bc5670..4438cdcd4873 100644 > > > --- a/fs/nfsd/nfssvc.c > > > +++ b/fs/nfsd/nfssvc.c > > > @@ -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; > > > -- > > > 2.44.0 > > > > > > > > > > >