mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
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>
This commit is contained in:
parent
73393232d6
commit
a1db410d0b
5 changed files with 147 additions and 56 deletions
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
int gss_svc_init(void);
|
int gss_svc_init(void);
|
||||||
void gss_svc_shutdown(void);
|
void gss_svc_shutdown(void);
|
||||||
|
int gss_svc_init_net(struct net *net);
|
||||||
|
void gss_svc_shutdown_net(struct net *net);
|
||||||
int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
|
int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
|
||||||
u32 svcauth_gss_flavor(struct auth_domain *dom);
|
u32 svcauth_gss_flavor(struct auth_domain *dom);
|
||||||
char *svc_gss_principal(struct svc_rqst *);
|
char *svc_gss_principal(struct svc_rqst *);
|
||||||
|
|
|
@ -1662,6 +1662,21 @@ static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
|
||||||
.release_pipe = gss_pipe_release,
|
.release_pipe = gss_pipe_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static __net_init int rpcsec_gss_init_net(struct net *net)
|
||||||
|
{
|
||||||
|
return gss_svc_init_net(net);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __net_exit void rpcsec_gss_exit_net(struct net *net)
|
||||||
|
{
|
||||||
|
gss_svc_shutdown_net(net);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pernet_operations rpcsec_gss_net_ops = {
|
||||||
|
.init = rpcsec_gss_init_net,
|
||||||
|
.exit = rpcsec_gss_exit_net,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize RPCSEC_GSS module
|
* Initialize RPCSEC_GSS module
|
||||||
*/
|
*/
|
||||||
|
@ -1675,8 +1690,13 @@ static int __init init_rpcsec_gss(void)
|
||||||
err = gss_svc_init();
|
err = gss_svc_init();
|
||||||
if (err)
|
if (err)
|
||||||
goto out_unregister;
|
goto out_unregister;
|
||||||
|
err = register_pernet_subsys(&rpcsec_gss_net_ops);
|
||||||
|
if (err)
|
||||||
|
goto out_svc_exit;
|
||||||
rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version");
|
rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version");
|
||||||
return 0;
|
return 0;
|
||||||
|
out_svc_exit:
|
||||||
|
gss_svc_shutdown();
|
||||||
out_unregister:
|
out_unregister:
|
||||||
rpcauth_unregister(&authgss_ops);
|
rpcauth_unregister(&authgss_ops);
|
||||||
out:
|
out:
|
||||||
|
@ -1685,6 +1705,7 @@ out:
|
||||||
|
|
||||||
static void __exit exit_rpcsec_gss(void)
|
static void __exit exit_rpcsec_gss(void)
|
||||||
{
|
{
|
||||||
|
unregister_pernet_subsys(&rpcsec_gss_net_ops);
|
||||||
gss_svc_shutdown();
|
gss_svc_shutdown();
|
||||||
rpcauth_unregister(&authgss_ops);
|
rpcauth_unregister(&authgss_ops);
|
||||||
rcu_barrier(); /* Wait for completion of call_rcu()'s */
|
rcu_barrier(); /* Wait for completion of call_rcu()'s */
|
||||||
|
|
|
@ -48,6 +48,8 @@
|
||||||
#include <linux/sunrpc/svcauth_gss.h>
|
#include <linux/sunrpc/svcauth_gss.h>
|
||||||
#include <linux/sunrpc/cache.h>
|
#include <linux/sunrpc/cache.h>
|
||||||
|
|
||||||
|
#include "../netns.h"
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#ifdef RPC_DEBUG
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,10 +77,8 @@ struct rsi {
|
||||||
int major_status, minor_status;
|
int major_status, minor_status;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cache_head *rsi_table[RSI_HASHMAX];
|
static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old);
|
||||||
static struct cache_detail rsi_cache;
|
static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item);
|
||||||
static struct rsi *rsi_update(struct rsi *new, struct rsi *old);
|
|
||||||
static struct rsi *rsi_lookup(struct rsi *item);
|
|
||||||
|
|
||||||
static void rsi_free(struct rsi *rsii)
|
static void rsi_free(struct rsi *rsii)
|
||||||
{
|
{
|
||||||
|
@ -216,7 +216,7 @@ static int rsi_parse(struct cache_detail *cd,
|
||||||
if (dup_to_netobj(&rsii.in_token, buf, len))
|
if (dup_to_netobj(&rsii.in_token, buf, len))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rsip = rsi_lookup(&rsii);
|
rsip = rsi_lookup(cd, &rsii);
|
||||||
if (!rsip)
|
if (!rsip)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -258,21 +258,20 @@ static int rsi_parse(struct cache_detail *cd,
|
||||||
if (dup_to_netobj(&rsii.out_token, buf, len))
|
if (dup_to_netobj(&rsii.out_token, buf, len))
|
||||||
goto out;
|
goto out;
|
||||||
rsii.h.expiry_time = expiry;
|
rsii.h.expiry_time = expiry;
|
||||||
rsip = rsi_update(&rsii, rsip);
|
rsip = rsi_update(cd, &rsii, rsip);
|
||||||
status = 0;
|
status = 0;
|
||||||
out:
|
out:
|
||||||
rsi_free(&rsii);
|
rsi_free(&rsii);
|
||||||
if (rsip)
|
if (rsip)
|
||||||
cache_put(&rsip->h, &rsi_cache);
|
cache_put(&rsip->h, cd);
|
||||||
else
|
else
|
||||||
status = -ENOMEM;
|
status = -ENOMEM;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct cache_detail rsi_cache = {
|
static struct cache_detail rsi_cache_template = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.hash_size = RSI_HASHMAX,
|
.hash_size = RSI_HASHMAX,
|
||||||
.hash_table = rsi_table,
|
|
||||||
.name = "auth.rpcsec.init",
|
.name = "auth.rpcsec.init",
|
||||||
.cache_put = rsi_put,
|
.cache_put = rsi_put,
|
||||||
.cache_upcall = rsi_upcall,
|
.cache_upcall = rsi_upcall,
|
||||||
|
@ -283,24 +282,24 @@ static struct cache_detail rsi_cache = {
|
||||||
.alloc = rsi_alloc,
|
.alloc = rsi_alloc,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct rsi *rsi_lookup(struct rsi *item)
|
static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item)
|
||||||
{
|
{
|
||||||
struct cache_head *ch;
|
struct cache_head *ch;
|
||||||
int hash = rsi_hash(item);
|
int hash = rsi_hash(item);
|
||||||
|
|
||||||
ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash);
|
ch = sunrpc_cache_lookup(cd, &item->h, hash);
|
||||||
if (ch)
|
if (ch)
|
||||||
return container_of(ch, struct rsi, h);
|
return container_of(ch, struct rsi, h);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rsi *rsi_update(struct rsi *new, struct rsi *old)
|
static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old)
|
||||||
{
|
{
|
||||||
struct cache_head *ch;
|
struct cache_head *ch;
|
||||||
int hash = rsi_hash(new);
|
int hash = rsi_hash(new);
|
||||||
|
|
||||||
ch = sunrpc_cache_update(&rsi_cache, &new->h,
|
ch = sunrpc_cache_update(cd, &new->h,
|
||||||
&old->h, hash);
|
&old->h, hash);
|
||||||
if (ch)
|
if (ch)
|
||||||
return container_of(ch, struct rsi, h);
|
return container_of(ch, struct rsi, h);
|
||||||
|
@ -339,10 +338,8 @@ struct rsc {
|
||||||
char *client_name;
|
char *client_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cache_head *rsc_table[RSC_HASHMAX];
|
static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old);
|
||||||
static struct cache_detail rsc_cache;
|
static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item);
|
||||||
static struct rsc *rsc_update(struct rsc *new, struct rsc *old);
|
|
||||||
static struct rsc *rsc_lookup(struct rsc *item);
|
|
||||||
|
|
||||||
static void rsc_free(struct rsc *rsci)
|
static void rsc_free(struct rsc *rsci)
|
||||||
{
|
{
|
||||||
|
@ -444,7 +441,7 @@ static int rsc_parse(struct cache_detail *cd,
|
||||||
if (expiry == 0)
|
if (expiry == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rscp = rsc_lookup(&rsci);
|
rscp = rsc_lookup(cd, &rsci);
|
||||||
if (!rscp)
|
if (!rscp)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -506,22 +503,21 @@ static int rsc_parse(struct cache_detail *cd,
|
||||||
|
|
||||||
}
|
}
|
||||||
rsci.h.expiry_time = expiry;
|
rsci.h.expiry_time = expiry;
|
||||||
rscp = rsc_update(&rsci, rscp);
|
rscp = rsc_update(cd, &rsci, rscp);
|
||||||
status = 0;
|
status = 0;
|
||||||
out:
|
out:
|
||||||
gss_mech_put(gm);
|
gss_mech_put(gm);
|
||||||
rsc_free(&rsci);
|
rsc_free(&rsci);
|
||||||
if (rscp)
|
if (rscp)
|
||||||
cache_put(&rscp->h, &rsc_cache);
|
cache_put(&rscp->h, cd);
|
||||||
else
|
else
|
||||||
status = -ENOMEM;
|
status = -ENOMEM;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct cache_detail rsc_cache = {
|
static struct cache_detail rsc_cache_template = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.hash_size = RSC_HASHMAX,
|
.hash_size = RSC_HASHMAX,
|
||||||
.hash_table = rsc_table,
|
|
||||||
.name = "auth.rpcsec.context",
|
.name = "auth.rpcsec.context",
|
||||||
.cache_put = rsc_put,
|
.cache_put = rsc_put,
|
||||||
.cache_parse = rsc_parse,
|
.cache_parse = rsc_parse,
|
||||||
|
@ -531,24 +527,24 @@ static struct cache_detail rsc_cache = {
|
||||||
.alloc = rsc_alloc,
|
.alloc = rsc_alloc,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct rsc *rsc_lookup(struct rsc *item)
|
static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item)
|
||||||
{
|
{
|
||||||
struct cache_head *ch;
|
struct cache_head *ch;
|
||||||
int hash = rsc_hash(item);
|
int hash = rsc_hash(item);
|
||||||
|
|
||||||
ch = sunrpc_cache_lookup(&rsc_cache, &item->h, hash);
|
ch = sunrpc_cache_lookup(cd, &item->h, hash);
|
||||||
if (ch)
|
if (ch)
|
||||||
return container_of(ch, struct rsc, h);
|
return container_of(ch, struct rsc, h);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rsc *rsc_update(struct rsc *new, struct rsc *old)
|
static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old)
|
||||||
{
|
{
|
||||||
struct cache_head *ch;
|
struct cache_head *ch;
|
||||||
int hash = rsc_hash(new);
|
int hash = rsc_hash(new);
|
||||||
|
|
||||||
ch = sunrpc_cache_update(&rsc_cache, &new->h,
|
ch = sunrpc_cache_update(cd, &new->h,
|
||||||
&old->h, hash);
|
&old->h, hash);
|
||||||
if (ch)
|
if (ch)
|
||||||
return container_of(ch, struct rsc, h);
|
return container_of(ch, struct rsc, h);
|
||||||
|
@ -558,7 +554,7 @@ static struct rsc *rsc_update(struct rsc *new, struct rsc *old)
|
||||||
|
|
||||||
|
|
||||||
static struct rsc *
|
static struct rsc *
|
||||||
gss_svc_searchbyctx(struct xdr_netobj *handle)
|
gss_svc_searchbyctx(struct cache_detail *cd, struct xdr_netobj *handle)
|
||||||
{
|
{
|
||||||
struct rsc rsci;
|
struct rsc rsci;
|
||||||
struct rsc *found;
|
struct rsc *found;
|
||||||
|
@ -566,11 +562,11 @@ gss_svc_searchbyctx(struct xdr_netobj *handle)
|
||||||
memset(&rsci, 0, sizeof(rsci));
|
memset(&rsci, 0, sizeof(rsci));
|
||||||
if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
|
if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
|
||||||
return NULL;
|
return NULL;
|
||||||
found = rsc_lookup(&rsci);
|
found = rsc_lookup(cd, &rsci);
|
||||||
rsc_free(&rsci);
|
rsc_free(&rsci);
|
||||||
if (!found)
|
if (!found)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (cache_check(&rsc_cache, &found->h, NULL))
|
if (cache_check(cd, &found->h, NULL))
|
||||||
return NULL;
|
return NULL;
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
@ -968,20 +964,20 @@ svcauth_gss_set_client(struct svc_rqst *rqstp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip)
|
gss_write_init_verf(struct cache_detail *cd, struct svc_rqst *rqstp, struct rsi *rsip)
|
||||||
{
|
{
|
||||||
struct rsc *rsci;
|
struct rsc *rsci;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (rsip->major_status != GSS_S_COMPLETE)
|
if (rsip->major_status != GSS_S_COMPLETE)
|
||||||
return gss_write_null_verf(rqstp);
|
return gss_write_null_verf(rqstp);
|
||||||
rsci = gss_svc_searchbyctx(&rsip->out_handle);
|
rsci = gss_svc_searchbyctx(cd, &rsip->out_handle);
|
||||||
if (rsci == NULL) {
|
if (rsci == NULL) {
|
||||||
rsip->major_status = GSS_S_NO_CONTEXT;
|
rsip->major_status = GSS_S_NO_CONTEXT;
|
||||||
return gss_write_null_verf(rqstp);
|
return gss_write_null_verf(rqstp);
|
||||||
}
|
}
|
||||||
rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN);
|
rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN);
|
||||||
cache_put(&rsci->h, &rsc_cache);
|
cache_put(&rsci->h, cd);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1000,6 +996,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
|
||||||
struct xdr_netobj tmpobj;
|
struct xdr_netobj tmpobj;
|
||||||
struct rsi *rsip, rsikey;
|
struct rsi *rsip, rsikey;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
|
||||||
|
|
||||||
/* Read the verifier; should be NULL: */
|
/* Read the verifier; should be NULL: */
|
||||||
*authp = rpc_autherr_badverf;
|
*authp = rpc_autherr_badverf;
|
||||||
|
@ -1028,17 +1025,17 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform upcall, or find upcall result: */
|
/* Perform upcall, or find upcall result: */
|
||||||
rsip = rsi_lookup(&rsikey);
|
rsip = rsi_lookup(sn->rsi_cache, &rsikey);
|
||||||
rsi_free(&rsikey);
|
rsi_free(&rsikey);
|
||||||
if (!rsip)
|
if (!rsip)
|
||||||
return SVC_CLOSE;
|
return SVC_CLOSE;
|
||||||
if (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0)
|
if (cache_check(sn->rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0)
|
||||||
/* No upcall result: */
|
/* No upcall result: */
|
||||||
return SVC_CLOSE;
|
return SVC_CLOSE;
|
||||||
|
|
||||||
ret = SVC_CLOSE;
|
ret = SVC_CLOSE;
|
||||||
/* Got an answer to the upcall; use it: */
|
/* Got an answer to the upcall; use it: */
|
||||||
if (gss_write_init_verf(rqstp, rsip))
|
if (gss_write_init_verf(sn->rsc_cache, rqstp, rsip))
|
||||||
goto out;
|
goto out;
|
||||||
if (resv->iov_len + 4 > PAGE_SIZE)
|
if (resv->iov_len + 4 > PAGE_SIZE)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1055,7 +1052,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
|
||||||
|
|
||||||
ret = SVC_COMPLETE;
|
ret = SVC_COMPLETE;
|
||||||
out:
|
out:
|
||||||
cache_put(&rsip->h, &rsi_cache);
|
cache_put(&rsip->h, sn->rsi_cache);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1079,6 +1076,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
|
||||||
__be32 *rpcstart;
|
__be32 *rpcstart;
|
||||||
__be32 *reject_stat = resv->iov_base + resv->iov_len;
|
__be32 *reject_stat = resv->iov_base + resv->iov_len;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
|
||||||
|
|
||||||
dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n",
|
dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n",
|
||||||
argv->iov_len);
|
argv->iov_len);
|
||||||
|
@ -1129,7 +1127,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
|
||||||
case RPC_GSS_PROC_DESTROY:
|
case RPC_GSS_PROC_DESTROY:
|
||||||
/* Look up the context, and check the verifier: */
|
/* Look up the context, and check the verifier: */
|
||||||
*authp = rpcsec_gsserr_credproblem;
|
*authp = rpcsec_gsserr_credproblem;
|
||||||
rsci = gss_svc_searchbyctx(&gc->gc_ctx);
|
rsci = gss_svc_searchbyctx(sn->rsc_cache, &gc->gc_ctx);
|
||||||
if (!rsci)
|
if (!rsci)
|
||||||
goto auth_err;
|
goto auth_err;
|
||||||
switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) {
|
switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) {
|
||||||
|
@ -1209,7 +1207,7 @@ drop:
|
||||||
ret = SVC_DROP;
|
ret = SVC_DROP;
|
||||||
out:
|
out:
|
||||||
if (rsci)
|
if (rsci)
|
||||||
cache_put(&rsci->h, &rsc_cache);
|
cache_put(&rsci->h, sn->rsc_cache);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1362,6 +1360,7 @@ svcauth_gss_release(struct svc_rqst *rqstp)
|
||||||
struct rpc_gss_wire_cred *gc = &gsd->clcred;
|
struct rpc_gss_wire_cred *gc = &gsd->clcred;
|
||||||
struct xdr_buf *resbuf = &rqstp->rq_res;
|
struct xdr_buf *resbuf = &rqstp->rq_res;
|
||||||
int stat = -EINVAL;
|
int stat = -EINVAL;
|
||||||
|
struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
|
||||||
|
|
||||||
if (gc->gc_proc != RPC_GSS_PROC_DATA)
|
if (gc->gc_proc != RPC_GSS_PROC_DATA)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1404,7 +1403,7 @@ out_err:
|
||||||
put_group_info(rqstp->rq_cred.cr_group_info);
|
put_group_info(rqstp->rq_cred.cr_group_info);
|
||||||
rqstp->rq_cred.cr_group_info = NULL;
|
rqstp->rq_cred.cr_group_info = NULL;
|
||||||
if (gsd->rsci)
|
if (gsd->rsci)
|
||||||
cache_put(&gsd->rsci->h, &rsc_cache);
|
cache_put(&gsd->rsci->h, sn->rsc_cache);
|
||||||
gsd->rsci = NULL;
|
gsd->rsci = NULL;
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
|
@ -1429,30 +1428,96 @@ static struct auth_ops svcauthops_gss = {
|
||||||
.set_client = svcauth_gss_set_client,
|
.set_client = svcauth_gss_set_client,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int rsi_cache_create_net(struct net *net)
|
||||||
|
{
|
||||||
|
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
|
||||||
|
struct cache_detail *cd;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
cd = cache_create_net(&rsi_cache_template, net);
|
||||||
|
if (IS_ERR(cd))
|
||||||
|
return PTR_ERR(cd);
|
||||||
|
err = cache_register_net(cd, net);
|
||||||
|
if (err) {
|
||||||
|
cache_destroy_net(cd, net);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
sn->rsi_cache = cd;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rsi_cache_destroy_net(struct net *net)
|
||||||
|
{
|
||||||
|
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
|
||||||
|
struct cache_detail *cd = sn->rsi_cache;
|
||||||
|
|
||||||
|
sn->rsi_cache = NULL;
|
||||||
|
cache_purge(cd);
|
||||||
|
cache_unregister_net(cd, net);
|
||||||
|
cache_destroy_net(cd, net);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rsc_cache_create_net(struct net *net)
|
||||||
|
{
|
||||||
|
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
|
||||||
|
struct cache_detail *cd;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
cd = cache_create_net(&rsc_cache_template, net);
|
||||||
|
if (IS_ERR(cd))
|
||||||
|
return PTR_ERR(cd);
|
||||||
|
err = cache_register_net(cd, net);
|
||||||
|
if (err) {
|
||||||
|
cache_destroy_net(cd, net);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
sn->rsc_cache = cd;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rsc_cache_destroy_net(struct net *net)
|
||||||
|
{
|
||||||
|
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
|
||||||
|
struct cache_detail *cd = sn->rsc_cache;
|
||||||
|
|
||||||
|
sn->rsc_cache = NULL;
|
||||||
|
cache_purge(cd);
|
||||||
|
cache_unregister_net(cd, net);
|
||||||
|
cache_destroy_net(cd, net);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gss_svc_init_net(struct net *net)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = rsc_cache_create_net(net);
|
||||||
|
if (rv)
|
||||||
|
return rv;
|
||||||
|
rv = rsi_cache_create_net(net);
|
||||||
|
if (rv)
|
||||||
|
goto out1;
|
||||||
|
return 0;
|
||||||
|
out1:
|
||||||
|
rsc_cache_destroy_net(net);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gss_svc_shutdown_net(struct net *net)
|
||||||
|
{
|
||||||
|
rsi_cache_destroy_net(net);
|
||||||
|
rsc_cache_destroy_net(net);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
gss_svc_init(void)
|
gss_svc_init(void)
|
||||||
{
|
{
|
||||||
int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
|
return svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
|
||||||
if (rv)
|
|
||||||
return rv;
|
|
||||||
rv = cache_register(&rsc_cache);
|
|
||||||
if (rv)
|
|
||||||
goto out1;
|
|
||||||
rv = cache_register(&rsi_cache);
|
|
||||||
if (rv)
|
|
||||||
goto out2;
|
|
||||||
return 0;
|
|
||||||
out2:
|
|
||||||
cache_unregister(&rsc_cache);
|
|
||||||
out1:
|
|
||||||
svc_auth_unregister(RPC_AUTH_GSS);
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gss_svc_shutdown(void)
|
gss_svc_shutdown(void)
|
||||||
{
|
{
|
||||||
cache_unregister(&rsc_cache);
|
|
||||||
cache_unregister(&rsi_cache);
|
|
||||||
svc_auth_unregister(RPC_AUTH_GSS);
|
svc_auth_unregister(RPC_AUTH_GSS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ struct sunrpc_net {
|
||||||
struct proc_dir_entry *proc_net_rpc;
|
struct proc_dir_entry *proc_net_rpc;
|
||||||
struct cache_detail *ip_map_cache;
|
struct cache_detail *ip_map_cache;
|
||||||
struct cache_detail *unix_gid_cache;
|
struct cache_detail *unix_gid_cache;
|
||||||
|
struct cache_detail *rsc_cache;
|
||||||
|
struct cache_detail *rsi_cache;
|
||||||
|
|
||||||
struct super_block *pipefs_sb;
|
struct super_block *pipefs_sb;
|
||||||
struct mutex pipefs_sb_lock;
|
struct mutex pipefs_sb_lock;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "netns.h"
|
#include "netns.h"
|
||||||
|
|
||||||
int sunrpc_net_id;
|
int sunrpc_net_id;
|
||||||
|
EXPORT_SYMBOL_GPL(sunrpc_net_id);
|
||||||
|
|
||||||
extern int unix_gid_cache_create(struct net *net);
|
extern int unix_gid_cache_create(struct net *net);
|
||||||
extern int unix_gid_cache_destroy(struct net *net);
|
extern int unix_gid_cache_destroy(struct net *net);
|
||||||
|
|
Loading…
Reference in a new issue