diff options
| -rw-r--r-- | fs/nfsd/netns.h | 3 | ||||
| -rw-r--r-- | fs/nfsd/nfs4idmap.c | 33 |
2 files changed, 26 insertions, 10 deletions
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 { | |||
| 31 | 31 | ||
| 32 | struct cache_detail *svc_expkey_cache; | 32 | struct cache_detail *svc_expkey_cache; |
| 33 | struct cache_detail *svc_export_cache; | 33 | struct cache_detail *svc_export_cache; |
| 34 | |||
| 35 | struct cache_detail *idtoname_cache; | ||
| 36 | |||
| 34 | }; | 37 | }; |
| 35 | 38 | ||
| 36 | extern int nfsd_net_id; | 39 | 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 @@ | |||
| 36 | #include <linux/seq_file.h> | 36 | #include <linux/seq_file.h> |
| 37 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
| 38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 39 | #include <linux/sunrpc/svc_xprt.h> | ||
| 39 | #include <net/net_namespace.h> | 40 | #include <net/net_namespace.h> |
| 40 | #include "idmap.h" | 41 | #include "idmap.h" |
| 41 | #include "nfsd.h" | 42 | #include "nfsd.h" |
| 43 | #include "netns.h" | ||
| 42 | 44 | ||
| 43 | /* | 45 | /* |
| 44 | * Turn off idmapping when using AUTH_SYS. | 46 | * Turn off idmapping when using AUTH_SYS. |
| @@ -107,8 +109,6 @@ ent_alloc(void) | |||
| 107 | * ID -> Name cache | 109 | * ID -> Name cache |
| 108 | */ | 110 | */ |
| 109 | 111 | ||
| 110 | static struct cache_head *idtoname_table[ENT_HASHMAX]; | ||
| 111 | |||
| 112 | static uint32_t | 112 | static uint32_t |
| 113 | idtoname_hash(struct ent *ent) | 113 | idtoname_hash(struct ent *ent) |
| 114 | { | 114 | { |
| @@ -187,10 +187,9 @@ static struct ent *idtoname_lookup(struct cache_detail *, struct ent *); | |||
| 187 | static struct ent *idtoname_update(struct cache_detail *, struct ent *, | 187 | static struct ent *idtoname_update(struct cache_detail *, struct ent *, |
| 188 | struct ent *); | 188 | struct ent *); |
| 189 | 189 | ||
| 190 | static struct cache_detail idtoname_cache = { | 190 | static struct cache_detail idtoname_cache_template = { |
| 191 | .owner = THIS_MODULE, | 191 | .owner = THIS_MODULE, |
| 192 | .hash_size = ENT_HASHMAX, | 192 | .hash_size = ENT_HASHMAX, |
| 193 | .hash_table = idtoname_table, | ||
| 194 | .name = "nfs4.idtoname", | 193 | .name = "nfs4.idtoname", |
| 195 | .cache_put = ent_put, | 194 | .cache_put = ent_put, |
| 196 | .cache_upcall = idtoname_upcall, | 195 | .cache_upcall = idtoname_upcall, |
| @@ -472,21 +471,34 @@ int | |||
| 472 | nfsd_idmap_init(struct net *net) | 471 | nfsd_idmap_init(struct net *net) |
| 473 | { | 472 | { |
| 474 | int rv; | 473 | int rv; |
| 474 | struct nfsd_net *nn = net_generic(net, nfsd_net_id); | ||
| 475 | 475 | ||
| 476 | rv = cache_register_net(&idtoname_cache, net); | 476 | nn->idtoname_cache = cache_create_net(&idtoname_cache_template, net); |
| 477 | if (IS_ERR(nn->idtoname_cache)) | ||
| 478 | return PTR_ERR(nn->idtoname_cache); | ||
| 479 | rv = cache_register_net(nn->idtoname_cache, net); | ||
| 477 | if (rv) | 480 | if (rv) |
| 478 | return rv; | 481 | goto destroy_idtoname_cache; |
| 479 | rv = cache_register_net(&nametoid_cache, net); | 482 | rv = cache_register_net(&nametoid_cache, net); |
| 480 | if (rv) | 483 | if (rv) |
| 481 | cache_unregister_net(&idtoname_cache, net); | 484 | goto unregister_idtoname_cache; |
| 485 | return 0; | ||
| 486 | |||
| 487 | unregister_idtoname_cache: | ||
| 488 | cache_unregister_net(nn->idtoname_cache, net); | ||
| 489 | destroy_idtoname_cache: | ||
| 490 | cache_destroy_net(nn->idtoname_cache, net); | ||
| 482 | return rv; | 491 | return rv; |
| 483 | } | 492 | } |
| 484 | 493 | ||
| 485 | void | 494 | void |
| 486 | nfsd_idmap_shutdown(struct net *net) | 495 | nfsd_idmap_shutdown(struct net *net) |
| 487 | { | 496 | { |
| 488 | cache_unregister_net(&idtoname_cache, net); | 497 | struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
| 498 | |||
| 499 | cache_unregister_net(nn->idtoname_cache, net); | ||
| 489 | cache_unregister_net(&nametoid_cache, net); | 500 | cache_unregister_net(&nametoid_cache, net); |
| 501 | cache_destroy_net(nn->idtoname_cache, net); | ||
| 490 | } | 502 | } |
| 491 | 503 | ||
| 492 | static int | 504 | static int |
| @@ -553,9 +565,10 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) | |||
| 553 | .type = type, | 565 | .type = type, |
| 554 | }; | 566 | }; |
| 555 | int ret; | 567 | int ret; |
| 568 | struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id); | ||
| 556 | 569 | ||
| 557 | strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); | 570 | strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); |
| 558 | ret = idmap_lookup(rqstp, idtoname_lookup, &key, &idtoname_cache, &item); | 571 | ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item); |
| 559 | if (ret == -ENOENT) | 572 | if (ret == -ENOENT) |
| 560 | return sprintf(name, "%u", id); | 573 | return sprintf(name, "%u", id); |
| 561 | if (ret) | 574 | if (ret) |
| @@ -563,7 +576,7 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) | |||
| 563 | ret = strlen(item->name); | 576 | ret = strlen(item->name); |
| 564 | BUG_ON(ret > IDMAP_NAMESZ); | 577 | BUG_ON(ret > IDMAP_NAMESZ); |
| 565 | memcpy(name, item->name, ret); | 578 | memcpy(name, item->name, ret); |
| 566 | cache_put(&item->h, &idtoname_cache); | 579 | cache_put(&item->h, nn->idtoname_cache); |
| 567 | return ret; | 580 | return ret; |
| 568 | } | 581 | } |
| 569 | 582 | ||
