aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svcauth_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svcauth_unix.c')
-rw-r--r--net/sunrpc/svcauth_unix.c126
1 files changed, 71 insertions, 55 deletions
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 6ab35736d88f..521d8f7dc833 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -211,7 +211,7 @@ static int ip_map_parse(struct cache_detail *cd,
211 len = qword_get(&mesg, buf, mlen); 211 len = qword_get(&mesg, buf, mlen);
212 if (len <= 0) return -EINVAL; 212 if (len <= 0) return -EINVAL;
213 213
214 if (rpc_pton(buf, len, &address.sa, sizeof(address)) == 0) 214 if (rpc_pton(cd->net, buf, len, &address.sa, sizeof(address)) == 0)
215 return -EINVAL; 215 return -EINVAL;
216 switch (address.sa.sa_family) { 216 switch (address.sa.sa_family) {
217 case AF_INET: 217 case AF_INET:
@@ -436,7 +436,6 @@ struct unix_gid {
436 uid_t uid; 436 uid_t uid;
437 struct group_info *gi; 437 struct group_info *gi;
438}; 438};
439static struct cache_head *gid_table[GID_HASHMAX];
440 439
441static void unix_gid_put(struct kref *kref) 440static void unix_gid_put(struct kref *kref)
442{ 441{
@@ -494,8 +493,7 @@ static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h)
494 return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request); 493 return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request);
495} 494}
496 495
497static struct unix_gid *unix_gid_lookup(uid_t uid); 496static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid);
498extern struct cache_detail unix_gid_cache;
499 497
500static int unix_gid_parse(struct cache_detail *cd, 498static int unix_gid_parse(struct cache_detail *cd,
501 char *mesg, int mlen) 499 char *mesg, int mlen)
@@ -539,19 +537,19 @@ static int unix_gid_parse(struct cache_detail *cd,
539 GROUP_AT(ug.gi, i) = gid; 537 GROUP_AT(ug.gi, i) = gid;
540 } 538 }
541 539
542 ugp = unix_gid_lookup(uid); 540 ugp = unix_gid_lookup(cd, uid);
543 if (ugp) { 541 if (ugp) {
544 struct cache_head *ch; 542 struct cache_head *ch;
545 ug.h.flags = 0; 543 ug.h.flags = 0;
546 ug.h.expiry_time = expiry; 544 ug.h.expiry_time = expiry;
547 ch = sunrpc_cache_update(&unix_gid_cache, 545 ch = sunrpc_cache_update(cd,
548 &ug.h, &ugp->h, 546 &ug.h, &ugp->h,
549 hash_long(uid, GID_HASHBITS)); 547 hash_long(uid, GID_HASHBITS));
550 if (!ch) 548 if (!ch)
551 err = -ENOMEM; 549 err = -ENOMEM;
552 else { 550 else {
553 err = 0; 551 err = 0;
554 cache_put(ch, &unix_gid_cache); 552 cache_put(ch, cd);
555 } 553 }
556 } else 554 } else
557 err = -ENOMEM; 555 err = -ENOMEM;
@@ -587,10 +585,9 @@ static int unix_gid_show(struct seq_file *m,
587 return 0; 585 return 0;
588} 586}
589 587
590struct cache_detail unix_gid_cache = { 588static struct cache_detail unix_gid_cache_template = {
591 .owner = THIS_MODULE, 589 .owner = THIS_MODULE,
592 .hash_size = GID_HASHMAX, 590 .hash_size = GID_HASHMAX,
593 .hash_table = gid_table,
594 .name = "auth.unix.gid", 591 .name = "auth.unix.gid",
595 .cache_put = unix_gid_put, 592 .cache_put = unix_gid_put,
596 .cache_upcall = unix_gid_upcall, 593 .cache_upcall = unix_gid_upcall,
@@ -602,14 +599,42 @@ struct cache_detail unix_gid_cache = {
602 .alloc = unix_gid_alloc, 599 .alloc = unix_gid_alloc,
603}; 600};
604 601
605static struct unix_gid *unix_gid_lookup(uid_t uid) 602int unix_gid_cache_create(struct net *net)
603{
604 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
605 struct cache_detail *cd;
606 int err;
607
608 cd = cache_create_net(&unix_gid_cache_template, net);
609 if (IS_ERR(cd))
610 return PTR_ERR(cd);
611 err = cache_register_net(cd, net);
612 if (err) {
613 cache_destroy_net(cd, net);
614 return err;
615 }
616 sn->unix_gid_cache = cd;
617 return 0;
618}
619
620void unix_gid_cache_destroy(struct net *net)
621{
622 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
623 struct cache_detail *cd = sn->unix_gid_cache;
624
625 sn->unix_gid_cache = NULL;
626 cache_purge(cd);
627 cache_unregister_net(cd, net);
628 cache_destroy_net(cd, net);
629}
630
631static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid)
606{ 632{
607 struct unix_gid ug; 633 struct unix_gid ug;
608 struct cache_head *ch; 634 struct cache_head *ch;
609 635
610 ug.uid = uid; 636 ug.uid = uid;
611 ch = sunrpc_cache_lookup(&unix_gid_cache, &ug.h, 637 ch = sunrpc_cache_lookup(cd, &ug.h, hash_long(uid, GID_HASHBITS));
612 hash_long(uid, GID_HASHBITS));
613 if (ch) 638 if (ch)
614 return container_of(ch, struct unix_gid, h); 639 return container_of(ch, struct unix_gid, h);
615 else 640 else
@@ -621,11 +646,13 @@ static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp)
621 struct unix_gid *ug; 646 struct unix_gid *ug;
622 struct group_info *gi; 647 struct group_info *gi;
623 int ret; 648 int ret;
649 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net,
650 sunrpc_net_id);
624 651
625 ug = unix_gid_lookup(uid); 652 ug = unix_gid_lookup(sn->unix_gid_cache, uid);
626 if (!ug) 653 if (!ug)
627 return ERR_PTR(-EAGAIN); 654 return ERR_PTR(-EAGAIN);
628 ret = cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle); 655 ret = cache_check(sn->unix_gid_cache, &ug->h, &rqstp->rq_chandle);
629 switch (ret) { 656 switch (ret) {
630 case -ENOENT: 657 case -ENOENT:
631 return ERR_PTR(-ENOENT); 658 return ERR_PTR(-ENOENT);
@@ -633,7 +660,7 @@ static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp)
633 return ERR_PTR(-ESHUTDOWN); 660 return ERR_PTR(-ESHUTDOWN);
634 case 0: 661 case 0:
635 gi = get_group_info(ug->gi); 662 gi = get_group_info(ug->gi);
636 cache_put(&ug->h, &unix_gid_cache); 663 cache_put(&ug->h, sn->unix_gid_cache);
637 return gi; 664 return gi;
638 default: 665 default:
639 return ERR_PTR(-EAGAIN); 666 return ERR_PTR(-EAGAIN);
@@ -849,56 +876,45 @@ struct auth_ops svcauth_unix = {
849 .set_client = svcauth_unix_set_client, 876 .set_client = svcauth_unix_set_client,
850}; 877};
851 878
879static struct cache_detail ip_map_cache_template = {
880 .owner = THIS_MODULE,
881 .hash_size = IP_HASHMAX,
882 .name = "auth.unix.ip",
883 .cache_put = ip_map_put,
884 .cache_upcall = ip_map_upcall,
885 .cache_parse = ip_map_parse,
886 .cache_show = ip_map_show,
887 .match = ip_map_match,
888 .init = ip_map_init,
889 .update = update,
890 .alloc = ip_map_alloc,
891};
892
852int ip_map_cache_create(struct net *net) 893int ip_map_cache_create(struct net *net)
853{ 894{
854 int err = -ENOMEM;
855 struct cache_detail *cd;
856 struct cache_head **tbl;
857 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 895 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
896 struct cache_detail *cd;
897 int err;
858 898
859 cd = kzalloc(sizeof(struct cache_detail), GFP_KERNEL); 899 cd = cache_create_net(&ip_map_cache_template, net);
860 if (cd == NULL) 900 if (IS_ERR(cd))
861 goto err_cd; 901 return PTR_ERR(cd);
862
863 tbl = kzalloc(IP_HASHMAX * sizeof(struct cache_head *), GFP_KERNEL);
864 if (tbl == NULL)
865 goto err_tbl;
866
867 cd->owner = THIS_MODULE,
868 cd->hash_size = IP_HASHMAX,
869 cd->hash_table = tbl,
870 cd->name = "auth.unix.ip",
871 cd->cache_put = ip_map_put,
872 cd->cache_upcall = ip_map_upcall,
873 cd->cache_parse = ip_map_parse,
874 cd->cache_show = ip_map_show,
875 cd->match = ip_map_match,
876 cd->init = ip_map_init,
877 cd->update = update,
878 cd->alloc = ip_map_alloc,
879
880 err = cache_register_net(cd, net); 902 err = cache_register_net(cd, net);
881 if (err) 903 if (err) {
882 goto err_reg; 904 cache_destroy_net(cd, net);
883 905 return err;
906 }
884 sn->ip_map_cache = cd; 907 sn->ip_map_cache = cd;
885 return 0; 908 return 0;
886
887err_reg:
888 kfree(tbl);
889err_tbl:
890 kfree(cd);
891err_cd:
892 return err;
893} 909}
894 910
895void ip_map_cache_destroy(struct net *net) 911void ip_map_cache_destroy(struct net *net)
896{ 912{
897 struct sunrpc_net *sn; 913 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
914 struct cache_detail *cd = sn->ip_map_cache;
898 915
899 sn = net_generic(net, sunrpc_net_id); 916 sn->ip_map_cache = NULL;
900 cache_purge(sn->ip_map_cache); 917 cache_purge(cd);
901 cache_unregister_net(sn->ip_map_cache, net); 918 cache_unregister_net(cd, net);
902 kfree(sn->ip_map_cache->hash_table); 919 cache_destroy_net(cd, net);
903 kfree(sn->ip_map_cache);
904} 920}