From f890edbbeff6928b7db0c6179a9036cbd4f0efbf Mon Sep 17 00:00:00 2001 From: Stanislav Kinsbursky Date: Thu, 29 Mar 2012 19:34:16 +0400 Subject: NFSd: remove hard-coded dereferences to name-to-id and id-to-name caches These dereferences to global static caches are redundant. They also prevents converting these caches into per-net ones. So this patch is cleanup + precursor of patch set,a which will make them per-net. Signed-off-by: Stanislav Kinsbursky Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4idmap.c | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) (limited to 'fs/nfsd/nfs4idmap.c') diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index 322d11ce06a4..2ff44708ea96 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c @@ -183,8 +183,9 @@ warn_no_idmapd(struct cache_detail *detail, int has_died) static int idtoname_parse(struct cache_detail *, char *, int); -static struct ent *idtoname_lookup(struct ent *); -static struct ent *idtoname_update(struct ent *, struct ent *); +static struct ent *idtoname_lookup(struct cache_detail *, struct ent *); +static struct ent *idtoname_update(struct cache_detail *, struct ent *, + struct ent *); static struct cache_detail idtoname_cache = { .owner = THIS_MODULE, @@ -244,7 +245,7 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen) goto out; error = -ENOMEM; - res = idtoname_lookup(&ent); + res = idtoname_lookup(cd, &ent); if (!res) goto out; @@ -260,11 +261,11 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen) else memcpy(ent.name, buf1, sizeof(ent.name)); error = -ENOMEM; - res = idtoname_update(&ent, res); + res = idtoname_update(cd, &ent, res); if (res == NULL) goto out; - cache_put(&res->h, &idtoname_cache); + cache_put(&res->h, cd); error = 0; out: @@ -275,10 +276,9 @@ out: static struct ent * -idtoname_lookup(struct ent *item) +idtoname_lookup(struct cache_detail *cd, struct ent *item) { - struct cache_head *ch = sunrpc_cache_lookup(&idtoname_cache, - &item->h, + struct cache_head *ch = sunrpc_cache_lookup(cd, &item->h, idtoname_hash(item)); if (ch) return container_of(ch, struct ent, h); @@ -287,10 +287,9 @@ idtoname_lookup(struct ent *item) } static struct ent * -idtoname_update(struct ent *new, struct ent *old) +idtoname_update(struct cache_detail *cd, struct ent *new, struct ent *old) { - struct cache_head *ch = sunrpc_cache_update(&idtoname_cache, - &new->h, &old->h, + struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h, idtoname_hash(new)); if (ch) return container_of(ch, struct ent, h); @@ -359,8 +358,9 @@ nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) return 0; } -static struct ent *nametoid_lookup(struct ent *); -static struct ent *nametoid_update(struct ent *, struct ent *); +static struct ent *nametoid_lookup(struct cache_detail *, struct ent *); +static struct ent *nametoid_update(struct cache_detail *, struct ent *, + struct ent *); static int nametoid_parse(struct cache_detail *, char *, int); static struct cache_detail nametoid_cache = { @@ -426,14 +426,14 @@ nametoid_parse(struct cache_detail *cd, char *buf, int buflen) set_bit(CACHE_NEGATIVE, &ent.h.flags); error = -ENOMEM; - res = nametoid_lookup(&ent); + res = nametoid_lookup(cd, &ent); if (res == NULL) goto out; - res = nametoid_update(&ent, res); + res = nametoid_update(cd, &ent, res); if (res == NULL) goto out; - cache_put(&res->h, &nametoid_cache); + cache_put(&res->h, cd); error = 0; out: kfree(buf1); @@ -443,10 +443,9 @@ out: static struct ent * -nametoid_lookup(struct ent *item) +nametoid_lookup(struct cache_detail *cd, struct ent *item) { - struct cache_head *ch = sunrpc_cache_lookup(&nametoid_cache, - &item->h, + struct cache_head *ch = sunrpc_cache_lookup(cd, &item->h, nametoid_hash(item)); if (ch) return container_of(ch, struct ent, h); @@ -455,10 +454,9 @@ nametoid_lookup(struct ent *item) } static struct ent * -nametoid_update(struct ent *new, struct ent *old) +nametoid_update(struct cache_detail *cd, struct ent *new, struct ent *old) { - struct cache_head *ch = sunrpc_cache_update(&nametoid_cache, - &new->h, &old->h, + struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h, nametoid_hash(new)); if (ch) return container_of(ch, struct ent, h); @@ -493,12 +491,12 @@ nfsd_idmap_shutdown(void) static int idmap_lookup(struct svc_rqst *rqstp, - struct ent *(*lookup_fn)(struct ent *), struct ent *key, - struct cache_detail *detail, struct ent **item) + struct ent *(*lookup_fn)(struct cache_detail *, struct ent *), + struct ent *key, struct cache_detail *detail, struct ent **item) { int ret; - *item = lookup_fn(key); + *item = lookup_fn(detail, key); if (!*item) return -ENOMEM; retry: @@ -506,7 +504,7 @@ idmap_lookup(struct svc_rqst *rqstp, if (ret == -ETIMEDOUT) { struct ent *prev_item = *item; - *item = lookup_fn(key); + *item = lookup_fn(detail, key); if (*item != prev_item) goto retry; cache_put(&(*item)->h, detail); -- cgit v1.2.3 From 43ec1a20bfbe1fbf6df6bf5a7b9c88ea090dbfcd Mon Sep 17 00:00:00 2001 From: Stanislav Kinsbursky Date: Wed, 11 Apr 2012 17:32:44 +0400 Subject: nfsd: pass network context to idmap init/exit functions These functions will be called from per-net operations. Signed-off-by: Stanislav Kinsbursky Signed-off-by: J. Bruce Fields --- fs/nfsd/idmap.h | 8 ++++---- fs/nfsd/nfs4idmap.c | 14 +++++++------- fs/nfsd/nfsctl.c | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'fs/nfsd/nfs4idmap.c') diff --git a/fs/nfsd/idmap.h b/fs/nfsd/idmap.h index 2f3be1321534..9d513efc01ba 100644 --- a/fs/nfsd/idmap.h +++ b/fs/nfsd/idmap.h @@ -42,14 +42,14 @@ #define IDMAP_NAMESZ 128 #ifdef CONFIG_NFSD_V4 -int nfsd_idmap_init(void); -void nfsd_idmap_shutdown(void); +int nfsd_idmap_init(struct net *); +void nfsd_idmap_shutdown(struct net *); #else -static inline int nfsd_idmap_init(void) +static inline int nfsd_idmap_init(struct net *net) { return 0; } -static inline void nfsd_idmap_shutdown(void) +static inline void nfsd_idmap_shutdown(struct net *net) { } #endif diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index 2ff44708ea96..d37405f7000a 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c @@ -469,24 +469,24 @@ nametoid_update(struct cache_detail *cd, struct ent *new, struct ent *old) */ int -nfsd_idmap_init(void) +nfsd_idmap_init(struct net *net) { int rv; - rv = cache_register_net(&idtoname_cache, &init_net); + rv = cache_register_net(&idtoname_cache, net); if (rv) return rv; - rv = cache_register_net(&nametoid_cache, &init_net); + rv = cache_register_net(&nametoid_cache, net); if (rv) - cache_unregister_net(&idtoname_cache, &init_net); + cache_unregister_net(&idtoname_cache, net); return rv; } void -nfsd_idmap_shutdown(void) +nfsd_idmap_shutdown(struct net *net) { - cache_unregister_net(&idtoname_cache, &init_net); - cache_unregister_net(&nametoid_cache, &init_net); + cache_unregister_net(&idtoname_cache, net); + cache_unregister_net(&nametoid_cache, net); } static int diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 08cd87a9fb40..d6e8b85c6b7f 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1186,7 +1186,7 @@ static int __init init_nfsd(void) if (retval) goto out_free_stat; nfsd_lockd_init(); /* lockd->nfsd callbacks */ - retval = nfsd_idmap_init(); + retval = nfsd_idmap_init(&init_net); if (retval) goto out_free_lockd; retval = create_proc_exports_entry(); @@ -1200,7 +1200,7 @@ out_free_all: remove_proc_entry("fs/nfs/exports", NULL); remove_proc_entry("fs/nfs", NULL); out_free_idmap: - nfsd_idmap_shutdown(); + nfsd_idmap_shutdown(&init_net); out_free_lockd: nfsd_lockd_shutdown(); nfsd_reply_cache_shutdown(); @@ -1223,7 +1223,7 @@ static void __exit exit_nfsd(void) remove_proc_entry("fs/nfs", NULL); nfsd_stat_shutdown(); nfsd_lockd_shutdown(); - nfsd_idmap_shutdown(); + nfsd_idmap_shutdown(&init_net); nfsd4_free_slabs(); nfsd_fault_inject_cleanup(); unregister_filesystem(&nfsd_fs_type); -- cgit v1.2.3 From c2e76ef5e0716bc82364e6049e8023ffd5bbe395 Mon Sep 17 00:00:00 2001 From: Stanislav Kinsbursky Date: Wed, 11 Apr 2012 17:32:51 +0400 Subject: nfsd: make id-to-name cache allocated per network namespace context Signed-off-by: Stanislav Kinsbursky Signed-off-by: J. Bruce Fields --- fs/nfsd/netns.h | 3 +++ fs/nfsd/nfs4idmap.c | 33 +++++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 10 deletions(-) (limited to 'fs/nfsd/nfs4idmap.c') diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index 9794c6c7d133..948a718e24a4 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h @@ -31,6 +31,9 @@ struct nfsd_net { struct cache_detail *svc_expkey_cache; struct cache_detail *svc_export_cache; + + struct cache_detail *idtoname_cache; + }; extern int nfsd_net_id; diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index d37405f7000a..b285a693af8c 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c @@ -36,9 +36,11 @@ #include #include #include +#include #include #include "idmap.h" #include "nfsd.h" +#include "netns.h" /* * Turn off idmapping when using AUTH_SYS. @@ -107,8 +109,6 @@ ent_alloc(void) * ID -> Name cache */ -static struct cache_head *idtoname_table[ENT_HASHMAX]; - static uint32_t idtoname_hash(struct ent *ent) { @@ -187,10 +187,9 @@ static struct ent *idtoname_lookup(struct cache_detail *, struct ent *); static struct ent *idtoname_update(struct cache_detail *, struct ent *, struct ent *); -static struct cache_detail idtoname_cache = { +static struct cache_detail idtoname_cache_template = { .owner = THIS_MODULE, .hash_size = ENT_HASHMAX, - .hash_table = idtoname_table, .name = "nfs4.idtoname", .cache_put = ent_put, .cache_upcall = idtoname_upcall, @@ -472,21 +471,34 @@ int nfsd_idmap_init(struct net *net) { int rv; + struct nfsd_net *nn = net_generic(net, nfsd_net_id); - rv = cache_register_net(&idtoname_cache, net); + nn->idtoname_cache = cache_create_net(&idtoname_cache_template, net); + if (IS_ERR(nn->idtoname_cache)) + return PTR_ERR(nn->idtoname_cache); + rv = cache_register_net(nn->idtoname_cache, net); if (rv) - return rv; + goto destroy_idtoname_cache; rv = cache_register_net(&nametoid_cache, net); if (rv) - cache_unregister_net(&idtoname_cache, net); + goto unregister_idtoname_cache; + return 0; + +unregister_idtoname_cache: + cache_unregister_net(nn->idtoname_cache, net); +destroy_idtoname_cache: + cache_destroy_net(nn->idtoname_cache, net); return rv; } void nfsd_idmap_shutdown(struct net *net) { - cache_unregister_net(&idtoname_cache, net); + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + + cache_unregister_net(nn->idtoname_cache, net); cache_unregister_net(&nametoid_cache, net); + cache_destroy_net(nn->idtoname_cache, net); } static int @@ -553,9 +565,10 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) .type = type, }; int ret; + struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id); strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); - ret = idmap_lookup(rqstp, idtoname_lookup, &key, &idtoname_cache, &item); + ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item); if (ret == -ENOENT) return sprintf(name, "%u", id); if (ret) @@ -563,7 +576,7 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) ret = strlen(item->name); BUG_ON(ret > IDMAP_NAMESZ); memcpy(name, item->name, ret); - cache_put(&item->h, &idtoname_cache); + cache_put(&item->h, nn->idtoname_cache); return ret; } -- cgit v1.2.3 From 9e75a4dee08e8fe21f349e11c43955c34523bced Mon Sep 17 00:00:00 2001 From: Stanislav Kinsbursky Date: Wed, 11 Apr 2012 17:32:58 +0400 Subject: nfsd: make name-to-id cache allocated per network namespace context Signed-off-by: Stanislav Kinsbursky Signed-off-by: J. Bruce Fields --- fs/nfsd/netns.h | 2 +- fs/nfsd/nfs4idmap.c | 24 +++++++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'fs/nfsd/nfs4idmap.c') diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index 948a718e24a4..39365636b244 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h @@ -33,7 +33,7 @@ struct nfsd_net { struct cache_detail *svc_export_cache; struct cache_detail *idtoname_cache; - + struct cache_detail *nametoid_cache; }; extern int nfsd_net_id; diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index b285a693af8c..286a7f8f2024 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c @@ -301,8 +301,6 @@ idtoname_update(struct cache_detail *cd, struct ent *new, struct ent *old) * Name -> ID cache */ -static struct cache_head *nametoid_table[ENT_HASHMAX]; - static inline int nametoid_hash(struct ent *ent) { @@ -362,10 +360,9 @@ static struct ent *nametoid_update(struct cache_detail *, struct ent *, struct ent *); static int nametoid_parse(struct cache_detail *, char *, int); -static struct cache_detail nametoid_cache = { +static struct cache_detail nametoid_cache_template = { .owner = THIS_MODULE, .hash_size = ENT_HASHMAX, - .hash_table = nametoid_table, .name = "nfs4.nametoid", .cache_put = ent_put, .cache_upcall = nametoid_upcall, @@ -479,11 +476,18 @@ nfsd_idmap_init(struct net *net) rv = cache_register_net(nn->idtoname_cache, net); if (rv) goto destroy_idtoname_cache; - rv = cache_register_net(&nametoid_cache, net); - if (rv) + nn->nametoid_cache = cache_create_net(&nametoid_cache_template, net); + if (IS_ERR(nn->nametoid_cache)) { + rv = PTR_ERR(nn->idtoname_cache); goto unregister_idtoname_cache; + } + rv = cache_register_net(nn->nametoid_cache, net); + if (rv) + goto destroy_nametoid_cache; return 0; +destroy_nametoid_cache: + cache_destroy_net(nn->nametoid_cache, net); unregister_idtoname_cache: cache_unregister_net(nn->idtoname_cache, net); destroy_idtoname_cache: @@ -497,8 +501,9 @@ nfsd_idmap_shutdown(struct net *net) struct nfsd_net *nn = net_generic(net, nfsd_net_id); cache_unregister_net(nn->idtoname_cache, net); - cache_unregister_net(&nametoid_cache, net); + cache_unregister_net(nn->nametoid_cache, net); cache_destroy_net(nn->idtoname_cache, net); + cache_destroy_net(nn->nametoid_cache, net); } static int @@ -541,19 +546,20 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen .type = type, }; int ret; + struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id); if (namelen + 1 > sizeof(key.name)) return nfserr_badowner; memcpy(key.name, name, namelen); key.name[namelen] = '\0'; strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); - ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item); + ret = idmap_lookup(rqstp, nametoid_lookup, &key, nn->nametoid_cache, &item); if (ret == -ENOENT) return nfserr_badowner; if (ret) return nfserrno(ret); *id = item->id; - cache_put(&item->h, &nametoid_cache); + cache_put(&item->h, nn->nametoid_cache); return 0; } -- cgit v1.2.3