diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2012-01-19 12:42:37 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-01-31 19:28:15 -0500 |
commit | a1db410d0bbadc49943f0fcddb21702ceb429396 (patch) | |
tree | 09f1a94d7c4ef70d6122f936b1fa309996f170ee /net/sunrpc/auth_gss | |
parent | 73393232d6a425b6bb4cee590e3e66fc52532a15 (diff) |
SUNRPC: create GSS auth cache per network namespace
This patch makes GSS auth cache details allocated and registered per network
namespace context.
Thus with this patch rsi_cache and rsc_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>
Diffstat (limited to 'net/sunrpc/auth_gss')
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 21 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 165 |
2 files changed, 136 insertions, 50 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 5ebb602cabe0..cb2e56452748 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -1662,6 +1662,21 @@ static const struct rpc_pipe_ops gss_upcall_ops_v1 = { | |||
1662 | .release_pipe = gss_pipe_release, | 1662 | .release_pipe = gss_pipe_release, |
1663 | }; | 1663 | }; |
1664 | 1664 | ||
1665 | static __net_init int rpcsec_gss_init_net(struct net *net) | ||
1666 | { | ||
1667 | return gss_svc_init_net(net); | ||
1668 | } | ||
1669 | |||
1670 | static __net_exit void rpcsec_gss_exit_net(struct net *net) | ||
1671 | { | ||
1672 | gss_svc_shutdown_net(net); | ||
1673 | } | ||
1674 | |||
1675 | static struct pernet_operations rpcsec_gss_net_ops = { | ||
1676 | .init = rpcsec_gss_init_net, | ||
1677 | .exit = rpcsec_gss_exit_net, | ||
1678 | }; | ||
1679 | |||
1665 | /* | 1680 | /* |
1666 | * Initialize RPCSEC_GSS module | 1681 | * Initialize RPCSEC_GSS module |
1667 | */ | 1682 | */ |
@@ -1675,8 +1690,13 @@ static int __init init_rpcsec_gss(void) | |||
1675 | err = gss_svc_init(); | 1690 | err = gss_svc_init(); |
1676 | if (err) | 1691 | if (err) |
1677 | goto out_unregister; | 1692 | goto out_unregister; |
1693 | err = register_pernet_subsys(&rpcsec_gss_net_ops); | ||
1694 | if (err) | ||
1695 | goto out_svc_exit; | ||
1678 | rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version"); | 1696 | rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version"); |
1679 | return 0; | 1697 | return 0; |
1698 | out_svc_exit: | ||
1699 | gss_svc_shutdown(); | ||
1680 | out_unregister: | 1700 | out_unregister: |
1681 | rpcauth_unregister(&authgss_ops); | 1701 | rpcauth_unregister(&authgss_ops); |
1682 | out: | 1702 | out: |
@@ -1685,6 +1705,7 @@ out: | |||
1685 | 1705 | ||
1686 | static void __exit exit_rpcsec_gss(void) | 1706 | static void __exit exit_rpcsec_gss(void) |
1687 | { | 1707 | { |
1708 | unregister_pernet_subsys(&rpcsec_gss_net_ops); | ||
1688 | gss_svc_shutdown(); | 1709 | gss_svc_shutdown(); |
1689 | rpcauth_unregister(&authgss_ops); | 1710 | rpcauth_unregister(&authgss_ops); |
1690 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | 1711 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 8d0f7d3c71c8..1600cfb1618c 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -48,6 +48,8 @@ | |||
48 | #include <linux/sunrpc/svcauth_gss.h> | 48 | #include <linux/sunrpc/svcauth_gss.h> |
49 | #include <linux/sunrpc/cache.h> | 49 | #include <linux/sunrpc/cache.h> |
50 | 50 | ||
51 | #include "../netns.h" | ||
52 | |||
51 | #ifdef RPC_DEBUG | 53 | #ifdef RPC_DEBUG |
52 | # define RPCDBG_FACILITY RPCDBG_AUTH | 54 | # define RPCDBG_FACILITY RPCDBG_AUTH |
53 | #endif | 55 | #endif |
@@ -75,10 +77,8 @@ struct rsi { | |||
75 | int major_status, minor_status; | 77 | int major_status, minor_status; |
76 | }; | 78 | }; |
77 | 79 | ||
78 | static struct cache_head *rsi_table[RSI_HASHMAX]; | 80 | static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old); |
79 | static struct cache_detail rsi_cache; | 81 | static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item); |
80 | static struct rsi *rsi_update(struct rsi *new, struct rsi *old); | ||
81 | static struct rsi *rsi_lookup(struct rsi *item); | ||
82 | 82 | ||
83 | static void rsi_free(struct rsi *rsii) | 83 | static void rsi_free(struct rsi *rsii) |
84 | { | 84 | { |
@@ -216,7 +216,7 @@ static int rsi_parse(struct cache_detail *cd, | |||
216 | if (dup_to_netobj(&rsii.in_token, buf, len)) | 216 | if (dup_to_netobj(&rsii.in_token, buf, len)) |
217 | goto out; | 217 | goto out; |
218 | 218 | ||
219 | rsip = rsi_lookup(&rsii); | 219 | rsip = rsi_lookup(cd, &rsii); |
220 | if (!rsip) | 220 | if (!rsip) |
221 | goto out; | 221 | goto out; |
222 | 222 | ||
@@ -258,21 +258,20 @@ static int rsi_parse(struct cache_detail *cd, | |||
258 | if (dup_to_netobj(&rsii.out_token, buf, len)) | 258 | if (dup_to_netobj(&rsii.out_token, buf, len)) |
259 | goto out; | 259 | goto out; |
260 | rsii.h.expiry_time = expiry; | 260 | rsii.h.expiry_time = expiry; |
261 | rsip = rsi_update(&rsii, rsip); | 261 | rsip = rsi_update(cd, &rsii, rsip); |
262 | status = 0; | 262 | status = 0; |
263 | out: | 263 | out: |
264 | rsi_free(&rsii); | 264 | rsi_free(&rsii); |
265 | if (rsip) | 265 | if (rsip) |
266 | cache_put(&rsip->h, &rsi_cache); | 266 | cache_put(&rsip->h, cd); |
267 | else | 267 | else |
268 | status = -ENOMEM; | 268 | status = -ENOMEM; |
269 | return status; | 269 | return status; |
270 | } | 270 | } |
271 | 271 | ||
272 | static struct cache_detail rsi_cache = { | 272 | static struct cache_detail rsi_cache_template = { |
273 | .owner = THIS_MODULE, | 273 | .owner = THIS_MODULE, |
274 | .hash_size = RSI_HASHMAX, | 274 | .hash_size = RSI_HASHMAX, |
275 | .hash_table = rsi_table, | ||
276 | .name = "auth.rpcsec.init", | 275 | .name = "auth.rpcsec.init", |
277 | .cache_put = rsi_put, | 276 | .cache_put = rsi_put, |
278 | .cache_upcall = rsi_upcall, | 277 | .cache_upcall = rsi_upcall, |
@@ -283,24 +282,24 @@ static struct cache_detail rsi_cache = { | |||
283 | .alloc = rsi_alloc, | 282 | .alloc = rsi_alloc, |
284 | }; | 283 | }; |
285 | 284 | ||
286 | static struct rsi *rsi_lookup(struct rsi *item) | 285 | static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item) |
287 | { | 286 | { |
288 | struct cache_head *ch; | 287 | struct cache_head *ch; |
289 | int hash = rsi_hash(item); | 288 | int hash = rsi_hash(item); |
290 | 289 | ||
291 | ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash); | 290 | ch = sunrpc_cache_lookup(cd, &item->h, hash); |
292 | if (ch) | 291 | if (ch) |
293 | return container_of(ch, struct rsi, h); | 292 | return container_of(ch, struct rsi, h); |
294 | else | 293 | else |
295 | return NULL; | 294 | return NULL; |
296 | } | 295 | } |
297 | 296 | ||
298 | static struct rsi *rsi_update(struct rsi *new, struct rsi *old) | 297 | static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old) |
299 | { | 298 | { |
300 | struct cache_head *ch; | 299 | struct cache_head *ch; |
301 | int hash = rsi_hash(new); | 300 | int hash = rsi_hash(new); |
302 | 301 | ||
303 | ch = sunrpc_cache_update(&rsi_cache, &new->h, | 302 | ch = sunrpc_cache_update(cd, &new->h, |
304 | &old->h, hash); | 303 | &old->h, hash); |
305 | if (ch) | 304 | if (ch) |
306 | return container_of(ch, struct rsi, h); | 305 | return container_of(ch, struct rsi, h); |
@@ -339,10 +338,8 @@ struct rsc { | |||
339 | char *client_name; | 338 | char *client_name; |
340 | }; | 339 | }; |
341 | 340 | ||
342 | static struct cache_head *rsc_table[RSC_HASHMAX]; | 341 | static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old); |
343 | static struct cache_detail rsc_cache; | 342 | static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item); |
344 | static struct rsc *rsc_update(struct rsc *new, struct rsc *old); | ||
345 | static struct rsc *rsc_lookup(struct rsc *item); | ||
346 | 343 | ||
347 | static void rsc_free(struct rsc *rsci) | 344 | static void rsc_free(struct rsc *rsci) |
348 | { | 345 | { |
@@ -444,7 +441,7 @@ static int rsc_parse(struct cache_detail *cd, | |||
444 | if (expiry == 0) | 441 | if (expiry == 0) |
445 | goto out; | 442 | goto out; |
446 | 443 | ||
447 | rscp = rsc_lookup(&rsci); | 444 | rscp = rsc_lookup(cd, &rsci); |
448 | if (!rscp) | 445 | if (!rscp) |
449 | goto out; | 446 | goto out; |
450 | 447 | ||
@@ -506,22 +503,21 @@ static int rsc_parse(struct cache_detail *cd, | |||
506 | 503 | ||
507 | } | 504 | } |
508 | rsci.h.expiry_time = expiry; | 505 | rsci.h.expiry_time = expiry; |
509 | rscp = rsc_update(&rsci, rscp); | 506 | rscp = rsc_update(cd, &rsci, rscp); |
510 | status = 0; | 507 | status = 0; |
511 | out: | 508 | out: |
512 | gss_mech_put(gm); | 509 | gss_mech_put(gm); |
513 | rsc_free(&rsci); | 510 | rsc_free(&rsci); |
514 | if (rscp) | 511 | if (rscp) |
515 | cache_put(&rscp->h, &rsc_cache); | 512 | cache_put(&rscp->h, cd); |
516 | else | 513 | else |
517 | status = -ENOMEM; | 514 | status = -ENOMEM; |
518 | return status; | 515 | return status; |
519 | } | 516 | } |
520 | 517 | ||
521 | static struct cache_detail rsc_cache = { | 518 | static struct cache_detail rsc_cache_template = { |
522 | .owner = THIS_MODULE, | 519 | .owner = THIS_MODULE, |
523 | .hash_size = RSC_HASHMAX, | 520 | .hash_size = RSC_HASHMAX, |
524 | .hash_table = rsc_table, | ||
525 | .name = "auth.rpcsec.context", | 521 | .name = "auth.rpcsec.context", |
526 | .cache_put = rsc_put, | 522 | .cache_put = rsc_put, |
527 | .cache_parse = rsc_parse, | 523 | .cache_parse = rsc_parse, |
@@ -531,24 +527,24 @@ static struct cache_detail rsc_cache = { | |||
531 | .alloc = rsc_alloc, | 527 | .alloc = rsc_alloc, |
532 | }; | 528 | }; |
533 | 529 | ||
534 | static struct rsc *rsc_lookup(struct rsc *item) | 530 | static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item) |
535 | { | 531 | { |
536 | struct cache_head *ch; | 532 | struct cache_head *ch; |
537 | int hash = rsc_hash(item); | 533 | int hash = rsc_hash(item); |
538 | 534 | ||
539 | ch = sunrpc_cache_lookup(&rsc_cache, &item->h, hash); | 535 | ch = sunrpc_cache_lookup(cd, &item->h, hash); |
540 | if (ch) | 536 | if (ch) |
541 | return container_of(ch, struct rsc, h); | 537 | return container_of(ch, struct rsc, h); |
542 | else | 538 | else |
543 | return NULL; | 539 | return NULL; |
544 | } | 540 | } |
545 | 541 | ||
546 | static struct rsc *rsc_update(struct rsc *new, struct rsc *old) | 542 | static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old) |
547 | { | 543 | { |
548 | struct cache_head *ch; | 544 | struct cache_head *ch; |
549 | int hash = rsc_hash(new); | 545 | int hash = rsc_hash(new); |
550 | 546 | ||
551 | ch = sunrpc_cache_update(&rsc_cache, &new->h, | 547 | ch = sunrpc_cache_update(cd, &new->h, |
552 | &old->h, hash); | 548 | &old->h, hash); |
553 | if (ch) | 549 | if (ch) |
554 | return container_of(ch, struct rsc, h); | 550 | return container_of(ch, struct rsc, h); |
@@ -558,7 +554,7 @@ static struct rsc *rsc_update(struct rsc *new, struct rsc *old) | |||
558 | 554 | ||
559 | 555 | ||
560 | static struct rsc * | 556 | static struct rsc * |
561 | gss_svc_searchbyctx(struct xdr_netobj *handle) | 557 | gss_svc_searchbyctx(struct cache_detail *cd, struct xdr_netobj *handle) |
562 | { | 558 | { |
563 | struct rsc rsci; | 559 | struct rsc rsci; |
564 | struct rsc *found; | 560 | struct rsc *found; |
@@ -566,11 +562,11 @@ gss_svc_searchbyctx(struct xdr_netobj *handle) | |||
566 | memset(&rsci, 0, sizeof(rsci)); | 562 | memset(&rsci, 0, sizeof(rsci)); |
567 | if (dup_to_netobj(&rsci.handle, handle->data, handle->len)) | 563 | if (dup_to_netobj(&rsci.handle, handle->data, handle->len)) |
568 | return NULL; | 564 | return NULL; |
569 | found = rsc_lookup(&rsci); | 565 | found = rsc_lookup(cd, &rsci); |
570 | rsc_free(&rsci); | 566 | rsc_free(&rsci); |
571 | if (!found) | 567 | if (!found) |
572 | return NULL; | 568 | return NULL; |
573 | if (cache_check(&rsc_cache, &found->h, NULL)) | 569 | if (cache_check(cd, &found->h, NULL)) |
574 | return NULL; | 570 | return NULL; |
575 | return found; | 571 | return found; |
576 | } | 572 | } |
@@ -968,20 +964,20 @@ svcauth_gss_set_client(struct svc_rqst *rqstp) | |||
968 | } | 964 | } |
969 | 965 | ||
970 | static inline int | 966 | static inline int |
971 | gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip) | 967 | gss_write_init_verf(struct cache_detail *cd, struct svc_rqst *rqstp, struct rsi *rsip) |
972 | { | 968 | { |
973 | struct rsc *rsci; | 969 | struct rsc *rsci; |
974 | int rc; | 970 | int rc; |
975 | 971 | ||
976 | if (rsip->major_status != GSS_S_COMPLETE) | 972 | if (rsip->major_status != GSS_S_COMPLETE) |
977 | return gss_write_null_verf(rqstp); | 973 | return gss_write_null_verf(rqstp); |
978 | rsci = gss_svc_searchbyctx(&rsip->out_handle); | 974 | rsci = gss_svc_searchbyctx(cd, &rsip->out_handle); |
979 | if (rsci == NULL) { | 975 | if (rsci == NULL) { |
980 | rsip->major_status = GSS_S_NO_CONTEXT; | 976 | rsip->major_status = GSS_S_NO_CONTEXT; |
981 | return gss_write_null_verf(rqstp); | 977 | return gss_write_null_verf(rqstp); |
982 | } | 978 | } |
983 | rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN); | 979 | rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN); |
984 | cache_put(&rsci->h, &rsc_cache); | 980 | cache_put(&rsci->h, cd); |
985 | return rc; | 981 | return rc; |
986 | } | 982 | } |
987 | 983 | ||
@@ -1000,6 +996,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
1000 | struct xdr_netobj tmpobj; | 996 | struct xdr_netobj tmpobj; |
1001 | struct rsi *rsip, rsikey; | 997 | struct rsi *rsip, rsikey; |
1002 | int ret; | 998 | int ret; |
999 | struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); | ||
1003 | 1000 | ||
1004 | /* Read the verifier; should be NULL: */ | 1001 | /* Read the verifier; should be NULL: */ |
1005 | *authp = rpc_autherr_badverf; | 1002 | *authp = rpc_autherr_badverf; |
@@ -1028,17 +1025,17 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
1028 | } | 1025 | } |
1029 | 1026 | ||
1030 | /* Perform upcall, or find upcall result: */ | 1027 | /* Perform upcall, or find upcall result: */ |
1031 | rsip = rsi_lookup(&rsikey); | 1028 | rsip = rsi_lookup(sn->rsi_cache, &rsikey); |
1032 | rsi_free(&rsikey); | 1029 | rsi_free(&rsikey); |
1033 | if (!rsip) | 1030 | if (!rsip) |
1034 | return SVC_CLOSE; | 1031 | return SVC_CLOSE; |
1035 | if (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0) | 1032 | if (cache_check(sn->rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0) |
1036 | /* No upcall result: */ | 1033 | /* No upcall result: */ |
1037 | return SVC_CLOSE; | 1034 | return SVC_CLOSE; |
1038 | 1035 | ||
1039 | ret = SVC_CLOSE; | 1036 | ret = SVC_CLOSE; |
1040 | /* Got an answer to the upcall; use it: */ | 1037 | /* Got an answer to the upcall; use it: */ |
1041 | if (gss_write_init_verf(rqstp, rsip)) | 1038 | if (gss_write_init_verf(sn->rsc_cache, rqstp, rsip)) |
1042 | goto out; | 1039 | goto out; |
1043 | if (resv->iov_len + 4 > PAGE_SIZE) | 1040 | if (resv->iov_len + 4 > PAGE_SIZE) |
1044 | goto out; | 1041 | goto out; |
@@ -1055,7 +1052,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
1055 | 1052 | ||
1056 | ret = SVC_COMPLETE; | 1053 | ret = SVC_COMPLETE; |
1057 | out: | 1054 | out: |
1058 | cache_put(&rsip->h, &rsi_cache); | 1055 | cache_put(&rsip->h, sn->rsi_cache); |
1059 | return ret; | 1056 | return ret; |
1060 | } | 1057 | } |
1061 | 1058 | ||
@@ -1079,6 +1076,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
1079 | __be32 *rpcstart; | 1076 | __be32 *rpcstart; |
1080 | __be32 *reject_stat = resv->iov_base + resv->iov_len; | 1077 | __be32 *reject_stat = resv->iov_base + resv->iov_len; |
1081 | int ret; | 1078 | int ret; |
1079 | struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); | ||
1082 | 1080 | ||
1083 | dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n", | 1081 | dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n", |
1084 | argv->iov_len); | 1082 | argv->iov_len); |
@@ -1129,7 +1127,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
1129 | case RPC_GSS_PROC_DESTROY: | 1127 | case RPC_GSS_PROC_DESTROY: |
1130 | /* Look up the context, and check the verifier: */ | 1128 | /* Look up the context, and check the verifier: */ |
1131 | *authp = rpcsec_gsserr_credproblem; | 1129 | *authp = rpcsec_gsserr_credproblem; |
1132 | rsci = gss_svc_searchbyctx(&gc->gc_ctx); | 1130 | rsci = gss_svc_searchbyctx(sn->rsc_cache, &gc->gc_ctx); |
1133 | if (!rsci) | 1131 | if (!rsci) |
1134 | goto auth_err; | 1132 | goto auth_err; |
1135 | switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) { | 1133 | switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) { |
@@ -1209,7 +1207,7 @@ drop: | |||
1209 | ret = SVC_DROP; | 1207 | ret = SVC_DROP; |
1210 | out: | 1208 | out: |
1211 | if (rsci) | 1209 | if (rsci) |
1212 | cache_put(&rsci->h, &rsc_cache); | 1210 | cache_put(&rsci->h, sn->rsc_cache); |
1213 | return ret; | 1211 | return ret; |
1214 | } | 1212 | } |
1215 | 1213 | ||
@@ -1362,6 +1360,7 @@ svcauth_gss_release(struct svc_rqst *rqstp) | |||
1362 | struct rpc_gss_wire_cred *gc = &gsd->clcred; | 1360 | struct rpc_gss_wire_cred *gc = &gsd->clcred; |
1363 | struct xdr_buf *resbuf = &rqstp->rq_res; | 1361 | struct xdr_buf *resbuf = &rqstp->rq_res; |
1364 | int stat = -EINVAL; | 1362 | int stat = -EINVAL; |
1363 | struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); | ||
1365 | 1364 | ||
1366 | if (gc->gc_proc != RPC_GSS_PROC_DATA) | 1365 | if (gc->gc_proc != RPC_GSS_PROC_DATA) |
1367 | goto out; | 1366 | goto out; |
@@ -1404,7 +1403,7 @@ out_err: | |||
1404 | put_group_info(rqstp->rq_cred.cr_group_info); | 1403 | put_group_info(rqstp->rq_cred.cr_group_info); |
1405 | rqstp->rq_cred.cr_group_info = NULL; | 1404 | rqstp->rq_cred.cr_group_info = NULL; |
1406 | if (gsd->rsci) | 1405 | if (gsd->rsci) |
1407 | cache_put(&gsd->rsci->h, &rsc_cache); | 1406 | cache_put(&gsd->rsci->h, sn->rsc_cache); |
1408 | gsd->rsci = NULL; | 1407 | gsd->rsci = NULL; |
1409 | 1408 | ||
1410 | return stat; | 1409 | return stat; |
@@ -1429,30 +1428,96 @@ static struct auth_ops svcauthops_gss = { | |||
1429 | .set_client = svcauth_gss_set_client, | 1428 | .set_client = svcauth_gss_set_client, |
1430 | }; | 1429 | }; |
1431 | 1430 | ||
1431 | static int rsi_cache_create_net(struct net *net) | ||
1432 | { | ||
1433 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1434 | struct cache_detail *cd; | ||
1435 | int err; | ||
1436 | |||
1437 | cd = cache_create_net(&rsi_cache_template, net); | ||
1438 | if (IS_ERR(cd)) | ||
1439 | return PTR_ERR(cd); | ||
1440 | err = cache_register_net(cd, net); | ||
1441 | if (err) { | ||
1442 | cache_destroy_net(cd, net); | ||
1443 | return err; | ||
1444 | } | ||
1445 | sn->rsi_cache = cd; | ||
1446 | return 0; | ||
1447 | } | ||
1448 | |||
1449 | static void rsi_cache_destroy_net(struct net *net) | ||
1450 | { | ||
1451 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1452 | struct cache_detail *cd = sn->rsi_cache; | ||
1453 | |||
1454 | sn->rsi_cache = NULL; | ||
1455 | cache_purge(cd); | ||
1456 | cache_unregister_net(cd, net); | ||
1457 | cache_destroy_net(cd, net); | ||
1458 | } | ||
1459 | |||
1460 | static int rsc_cache_create_net(struct net *net) | ||
1461 | { | ||
1462 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1463 | struct cache_detail *cd; | ||
1464 | int err; | ||
1465 | |||
1466 | cd = cache_create_net(&rsc_cache_template, net); | ||
1467 | if (IS_ERR(cd)) | ||
1468 | return PTR_ERR(cd); | ||
1469 | err = cache_register_net(cd, net); | ||
1470 | if (err) { | ||
1471 | cache_destroy_net(cd, net); | ||
1472 | return err; | ||
1473 | } | ||
1474 | sn->rsc_cache = cd; | ||
1475 | return 0; | ||
1476 | } | ||
1477 | |||
1478 | static void rsc_cache_destroy_net(struct net *net) | ||
1479 | { | ||
1480 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1481 | struct cache_detail *cd = sn->rsc_cache; | ||
1482 | |||
1483 | sn->rsc_cache = NULL; | ||
1484 | cache_purge(cd); | ||
1485 | cache_unregister_net(cd, net); | ||
1486 | cache_destroy_net(cd, net); | ||
1487 | } | ||
1488 | |||
1432 | int | 1489 | int |
1433 | gss_svc_init(void) | 1490 | gss_svc_init_net(struct net *net) |
1434 | { | 1491 | { |
1435 | int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss); | 1492 | int rv; |
1493 | |||
1494 | rv = rsc_cache_create_net(net); | ||
1436 | if (rv) | 1495 | if (rv) |
1437 | return rv; | 1496 | return rv; |
1438 | rv = cache_register(&rsc_cache); | 1497 | rv = rsi_cache_create_net(net); |
1439 | if (rv) | 1498 | if (rv) |
1440 | goto out1; | 1499 | goto out1; |
1441 | rv = cache_register(&rsi_cache); | ||
1442 | if (rv) | ||
1443 | goto out2; | ||
1444 | return 0; | 1500 | return 0; |
1445 | out2: | ||
1446 | cache_unregister(&rsc_cache); | ||
1447 | out1: | 1501 | out1: |
1448 | svc_auth_unregister(RPC_AUTH_GSS); | 1502 | rsc_cache_destroy_net(net); |
1449 | return rv; | 1503 | return rv; |
1450 | } | 1504 | } |
1451 | 1505 | ||
1452 | void | 1506 | void |
1507 | gss_svc_shutdown_net(struct net *net) | ||
1508 | { | ||
1509 | rsi_cache_destroy_net(net); | ||
1510 | rsc_cache_destroy_net(net); | ||
1511 | } | ||
1512 | |||
1513 | int | ||
1514 | gss_svc_init(void) | ||
1515 | { | ||
1516 | return svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss); | ||
1517 | } | ||
1518 | |||
1519 | void | ||
1453 | gss_svc_shutdown(void) | 1520 | gss_svc_shutdown(void) |
1454 | { | 1521 | { |
1455 | cache_unregister(&rsc_cache); | ||
1456 | cache_unregister(&rsi_cache); | ||
1457 | svc_auth_unregister(RPC_AUTH_GSS); | 1522 | svc_auth_unregister(RPC_AUTH_GSS); |
1458 | } | 1523 | } |