Commit 73393232d6a425b6bb4cee590e3e66fc52532a15
Committed by
Trond Myklebust
1 parent
0a402d5a65
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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
net/sunrpc/netns.h
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); |