summaryrefslogtreecommitdiffstats
path: root/fs/nfs/idmap.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-02-08 13:39:15 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-02-15 00:19:51 -0500
commit685f50f9188ac1e8244d0340a9d6ea36b6136cec (patch)
treeddb20fcea10937841e1c2af8b2da961ca0848354 /fs/nfs/idmap.c
parente3da87066f950076fe274b58f0d0adc7d9f9d412 (diff)
NFSv4: Further reduce the footprint of the idmapper
Don't allocate the legacy idmapper tables until we actually need them. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Reviewed-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/nfs/idmap.c')
-rw-r--r--fs/nfs/idmap.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index fff79481218c..b5c6d8eb7e03 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -367,7 +367,7 @@ struct idmap_hashent {
367 367
368struct idmap_hashtable { 368struct idmap_hashtable {
369 __u8 h_type; 369 __u8 h_type;
370 struct idmap_hashent h_entries[IDMAP_HASH_SZ]; 370 struct idmap_hashent *h_entries;
371}; 371};
372 372
373struct idmap { 373struct idmap {
@@ -478,21 +478,40 @@ nfs_idmap_new(struct nfs_client *clp)
478 return 0; 478 return 0;
479} 479}
480 480
481static void
482idmap_alloc_hashtable(struct idmap_hashtable *h)
483{
484 if (h->h_entries != NULL)
485 return;
486 h->h_entries = kcalloc(IDMAP_HASH_SZ,
487 sizeof(*h->h_entries),
488 GFP_KERNEL);
489}
490
491static void
492idmap_free_hashtable(struct idmap_hashtable *h)
493{
494 int i;
495
496 if (h->h_entries == NULL)
497 return;
498 for (i = 0; i < IDMAP_HASH_SZ; i++)
499 kfree(h->h_entries[i].ih_name);
500 kfree(h->h_entries);
501}
502
481void 503void
482nfs_idmap_delete(struct nfs_client *clp) 504nfs_idmap_delete(struct nfs_client *clp)
483{ 505{
484 struct idmap *idmap = clp->cl_idmap; 506 struct idmap *idmap = clp->cl_idmap;
485 int i;
486 507
487 if (!idmap) 508 if (!idmap)
488 return; 509 return;
489 nfs_idmap_unregister(clp, idmap->idmap_pipe); 510 nfs_idmap_unregister(clp, idmap->idmap_pipe);
490 rpc_destroy_pipe_data(idmap->idmap_pipe); 511 rpc_destroy_pipe_data(idmap->idmap_pipe);
491 clp->cl_idmap = NULL; 512 clp->cl_idmap = NULL;
492 for (i = 0; i < ARRAY_SIZE(idmap->idmap_user_hash.h_entries); i++) 513 idmap_free_hashtable(&idmap->idmap_user_hash);
493 kfree(idmap->idmap_user_hash.h_entries[i].ih_name); 514 idmap_free_hashtable(&idmap->idmap_group_hash);
494 for (i = 0; i < ARRAY_SIZE(idmap->idmap_group_hash.h_entries); i++)
495 kfree(idmap->idmap_group_hash.h_entries[i].ih_name);
496 kfree(idmap); 515 kfree(idmap);
497} 516}
498 517
@@ -586,6 +605,8 @@ void nfs_idmap_quit(void)
586static inline struct idmap_hashent * 605static inline struct idmap_hashent *
587idmap_name_hash(struct idmap_hashtable* h, const char *name, size_t len) 606idmap_name_hash(struct idmap_hashtable* h, const char *name, size_t len)
588{ 607{
608 if (h->h_entries == NULL)
609 return NULL;
589 return &h->h_entries[fnvhash32(name, len) % IDMAP_HASH_SZ]; 610 return &h->h_entries[fnvhash32(name, len) % IDMAP_HASH_SZ];
590} 611}
591 612
@@ -594,6 +615,8 @@ idmap_lookup_name(struct idmap_hashtable *h, const char *name, size_t len)
594{ 615{
595 struct idmap_hashent *he = idmap_name_hash(h, name, len); 616 struct idmap_hashent *he = idmap_name_hash(h, name, len);
596 617
618 if (he == NULL)
619 return NULL;
597 if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0) 620 if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0)
598 return NULL; 621 return NULL;
599 if (time_after(jiffies, he->ih_expires)) 622 if (time_after(jiffies, he->ih_expires))
@@ -604,6 +627,8 @@ idmap_lookup_name(struct idmap_hashtable *h, const char *name, size_t len)
604static inline struct idmap_hashent * 627static inline struct idmap_hashent *
605idmap_id_hash(struct idmap_hashtable* h, __u32 id) 628idmap_id_hash(struct idmap_hashtable* h, __u32 id)
606{ 629{
630 if (h->h_entries == NULL)
631 return NULL;
607 return &h->h_entries[fnvhash32(&id, sizeof(id)) % IDMAP_HASH_SZ]; 632 return &h->h_entries[fnvhash32(&id, sizeof(id)) % IDMAP_HASH_SZ];
608} 633}
609 634
@@ -611,6 +636,9 @@ static struct idmap_hashent *
611idmap_lookup_id(struct idmap_hashtable *h, __u32 id) 636idmap_lookup_id(struct idmap_hashtable *h, __u32 id)
612{ 637{
613 struct idmap_hashent *he = idmap_id_hash(h, id); 638 struct idmap_hashent *he = idmap_id_hash(h, id);
639
640 if (he == NULL)
641 return NULL;
614 if (he->ih_id != id || he->ih_namelen == 0) 642 if (he->ih_id != id || he->ih_namelen == 0)
615 return NULL; 643 return NULL;
616 if (time_after(jiffies, he->ih_expires)) 644 if (time_after(jiffies, he->ih_expires))
@@ -626,12 +654,14 @@ idmap_lookup_id(struct idmap_hashtable *h, __u32 id)
626static inline struct idmap_hashent * 654static inline struct idmap_hashent *
627idmap_alloc_name(struct idmap_hashtable *h, char *name, size_t len) 655idmap_alloc_name(struct idmap_hashtable *h, char *name, size_t len)
628{ 656{
657 idmap_alloc_hashtable(h);
629 return idmap_name_hash(h, name, len); 658 return idmap_name_hash(h, name, len);
630} 659}
631 660
632static inline struct idmap_hashent * 661static inline struct idmap_hashent *
633idmap_alloc_id(struct idmap_hashtable *h, __u32 id) 662idmap_alloc_id(struct idmap_hashtable *h, __u32 id)
634{ 663{
664 idmap_alloc_hashtable(h);
635 return idmap_id_hash(h, id); 665 return idmap_id_hash(h, id);
636} 666}
637 667