Commit 73393232d6a425b6bb4cee590e3e66fc52532a15

Authored by Stanislav Kinsbursky
Committed by Trond Myklebust
1 parent 0a402d5a65

SUNRPC: create unix gid cache per network namespace

v2:
1) fixed silly usage of template cache as a real one (this code left from
static global cache for all)

This patch makes unix_gid_cache cache detail allocated and registered per
network namespace context.
Thus with this patch unix_gid_cache contents for network namespace "X" are
controlled from proc file system mount for the same network namespace "X".

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Acked-by: J. Bruce Fields <bfields@redhat.com>

Showing 3 changed files with 52 additions and 18 deletions Side-by-side Diff

... ... @@ -9,6 +9,7 @@
9 9 struct sunrpc_net {
10 10 struct proc_dir_entry *proc_net_rpc;
11 11 struct cache_detail *ip_map_cache;
  12 + struct cache_detail *unix_gid_cache;
12 13  
13 14 struct super_block *pipefs_sb;
14 15 struct mutex pipefs_sb_lock;
net/sunrpc/sunrpc_syms.c
... ... @@ -26,6 +26,9 @@
26 26  
27 27 int sunrpc_net_id;
28 28  
  29 +extern int unix_gid_cache_create(struct net *net);
  30 +extern int unix_gid_cache_destroy(struct net *net);
  31 +
29 32 static __net_init int sunrpc_init_net(struct net *net)
30 33 {
31 34 int err;
32 35  
... ... @@ -39,11 +42,17 @@
39 42 if (err)
40 43 goto err_ipmap;
41 44  
  45 + err = unix_gid_cache_create(net);
  46 + if (err)
  47 + goto err_unixgid;
  48 +
42 49 rpc_pipefs_init_net(net);
43 50 INIT_LIST_HEAD(&sn->all_clients);
44 51 spin_lock_init(&sn->rpc_client_lock);
45 52 return 0;
46 53  
  54 +err_unixgid:
  55 + ip_map_cache_destroy(net);
47 56 err_ipmap:
48 57 rpc_proc_exit(net);
49 58 err_proc:
... ... @@ -52,6 +61,7 @@
52 61  
53 62 static __net_exit void sunrpc_exit_net(struct net *net)
54 63 {
  64 + unix_gid_cache_destroy(net);
55 65 ip_map_cache_destroy(net);
56 66 rpc_proc_exit(net);
57 67 }
... ... @@ -63,8 +73,6 @@
63 73 .size = sizeof(struct sunrpc_net),
64 74 };
65 75  
66   -extern struct cache_detail unix_gid_cache;
67   -
68 76 static int __init
69 77 init_sunrpc(void)
70 78 {
... ... @@ -86,7 +94,6 @@
86 94 #ifdef RPC_DEBUG
87 95 rpc_register_sysctl();
88 96 #endif
89   - cache_register(&unix_gid_cache);
90 97 svc_init_xprt_sock(); /* svc sock transport */
91 98 init_socket_xprt(); /* clnt sock transport */
92 99 return 0;
... ... @@ -109,7 +116,6 @@
109 116 svc_cleanup_xprt_sock();
110 117 unregister_rpc_pipefs();
111 118 rpc_destroy_mempool();
112   - cache_unregister(&unix_gid_cache);
113 119 unregister_pernet_subsys(&sunrpc_net_ops);
114 120 #ifdef RPC_DEBUG
115 121 rpc_unregister_sysctl();
net/sunrpc/svcauth_unix.c
... ... @@ -436,7 +436,6 @@
436 436 uid_t uid;
437 437 struct group_info *gi;
438 438 };
439   -static struct cache_head *gid_table[GID_HASHMAX];
440 439  
441 440 static void unix_gid_put(struct kref *kref)
442 441 {
... ... @@ -494,8 +493,7 @@
494 493 return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request);
495 494 }
496 495  
497   -static struct unix_gid *unix_gid_lookup(uid_t uid);
498   -extern struct cache_detail unix_gid_cache;
  496 +static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid);
499 497  
500 498 static int unix_gid_parse(struct cache_detail *cd,
501 499 char *mesg, int mlen)
502 500  
503 501  
... ... @@ -539,19 +537,19 @@
539 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 541 if (ugp) {
544 542 struct cache_head *ch;
545 543 ug.h.flags = 0;
546 544 ug.h.expiry_time = expiry;
547   - ch = sunrpc_cache_update(&unix_gid_cache,
  545 + ch = sunrpc_cache_update(cd,
548 546 &ug.h, &ugp->h,
549 547 hash_long(uid, GID_HASHBITS));
550 548 if (!ch)
551 549 err = -ENOMEM;
552 550 else {
553 551 err = 0;
554   - cache_put(ch, &unix_gid_cache);
  552 + cache_put(ch, cd);
555 553 }
556 554 } else
557 555 err = -ENOMEM;
558 556  
... ... @@ -587,10 +585,9 @@
587 585 return 0;
588 586 }
589 587  
590   -struct cache_detail unix_gid_cache = {
  588 +static struct cache_detail unix_gid_cache_template = {
591 589 .owner = THIS_MODULE,
592 590 .hash_size = GID_HASHMAX,
593   - .hash_table = gid_table,
594 591 .name = "auth.unix.gid",
595 592 .cache_put = unix_gid_put,
596 593 .cache_upcall = unix_gid_upcall,
597 594  
598 595  
... ... @@ -602,14 +599,42 @@
602 599 .alloc = unix_gid_alloc,
603 600 };
604 601  
605   -static struct unix_gid *unix_gid_lookup(uid_t uid)
  602 +int unix_gid_cache_create(struct net *net)
606 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 +
  620 +void 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 +
  631 +static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid)
  632 +{
607 633 struct unix_gid ug;
608 634 struct cache_head *ch;
609 635  
610 636 ug.uid = uid;
611   - ch = sunrpc_cache_lookup(&unix_gid_cache, &ug.h,
612   - hash_long(uid, GID_HASHBITS));
  637 + ch = sunrpc_cache_lookup(cd, &ug.h, hash_long(uid, GID_HASHBITS));
613 638 if (ch)
614 639 return container_of(ch, struct unix_gid, h);
615 640 else
616 641  
617 642  
... ... @@ -621,11 +646,13 @@
621 646 struct unix_gid *ug;
622 647 struct group_info *gi;
623 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 653 if (!ug)
627 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 656 switch (ret) {
630 657 case -ENOENT:
631 658 return ERR_PTR(-ENOENT);
... ... @@ -633,7 +660,7 @@
633 660 return ERR_PTR(-ESHUTDOWN);
634 661 case 0:
635 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 664 return gi;
638 665 default:
639 666 return ERR_PTR(-EAGAIN);