From 4a8c1344dccb848dbcf0edabc8b5c51a8ecf2808 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 7 Jun 2007 10:14:14 -0400 Subject: SUNRPC: Add a backpointer from the struct rpc_cred to the rpc_auth Cleans up an issue whereby rpcsec_gss uses the rpc_clnt->cl_auth. If we want to be able to add several rpc_auths to a single rpc_clnt, then this abuse must go. Signed-off-by: Trond Myklebust --- net/sunrpc/auth_unix.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net/sunrpc/auth_unix.c') diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 4e7733aee36..82300b83045 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -92,6 +92,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) if (i < NFS_NGROUPS) cred->uc_gids[i] = NOGROUP; } + cred->uc_base.cr_auth = &unix_auth; cred->uc_base.cr_ops = &unix_credops; return (struct rpc_cred *) cred; -- cgit v1.2.3-70-g09d2 From 3ab9bb7243489f9db3abf3d05521ddfc6b184c0a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 9 Jun 2007 15:41:42 -0400 Subject: SUNRPC: Fix a memory leak in the auth credcache code The leak only affects the RPCSEC_GSS caches, since they are the only ones that are dynamically allocated... Rename the existing rpcauth_free_credcache() to rpcauth_clear_credcache() in order to better describe its role, then add a new function rpcauth_destroy_credcache() that actually frees the cache in addition to clearing it out. Also move the call to destroy the credcache in gss_destroy() to come before the rpc upcall pipe is unlinked. Signed-off-by: Trond Myklebust --- include/linux/sunrpc/auth.h | 3 ++- net/sunrpc/auth.c | 18 ++++++++++++++++-- net/sunrpc/auth_gss/auth_gss.c | 3 ++- net/sunrpc/auth_unix.c | 2 +- net/sunrpc/sunrpc_syms.c | 2 +- 5 files changed, 22 insertions(+), 6 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 8ef27afeea7..3972b8414c8 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -143,7 +143,8 @@ int rpcauth_refreshcred(struct rpc_task *); void rpcauth_invalcred(struct rpc_task *); int rpcauth_uptodatecred(struct rpc_task *); int rpcauth_init_credcache(struct rpc_auth *, unsigned long); -void rpcauth_free_credcache(struct rpc_auth *); +void rpcauth_destroy_credcache(struct rpc_auth *); +void rpcauth_clear_credcache(struct rpc_cred_cache *); static inline struct rpc_cred * get_rpccred(struct rpc_cred *cred) diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 9527f2bb174..f6b6c81cbc3 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -137,9 +137,8 @@ void rpcauth_destroy_credlist(struct hlist_head *head) * that are not referenced. */ void -rpcauth_free_credcache(struct rpc_auth *auth) +rpcauth_clear_credcache(struct rpc_cred_cache *cache) { - struct rpc_cred_cache *cache = auth->au_credcache; HLIST_HEAD(free); struct hlist_node *pos, *next; struct rpc_cred *cred; @@ -157,6 +156,21 @@ rpcauth_free_credcache(struct rpc_auth *auth) rpcauth_destroy_credlist(&free); } +/* + * Destroy the RPC credential cache + */ +void +rpcauth_destroy_credcache(struct rpc_auth *auth) +{ + struct rpc_cred_cache *cache = auth->au_credcache; + + if (cache) { + auth->au_credcache = NULL; + rpcauth_clear_credcache(cache); + kfree(cache); + } +} + static void rpcauth_prune_expired(struct rpc_auth *auth, struct rpc_cred *cred, struct hlist_head *free) { diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 50809086fa1..8b4c02f8bef 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -665,12 +665,13 @@ gss_destroy(struct rpc_auth *auth) dprintk("RPC: destroying GSS authenticator %p flavor %d\n", auth, auth->au_flavor); + rpcauth_destroy_credcache(auth); + gss_auth = container_of(auth, struct gss_auth, rpc_auth); rpc_unlink(gss_auth->dentry); gss_auth->dentry = NULL; gss_mech_put(gss_auth->mech); - rpcauth_free_credcache(auth); kfree(gss_auth); module_put(THIS_MODULE); } diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 82300b83045..5622783011a 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -50,7 +50,7 @@ static void unx_destroy(struct rpc_auth *auth) { dprintk("RPC: destroying UNIX authenticator %p\n", auth); - rpcauth_free_credcache(auth); + rpcauth_clear_credcache(auth->au_credcache); } /* diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index b99b11b1146..3e19e7af679 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c @@ -57,7 +57,7 @@ EXPORT_SYMBOL(rpcauth_unregister); EXPORT_SYMBOL(rpcauth_create); EXPORT_SYMBOL(rpcauth_lookupcred); EXPORT_SYMBOL(rpcauth_lookup_credcache); -EXPORT_SYMBOL(rpcauth_free_credcache); +EXPORT_SYMBOL(rpcauth_destroy_credcache); EXPORT_SYMBOL(rpcauth_init_credcache); EXPORT_SYMBOL(put_rpccred); -- cgit v1.2.3-70-g09d2 From 5c9cfc828ae34e19dabbdb9f2861b8c920454047 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 24 Jun 2007 15:24:29 -0400 Subject: SUNRPC: Fix a typo in unx_create() We want to set the unix_cred_cache.nextgc on the first call to unx_create(), which should be when unix_auth.au_count === 1 Signed-off-by: Trond Myklebust --- net/sunrpc/auth_unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 5622783011a..e54782e75d5 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -41,7 +41,7 @@ unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) { dprintk("RPC: creating UNIX authenticator for client %p\n", clnt); - if (atomic_inc_return(&unix_auth.au_count) == 0) + if (atomic_inc_return(&unix_auth.au_count) == 1) unix_cred_cache.nextgc = jiffies + (unix_cred_cache.expire >> 1); return &unix_auth; } -- cgit v1.2.3-70-g09d2 From f1c0a8615090359d57e096157feb9f900cbb233c Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 23 Jun 2007 20:17:58 -0400 Subject: SUNRPC: Mark auth and cred operation tables as constant. Also do the same for gss_api operation tables. Signed-off-by: Trond Myklebust --- include/linux/sunrpc/auth.h | 15 ++++++--------- include/linux/sunrpc/gss_api.h | 2 +- net/sunrpc/auth.c | 8 ++++---- net/sunrpc/auth_gss/auth_gss.c | 8 ++++---- net/sunrpc/auth_gss/gss_krb5_mech.c | 2 +- net/sunrpc/auth_gss/gss_spkm3_mech.c | 2 +- net/sunrpc/auth_null.c | 4 ++-- net/sunrpc/auth_unix.c | 6 +++--- 8 files changed, 22 insertions(+), 25 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index bc77c730325..e606c280468 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -35,7 +35,7 @@ struct rpc_credops; struct rpc_cred { struct hlist_node cr_hash; /* hash chain */ struct rpc_auth * cr_auth; - struct rpc_credops * cr_ops; + const struct rpc_credops *cr_ops; unsigned long cr_expire; /* when to gc */ atomic_t cr_count; /* ref count */ unsigned short cr_flags; /* various flags */ @@ -73,7 +73,7 @@ struct rpc_auth { unsigned int au_verfsize; unsigned int au_flags; /* various flags */ - struct rpc_authops * au_ops; /* operations */ + const struct rpc_authops *au_ops; /* operations */ rpc_authflavor_t au_flavor; /* pseudoflavor (note may * differ from the flavor in * au_ops->au_flavor in gss @@ -119,14 +119,11 @@ struct rpc_credops { void *, __be32 *, void *); }; -extern struct rpc_authops authunix_ops; -extern struct rpc_authops authnull_ops; -#ifdef CONFIG_SUNRPC_SECURE -extern struct rpc_authops authdes_ops; -#endif +extern const struct rpc_authops authunix_ops; +extern const struct rpc_authops authnull_ops; -int rpcauth_register(struct rpc_authops *); -int rpcauth_unregister(struct rpc_authops *); +int rpcauth_register(const struct rpc_authops *); +int rpcauth_unregister(const struct rpc_authops *); struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); void rpcauth_release(struct rpc_auth *); struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h index 5eca9e44205..bbac101ac37 100644 --- a/include/linux/sunrpc/gss_api.h +++ b/include/linux/sunrpc/gss_api.h @@ -77,7 +77,7 @@ struct gss_api_mech { struct module *gm_owner; struct xdr_netobj gm_oid; char *gm_name; - struct gss_api_ops *gm_ops; + const struct gss_api_ops *gm_ops; /* pseudoflavors supported by this mechanism: */ int gm_pf_num; struct pf_desc * gm_pfs; diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 1686dc74c6a..d3f0f944c0b 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -19,7 +19,7 @@ #endif static DEFINE_SPINLOCK(rpc_authflavor_lock); -static struct rpc_authops * auth_flavors[RPC_AUTH_MAXFLAVOR] = { +static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = { &authnull_ops, /* AUTH_NULL */ &authunix_ops, /* AUTH_UNIX */ NULL, /* others can be loadable modules */ @@ -33,7 +33,7 @@ pseudoflavor_to_flavor(u32 flavor) { } int -rpcauth_register(struct rpc_authops *ops) +rpcauth_register(const struct rpc_authops *ops) { rpc_authflavor_t flavor; int ret = -EPERM; @@ -50,7 +50,7 @@ rpcauth_register(struct rpc_authops *ops) } int -rpcauth_unregister(struct rpc_authops *ops) +rpcauth_unregister(const struct rpc_authops *ops) { rpc_authflavor_t flavor; int ret = -EPERM; @@ -70,7 +70,7 @@ struct rpc_auth * rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) { struct rpc_auth *auth; - struct rpc_authops *ops; + const struct rpc_authops *ops; u32 flavor = pseudoflavor_to_flavor(pseudoflavor); auth = ERR_PTR(-EINVAL); diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 459dc9b1d1a..177a9e413c0 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -54,9 +54,9 @@ #include #include -static struct rpc_authops authgss_ops; +static const struct rpc_authops authgss_ops; -static struct rpc_credops gss_credops; +static const struct rpc_credops gss_credops; #ifdef RPC_DEBUG # define RPCDBG_FACILITY RPCDBG_AUTH @@ -1193,7 +1193,7 @@ out: return status; } -static struct rpc_authops authgss_ops = { +static const struct rpc_authops authgss_ops = { .owner = THIS_MODULE, .au_flavor = RPC_AUTH_GSS, #ifdef RPC_DEBUG @@ -1205,7 +1205,7 @@ static struct rpc_authops authgss_ops = { .crcreate = gss_create_cred }; -static struct rpc_credops gss_credops = { +static const struct rpc_credops gss_credops = { .cr_name = "AUTH_GSS", .crdestroy = gss_destroy_cred, .cr_init = gss_cred_init, diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 7b194321705..71b9daefdff 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -201,7 +201,7 @@ gss_delete_sec_context_kerberos(void *internal_ctx) { kfree(kctx); } -static struct gss_api_ops gss_kerberos_ops = { +static const struct gss_api_ops gss_kerberos_ops = { .gss_import_sec_context = gss_import_sec_context_kerberos, .gss_get_mic = gss_get_mic_kerberos, .gss_verify_mic = gss_verify_mic_kerberos, diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c index 7e15aa68ae6..577d590e755 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c @@ -202,7 +202,7 @@ gss_get_mic_spkm3(struct gss_ctx *ctx, return err; } -static struct gss_api_ops gss_spkm3_ops = { +static const struct gss_api_ops gss_spkm3_ops = { .gss_import_sec_context = gss_import_sec_context_spkm3, .gss_get_mic = gss_get_mic_spkm3, .gss_verify_mic = gss_verify_mic_spkm3, diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c index 890bd9b3794..fe9b6aaf91e 100644 --- a/net/sunrpc/auth_null.c +++ b/net/sunrpc/auth_null.c @@ -101,7 +101,7 @@ nul_validate(struct rpc_task *task, __be32 *p) return p; } -struct rpc_authops authnull_ops = { +const struct rpc_authops authnull_ops = { .owner = THIS_MODULE, .au_flavor = RPC_AUTH_NULL, #ifdef RPC_DEBUG @@ -122,7 +122,7 @@ struct rpc_auth null_auth = { }; static -struct rpc_credops null_credops = { +const struct rpc_credops null_credops = { .cr_name = "AUTH_NULL", .crdestroy = nul_destroy_cred, .crmatch = nul_match, diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index e54782e75d5..6600c7ad72a 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -34,7 +34,7 @@ struct unx_cred { static struct rpc_auth unix_auth; static struct rpc_cred_cache unix_cred_cache; -static struct rpc_credops unix_credops; +static const struct rpc_credops unix_credops; static struct rpc_auth * unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) @@ -205,7 +205,7 @@ unx_validate(struct rpc_task *task, __be32 *p) return p; } -struct rpc_authops authunix_ops = { +const struct rpc_authops authunix_ops = { .owner = THIS_MODULE, .au_flavor = RPC_AUTH_UNIX, #ifdef RPC_DEBUG @@ -233,7 +233,7 @@ struct rpc_auth unix_auth = { }; static -struct rpc_credops unix_credops = { +const struct rpc_credops unix_credops = { .cr_name = "AUTH_UNIX", .crdestroy = unx_destroy_cred, .crmatch = unx_match, -- cgit v1.2.3-70-g09d2 From 5fe4755e2526a2aa82b7ed8daeb3aed74a236925 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 23 Jun 2007 19:55:31 -0400 Subject: SUNRPC: Clean up rpc credential initialisation Add a helper rpc_cred_init() Signed-off-by: Trond Myklebust --- include/linux/sunrpc/auth.h | 1 + include/linux/sunrpc/auth_gss.h | 5 ----- net/sunrpc/auth.c | 24 ++++++++++++++++++------ net/sunrpc/auth_gss/auth_gss.c | 6 +----- net/sunrpc/auth_unix.c | 10 ++-------- 5 files changed, 22 insertions(+), 24 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index e606c280468..d5bfc67461f 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -127,6 +127,7 @@ int rpcauth_unregister(const struct rpc_authops *); struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); void rpcauth_release(struct rpc_auth *); struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); +void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); struct rpc_cred * rpcauth_bindcred(struct rpc_task *); void rpcauth_holdcred(struct rpc_task *); diff --git a/include/linux/sunrpc/auth_gss.h b/include/linux/sunrpc/auth_gss.h index 2db2fbf3494..0bd1d06777b 100644 --- a/include/linux/sunrpc/auth_gss.h +++ b/include/linux/sunrpc/auth_gss.h @@ -85,11 +85,6 @@ struct gss_cred { struct gss_upcall_msg *gc_upcall; }; -#define gc_uid gc_base.cr_uid -#define gc_count gc_base.cr_count -#define gc_flags gc_base.cr_flags -#define gc_expire gc_base.cr_expire - #endif /* __KERNEL__ */ #endif /* _LINUX_SUNRPC_AUTH_GSS_H */ diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index d3f0f944c0b..2156327da45 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -264,13 +264,9 @@ retry: if (!cred) { new = auth->au_ops->crcreate(auth, acred, flags); - if (!IS_ERR(new)) { -#ifdef RPC_DEBUG - new->cr_magic = RPCAUTH_CRED_MAGIC; -#endif + if (!IS_ERR(new)) goto retry; - } else - cred = new; + cred = new; } else if ((cred->cr_flags & RPCAUTH_CRED_NEW) && cred->cr_ops->cr_init != NULL && !(flags & RPCAUTH_LOOKUP_NEW)) { @@ -302,6 +298,22 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags) return ret; } +void +rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred, + struct rpc_auth *auth, const struct rpc_credops *ops) +{ + INIT_HLIST_NODE(&cred->cr_hash); + atomic_set(&cred->cr_count, 1); + cred->cr_auth = auth; + cred->cr_ops = ops; + cred->cr_expire = jiffies; +#ifdef RPC_DEBUG + cred->cr_magic = RPCAUTH_CRED_MAGIC; +#endif + cred->cr_uid = acred->uid; +} +EXPORT_SYMBOL(rpcauth_init_cred); + struct rpc_cred * rpcauth_bindcred(struct rpc_task *task) { diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 177a9e413c0..766de0a41b2 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -727,15 +727,11 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL))) goto out_err; - atomic_set(&cred->gc_count, 1); - cred->gc_uid = acred->uid; + rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops); /* * Note: in order to force a call to call_refresh(), we deliberately * fail to flag the credential as RPCAUTH_CRED_UPTODATE. */ - cred->gc_flags = 0; - cred->gc_base.cr_auth = auth; - cred->gc_base.cr_ops = &gss_credops; cred->gc_base.cr_flags = RPCAUTH_CRED_NEW; cred->gc_service = gss_auth->service; return &cred->gc_base; diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 6600c7ad72a..2f1bdb5c86b 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -20,9 +20,6 @@ struct unx_cred { gid_t uc_gids[NFS_NGROUPS]; }; #define uc_uid uc_base.cr_uid -#define uc_count uc_base.cr_count -#define uc_flags uc_base.cr_flags -#define uc_expire uc_base.cr_expire #define UNX_CRED_EXPIRE (60 * HZ) @@ -74,8 +71,8 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL))) return ERR_PTR(-ENOMEM); - atomic_set(&cred->uc_count, 1); - cred->uc_flags = RPCAUTH_CRED_UPTODATE; + rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops); + cred->uc_base.cr_flags = RPCAUTH_CRED_UPTODATE; if (flags & RPCAUTH_LOOKUP_ROOTCREDS) { cred->uc_uid = 0; cred->uc_gid = 0; @@ -85,15 +82,12 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) if (groups > NFS_NGROUPS) groups = NFS_NGROUPS; - cred->uc_uid = acred->uid; cred->uc_gid = acred->gid; for (i = 0; i < groups; i++) cred->uc_gids[i] = GROUP_AT(acred->group_info, i); if (i < NFS_NGROUPS) cred->uc_gids[i] = NOGROUP; } - cred->uc_base.cr_auth = &unix_auth; - cred->uc_base.cr_ops = &unix_credops; return (struct rpc_cred *) cred; } -- cgit v1.2.3-70-g09d2 From 696e38df9d1b256e97b077ecde7afb8dd60364fd Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 25 Jun 2007 09:48:25 -0400 Subject: SUNRPC: replace casts in auth_unix.c with container_of() Signed-off-by: Trond Myklebust --- net/sunrpc/auth_unix.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 2f1bdb5c86b..f17dabbab1c 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -89,12 +89,14 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) cred->uc_gids[i] = NOGROUP; } - return (struct rpc_cred *) cred; + return &cred->uc_base; } static void -unx_destroy_cred(struct rpc_cred *cred) +unx_destroy_cred(struct rpc_cred *rcred) { + struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base); + kfree(cred); } @@ -106,7 +108,7 @@ unx_destroy_cred(struct rpc_cred *cred) static int unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags) { - struct unx_cred *cred = (struct unx_cred *) rcred; + struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base); int i; if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) { @@ -137,7 +139,7 @@ static __be32 * unx_marshal(struct rpc_task *task, __be32 *p) { struct rpc_clnt *clnt = task->tk_client; - struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred; + struct unx_cred *cred = container_of(task->tk_msg.rpc_cred, struct unx_cred, uc_base); __be32 *base, *hold; int i; -- cgit v1.2.3-70-g09d2 From fc432dd90760a629c57026e57f65ff80a1a31d2f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 25 Jun 2007 10:15:15 -0400 Subject: SUNRPC: Enforce atomic updates of rpc_cred->cr_flags Convert to the use of atomic bitops... Signed-off-by: Trond Myklebust --- include/linux/sunrpc/auth.h | 10 +++++----- net/sunrpc/auth.c | 22 ++++++++++++---------- net/sunrpc/auth_gss/auth_gss.c | 22 +++++++++++----------- net/sunrpc/auth_null.c | 4 ++-- net/sunrpc/auth_unix.c | 4 ++-- 5 files changed, 32 insertions(+), 30 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index d5bfc67461f..8586503d5eb 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -36,19 +36,19 @@ struct rpc_cred { struct hlist_node cr_hash; /* hash chain */ struct rpc_auth * cr_auth; const struct rpc_credops *cr_ops; - unsigned long cr_expire; /* when to gc */ - atomic_t cr_count; /* ref count */ - unsigned short cr_flags; /* various flags */ #ifdef RPC_DEBUG unsigned long cr_magic; /* 0x0f4aa4f0 */ #endif + unsigned long cr_expire; /* when to gc */ + unsigned long cr_flags; /* various flags */ + atomic_t cr_count; /* ref count */ uid_t cr_uid; /* per-flavor data */ }; -#define RPCAUTH_CRED_NEW 0x0001 -#define RPCAUTH_CRED_UPTODATE 0x0002 +#define RPCAUTH_CRED_NEW 0 +#define RPCAUTH_CRED_UPTODATE 1 #define RPCAUTH_CRED_MAGIC 0x0f4aa4f0 diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 2156327da45..4d7c78b05d1 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -190,8 +190,8 @@ rpcauth_prune_expired(struct rpc_auth *auth, struct rpc_cred *cred, struct hlist if (atomic_read(&cred->cr_count) != 1) return; if (time_after(jiffies, cred->cr_expire + auth->au_credcache->expire)) - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; - if (!(cred->cr_flags & RPCAUTH_CRED_UPTODATE)) { + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); + if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0) { __hlist_del(&cred->cr_hash); hlist_add_head(&cred->cr_hash, free); } @@ -267,7 +267,7 @@ retry: if (!IS_ERR(new)) goto retry; cred = new; - } else if ((cred->cr_flags & RPCAUTH_CRED_NEW) + } else if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && cred->cr_ops->cr_init != NULL && !(flags & RPCAUTH_LOOKUP_NEW)) { int res = cred->cr_ops->cr_init(auth, cred); @@ -440,17 +440,19 @@ rpcauth_refreshcred(struct rpc_task *task) void rpcauth_invalcred(struct rpc_task *task) { + struct rpc_cred *cred = task->tk_msg.rpc_cred; + dprintk("RPC: %5u invalidating %s cred %p\n", - task->tk_pid, task->tk_auth->au_ops->au_name, task->tk_msg.rpc_cred); - spin_lock(&rpc_credcache_lock); - if (task->tk_msg.rpc_cred) - task->tk_msg.rpc_cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; - spin_unlock(&rpc_credcache_lock); + task->tk_pid, task->tk_auth->au_ops->au_name, cred); + if (cred) + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); } int rpcauth_uptodatecred(struct rpc_task *task) { - return !(task->tk_msg.rpc_cred) || - (task->tk_msg.rpc_cred->cr_flags & RPCAUTH_CRED_UPTODATE); + struct rpc_cred *cred = task->tk_msg.rpc_cred; + + return cred == NULL || + test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0; } diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 766de0a41b2..55c47ae0a25 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -114,8 +114,8 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) write_lock(&gss_ctx_lock); old = gss_cred->gc_ctx; gss_cred->gc_ctx = ctx; - cred->cr_flags |= RPCAUTH_CRED_UPTODATE; - cred->cr_flags &= ~RPCAUTH_CRED_NEW; + set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); + clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); write_unlock(&gss_ctx_lock); if (old) gss_put_ctx(old); @@ -128,7 +128,7 @@ gss_cred_is_uptodate_ctx(struct rpc_cred *cred) int res = 0; read_lock(&gss_ctx_lock); - if ((cred->cr_flags & RPCAUTH_CRED_UPTODATE) && gss_cred->gc_ctx) + if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) && gss_cred->gc_ctx) res = 1; read_unlock(&gss_ctx_lock); return res; @@ -732,7 +732,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) * Note: in order to force a call to call_refresh(), we deliberately * fail to flag the credential as RPCAUTH_CRED_UPTODATE. */ - cred->gc_base.cr_flags = RPCAUTH_CRED_NEW; + cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW; cred->gc_service = gss_auth->service; return &cred->gc_base; @@ -764,7 +764,7 @@ gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags) * we don't really care if the credential has expired or not, * since the caller should be prepared to reinitialise it. */ - if ((flags & RPCAUTH_LOOKUP_NEW) && (rc->cr_flags & RPCAUTH_CRED_NEW)) + if ((flags & RPCAUTH_LOOKUP_NEW) && test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags)) goto out; /* Don't match with creds that have expired. */ if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry)) @@ -820,7 +820,7 @@ gss_marshal(struct rpc_task *task, __be32 *p) mic.data = (u8 *)(p + 1); maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic); if (maj_stat == GSS_S_CONTEXT_EXPIRED) { - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); } else if (maj_stat != 0) { printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat); goto out_put_ctx; @@ -873,7 +873,7 @@ gss_validate(struct rpc_task *task, __be32 *p) maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic); if (maj_stat == GSS_S_CONTEXT_EXPIRED) - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); if (maj_stat) goto out_bad; /* We leave it to unwrap to calculate au_rslack. For now we just @@ -927,7 +927,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic); status = -EIO; /* XXX? */ if (maj_stat == GSS_S_CONTEXT_EXPIRED) - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); else if (maj_stat) return status; q = xdr_encode_opaque(p, NULL, mic.len); @@ -1026,7 +1026,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was * done anyway, so it's safe to put the request on the wire: */ if (maj_stat == GSS_S_CONTEXT_EXPIRED) - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); else if (maj_stat) return status; @@ -1113,7 +1113,7 @@ gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic); if (maj_stat == GSS_S_CONTEXT_EXPIRED) - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); if (maj_stat != GSS_S_COMPLETE) return status; return 0; @@ -1138,7 +1138,7 @@ gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf); if (maj_stat == GSS_S_CONTEXT_EXPIRED) - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); if (maj_stat != GSS_S_COMPLETE) return status; if (ntohl(*(*p)++) != rqstp->rq_seqno) diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c index fe9b6aaf91e..6c905fb11c5 100644 --- a/net/sunrpc/auth_null.c +++ b/net/sunrpc/auth_null.c @@ -76,7 +76,7 @@ nul_marshal(struct rpc_task *task, __be32 *p) static int nul_refresh(struct rpc_task *task) { - task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE; + set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags); return 0; } @@ -136,7 +136,7 @@ struct rpc_cred null_cred = { .cr_auth = &null_auth, .cr_ops = &null_credops, .cr_count = ATOMIC_INIT(1), - .cr_flags = RPCAUTH_CRED_UPTODATE, + .cr_flags = 1UL << RPCAUTH_CRED_UPTODATE, #ifdef RPC_DEBUG .cr_magic = RPCAUTH_CRED_MAGIC, #endif diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index f17dabbab1c..29d50ffa69d 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -72,7 +72,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) return ERR_PTR(-ENOMEM); rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops); - cred->uc_base.cr_flags = RPCAUTH_CRED_UPTODATE; + cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; if (flags & RPCAUTH_LOOKUP_ROOTCREDS) { cred->uc_uid = 0; cred->uc_gid = 0; @@ -172,7 +172,7 @@ unx_marshal(struct rpc_task *task, __be32 *p) static int unx_refresh(struct rpc_task *task) { - task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE; + set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags); return 0; } -- cgit v1.2.3-70-g09d2 From 31be5bf15f3dafffce110eb1afadccbf2e3067b4 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 24 Jun 2007 15:55:26 -0400 Subject: SUNRPC: Convert the credcache lookup code to use RCU Signed-off-by: Trond Myklebust --- include/linux/sunrpc/auth.h | 3 ++ net/sunrpc/auth.c | 91 ++++++++++++++++++++++++++---------------- net/sunrpc/auth_gss/auth_gss.c | 22 +++++++--- net/sunrpc/auth_unix.c | 18 +++++++-- 4 files changed, 91 insertions(+), 43 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 4e78f0c5f01..5974e8a493c 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -16,6 +16,7 @@ #include #include +#include /* size of the nodename buffer */ #define UNX_MAXNODENAME 32 @@ -35,6 +36,7 @@ struct rpc_credops; struct rpc_cred { struct hlist_node cr_hash; /* hash chain */ struct list_head cr_lru; /* lru garbage collection */ + struct rcu_head cr_rcu; struct rpc_auth * cr_auth; const struct rpc_credops *cr_ops; #ifdef RPC_DEBUG @@ -50,6 +52,7 @@ struct rpc_cred { }; #define RPCAUTH_CRED_NEW 0 #define RPCAUTH_CRED_UPTODATE 1 +#define RPCAUTH_CRED_HASHED 2 #define RPCAUTH_CRED_MAGIC 0x0f4aa4f0 diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 00f9649b090..ad7bde2c437 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -112,6 +112,14 @@ rpcauth_release(struct rpc_auth *auth) static DEFINE_SPINLOCK(rpc_credcache_lock); +static void +rpcauth_unhash_cred_locked(struct rpc_cred *cred) +{ + hlist_del_rcu(&cred->cr_hash); + smp_mb__before_clear_bit(); + clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags); +} + /* * Initialize RPC credential cache */ @@ -166,8 +174,7 @@ rpcauth_clear_credcache(struct rpc_cred_cache *cache) cred = hlist_entry(head->first, struct rpc_cred, cr_hash); get_rpccred(cred); list_move_tail(&cred->cr_lru, &free); - smp_wmb(); - hlist_del_init(&cred->cr_hash); + rpcauth_unhash_cred_locked(cred); } } spin_unlock(&rpc_credcache_lock); @@ -207,8 +214,7 @@ rpcauth_prune_expired(struct list_head *free) continue; get_rpccred(cred); list_add_tail(&cred->cr_lru, free); - smp_wmb(); - hlist_del_init(&cred->cr_hash); + rpcauth_unhash_cred_locked(cred); } } @@ -218,10 +224,12 @@ rpcauth_prune_expired(struct list_head *free) static void rpcauth_gc_credcache(struct rpc_cred_cache *cache, struct list_head *free) { - if (time_before(jiffies, cache->nextgc)) + if (list_empty(&cred_unused) || time_before(jiffies, cache->nextgc)) return; + spin_lock(&rpc_credcache_lock); cache->nextgc = jiffies + cache->expire; rpcauth_prune_expired(free); + spin_unlock(&rpc_credcache_lock); } /* @@ -234,42 +242,57 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, LIST_HEAD(free); struct rpc_cred_cache *cache = auth->au_credcache; struct hlist_node *pos; - struct rpc_cred *new = NULL, - *cred = NULL, - *entry; + struct rpc_cred *cred = NULL, + *entry, *new; int nr = 0; if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) nr = acred->uid & RPC_CREDCACHE_MASK; -retry: - spin_lock(&rpc_credcache_lock); - hlist_for_each_entry(entry, pos, &cache->hashtable[nr], cr_hash) { + + rcu_read_lock(); + hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) { if (!entry->cr_ops->crmatch(acred, entry, flags)) continue; + spin_lock(&rpc_credcache_lock); + if (test_bit(RPCAUTH_CRED_HASHED, &entry->cr_flags) == 0) { + spin_unlock(&rpc_credcache_lock); + continue; + } cred = get_rpccred(entry); - hlist_del(&entry->cr_hash); + spin_unlock(&rpc_credcache_lock); break; } - if (new) { - if (cred) - list_add_tail(&new->cr_lru, &free); - else - cred = new; - } - if (cred) { - hlist_add_head(&cred->cr_hash, &cache->hashtable[nr]); + rcu_read_unlock(); + + if (cred != NULL) { + rpcauth_gc_credcache(cache, &free); + goto found; } - rpcauth_gc_credcache(cache, &free); - spin_unlock(&rpc_credcache_lock); - rpcauth_destroy_credlist(&free); + new = auth->au_ops->crcreate(auth, acred, flags); + if (IS_ERR(new)) { + cred = new; + goto out; + } - if (!cred) { - new = auth->au_ops->crcreate(auth, acred, flags); - if (!IS_ERR(new)) - goto retry; + spin_lock(&rpc_credcache_lock); + hlist_for_each_entry(entry, pos, &cache->hashtable[nr], cr_hash) { + if (!entry->cr_ops->crmatch(acred, entry, flags)) + continue; + cred = get_rpccred(entry); + break; + } + if (cred == NULL) { cred = new; - } else if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) + set_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags); + hlist_add_head_rcu(&cred->cr_hash, &cache->hashtable[nr]); + } else + list_add_tail(&new->cr_lru, &free); + rpcauth_prune_expired(&free); + cache->nextgc = jiffies + cache->expire; + spin_unlock(&rpc_credcache_lock); +found: + if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && cred->cr_ops->cr_init != NULL && !(flags & RPCAUTH_LOOKUP_NEW)) { int res = cred->cr_ops->cr_init(auth, cred); @@ -278,8 +301,9 @@ retry: cred = ERR_PTR(res); } } - - return (struct rpc_cred *) cred; + rpcauth_destroy_credlist(&free); +out: + return cred; } struct rpc_cred * @@ -357,21 +381,20 @@ void put_rpccred(struct rpc_cred *cred) { /* Fast path for unhashed credentials */ - if (!hlist_unhashed(&cred->cr_hash)) + if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) goto need_lock; if (!atomic_dec_and_test(&cred->cr_count)) return; goto out_destroy; - need_lock: if (!atomic_dec_and_lock(&cred->cr_count, &rpc_credcache_lock)) return; if (!list_empty(&cred->cr_lru)) list_del_init(&cred->cr_lru); if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0) - hlist_del(&cred->cr_hash); - else if (!hlist_unhashed(&cred->cr_hash)) { + rpcauth_unhash_cred_locked(cred); + else if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) { cred->cr_expire = jiffies; list_add_tail(&cred->cr_lru, &cred_unused); spin_unlock(&rpc_credcache_lock); diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 55c47ae0a25..068fa6dfb64 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -694,15 +694,25 @@ gss_destroy_ctx(struct gss_cl_ctx *ctx) } static void -gss_destroy_cred(struct rpc_cred *rc) +gss_free_cred(struct gss_cred *gss_cred) { - struct gss_cred *cred = container_of(rc, struct gss_cred, gc_base); + dprintk("RPC: gss_free_cred %p\n", gss_cred); + if (gss_cred->gc_ctx) + gss_put_ctx(gss_cred->gc_ctx); + kfree(gss_cred); +} - dprintk("RPC: gss_destroy_cred \n"); +static void +gss_free_cred_callback(struct rcu_head *head) +{ + struct gss_cred *gss_cred = container_of(head, struct gss_cred, gc_base.cr_rcu); + gss_free_cred(gss_cred); +} - if (cred->gc_ctx) - gss_put_ctx(cred->gc_ctx); - kfree(cred); +static void +gss_destroy_cred(struct rpc_cred *cred) +{ + call_rcu(&cred->cr_rcu, gss_free_cred_callback); } /* diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 29d50ffa69d..f7ff6ad3259 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -93,11 +93,23 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) } static void -unx_destroy_cred(struct rpc_cred *rcred) +unx_free_cred(struct unx_cred *unx_cred) { - struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base); + dprintk("RPC: unx_free_cred %p\n", unx_cred); + kfree(unx_cred); +} + +static void +unx_free_cred_callback(struct rcu_head *head) +{ + struct unx_cred *unx_cred = container_of(head, struct unx_cred, uc_base.cr_rcu); + unx_free_cred(unx_cred); +} - kfree(cred); +static void +unx_destroy_cred(struct rpc_cred *cred) +{ + call_rcu(&cred->cr_rcu, unx_free_cred_callback); } /* -- cgit v1.2.3-70-g09d2 From 9499b4341b56935f61af9e7e354e7d11e70f5258 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 24 Jun 2007 15:57:57 -0400 Subject: SUNRPC: Give credential cache a local spinlock Signed-off-by: Trond Myklebust --- include/linux/sunrpc/auth.h | 3 +++ net/sunrpc/auth.c | 46 +++++++++++++++++++++++++++++++-------------- net/sunrpc/auth_unix.c | 5 +++++ net/sunrpc/sunrpc_syms.c | 1 + 4 files changed, 41 insertions(+), 14 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 5974e8a493c..e5a3b5141ed 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -63,6 +63,7 @@ struct rpc_cred { #define RPC_CREDCACHE_MASK (RPC_CREDCACHE_NR - 1) struct rpc_cred_cache { struct hlist_head hashtable[RPC_CREDCACHE_NR]; + spinlock_t lock; unsigned long nextgc; /* next garbage collection */ unsigned long expire; /* cache expiry interval */ }; @@ -126,6 +127,8 @@ struct rpc_credops { extern const struct rpc_authops authunix_ops; extern const struct rpc_authops authnull_ops; +void __init rpc_init_authunix(void); + int rpcauth_register(const struct rpc_authops *); int rpcauth_unregister(const struct rpc_authops *); struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index ad7bde2c437..cf1198d10ee 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -120,6 +120,18 @@ rpcauth_unhash_cred_locked(struct rpc_cred *cred) clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags); } +static void +rpcauth_unhash_cred(struct rpc_cred *cred) +{ + spinlock_t *cache_lock; + + cache_lock = &cred->cr_auth->au_credcache->lock; + spin_lock(cache_lock); + if (atomic_read(&cred->cr_count) == 0) + rpcauth_unhash_cred_locked(cred); + spin_unlock(cache_lock); +} + /* * Initialize RPC credential cache */ @@ -134,6 +146,7 @@ rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire) return -ENOMEM; for (i = 0; i < RPC_CREDCACHE_NR; i++) INIT_HLIST_HEAD(&new->hashtable[i]); + spin_lock_init(&new->lock); new->expire = expire; new->nextgc = jiffies + (expire >> 1); auth->au_credcache = new; @@ -168,6 +181,7 @@ rpcauth_clear_credcache(struct rpc_cred_cache *cache) int i; spin_lock(&rpc_credcache_lock); + spin_lock(&cache->lock); for (i = 0; i < RPC_CREDCACHE_NR; i++) { head = &cache->hashtable[i]; while (!hlist_empty(head)) { @@ -177,6 +191,7 @@ rpcauth_clear_credcache(struct rpc_cred_cache *cache) rpcauth_unhash_cred_locked(cred); } } + spin_unlock(&cache->lock); spin_unlock(&rpc_credcache_lock); rpcauth_destroy_credlist(&free); } @@ -202,6 +217,7 @@ rpcauth_destroy_credcache(struct rpc_auth *auth) static void rpcauth_prune_expired(struct list_head *free) { + spinlock_t *cache_lock; struct rpc_cred *cred; while (!list_empty(&cred_unused)) { @@ -212,9 +228,14 @@ rpcauth_prune_expired(struct list_head *free) list_del_init(&cred->cr_lru); if (atomic_read(&cred->cr_count) != 0) continue; - get_rpccred(cred); - list_add_tail(&cred->cr_lru, free); - rpcauth_unhash_cred_locked(cred); + cache_lock = &cred->cr_auth->au_credcache->lock; + spin_lock(cache_lock); + if (atomic_read(&cred->cr_count) == 0) { + get_rpccred(cred); + list_add_tail(&cred->cr_lru, free); + rpcauth_unhash_cred_locked(cred); + } + spin_unlock(cache_lock); } } @@ -253,21 +274,19 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) { if (!entry->cr_ops->crmatch(acred, entry, flags)) continue; - spin_lock(&rpc_credcache_lock); + spin_lock(&cache->lock); if (test_bit(RPCAUTH_CRED_HASHED, &entry->cr_flags) == 0) { - spin_unlock(&rpc_credcache_lock); + spin_unlock(&cache->lock); continue; } cred = get_rpccred(entry); - spin_unlock(&rpc_credcache_lock); + spin_unlock(&cache->lock); break; } rcu_read_unlock(); - if (cred != NULL) { - rpcauth_gc_credcache(cache, &free); + if (cred != NULL) goto found; - } new = auth->au_ops->crcreate(auth, acred, flags); if (IS_ERR(new)) { @@ -275,7 +294,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, goto out; } - spin_lock(&rpc_credcache_lock); + spin_lock(&cache->lock); hlist_for_each_entry(entry, pos, &cache->hashtable[nr], cr_hash) { if (!entry->cr_ops->crmatch(acred, entry, flags)) continue; @@ -288,9 +307,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, hlist_add_head_rcu(&cred->cr_hash, &cache->hashtable[nr]); } else list_add_tail(&new->cr_lru, &free); - rpcauth_prune_expired(&free); - cache->nextgc = jiffies + cache->expire; - spin_unlock(&rpc_credcache_lock); + spin_unlock(&cache->lock); found: if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && cred->cr_ops->cr_init != NULL @@ -301,6 +318,7 @@ found: cred = ERR_PTR(res); } } + rpcauth_gc_credcache(cache, &free); rpcauth_destroy_credlist(&free); out: return cred; @@ -393,7 +411,7 @@ need_lock: if (!list_empty(&cred->cr_lru)) list_del_init(&cred->cr_lru); if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0) - rpcauth_unhash_cred_locked(cred); + rpcauth_unhash_cred(cred); else if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) { cred->cr_expire = jiffies; list_add_tail(&cred->cr_lru, &cred_unused); diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index f7ff6ad3259..205878a3caa 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -213,6 +213,11 @@ unx_validate(struct rpc_task *task, __be32 *p) return p; } +void __init rpc_init_authunix(void) +{ + spin_lock_init(&unix_cred_cache.lock); +} + const struct rpc_authops authunix_ops = { .owner = THIS_MODULE, .au_flavor = RPC_AUTH_UNIX, diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index 3e19e7af679..018065fca84 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c @@ -152,6 +152,7 @@ init_sunrpc(void) cache_register(&ip_map_cache); cache_register(&unix_gid_cache); init_socket_xprt(); + rpc_init_authunix(); out: return err; } -- cgit v1.2.3-70-g09d2 From f5c2187cfef628784d8a09b6d0f77888246d0c0f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 25 Jun 2007 17:11:20 -0400 Subject: SUNRPC: Convert the credential garbage collector into a shrinker callback Signed-off-by: Trond Myklebust --- include/linux/sunrpc/auth.h | 6 ++-- net/sunrpc/auth.c | 63 ++++++++++++++++++++++++++++++------------ net/sunrpc/auth_gss/auth_gss.c | 3 +- net/sunrpc/auth_unix.c | 6 +--- net/sunrpc/sunrpc_syms.c | 3 +- 5 files changed, 52 insertions(+), 29 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index e5a3b5141ed..7a69ca3beba 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -64,8 +64,6 @@ struct rpc_cred { struct rpc_cred_cache { struct hlist_head hashtable[RPC_CREDCACHE_NR]; spinlock_t lock; - unsigned long nextgc; /* next garbage collection */ - unsigned long expire; /* cache expiry interval */ }; struct rpc_authops; @@ -128,6 +126,8 @@ extern const struct rpc_authops authunix_ops; extern const struct rpc_authops authnull_ops; void __init rpc_init_authunix(void); +void __init rpcauth_init_module(void); +void __exit rpcauth_remove_module(void); int rpcauth_register(const struct rpc_authops *); int rpcauth_unregister(const struct rpc_authops *); @@ -147,7 +147,7 @@ int rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, int rpcauth_refreshcred(struct rpc_task *); void rpcauth_invalcred(struct rpc_task *); int rpcauth_uptodatecred(struct rpc_task *); -int rpcauth_init_credcache(struct rpc_auth *, unsigned long); +int rpcauth_init_credcache(struct rpc_auth *); void rpcauth_destroy_credcache(struct rpc_auth *); void rpcauth_clear_credcache(struct rpc_cred_cache *); diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index cf1198d10ee..81f4c776c55 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -26,6 +26,7 @@ static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = { }; static LIST_HEAD(cred_unused); +static unsigned long number_cred_unused; static u32 pseudoflavor_to_flavor(u32 flavor) { @@ -136,7 +137,7 @@ rpcauth_unhash_cred(struct rpc_cred *cred) * Initialize RPC credential cache */ int -rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire) +rpcauth_init_credcache(struct rpc_auth *auth) { struct rpc_cred_cache *new; int i; @@ -147,8 +148,6 @@ rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire) for (i = 0; i < RPC_CREDCACHE_NR; i++) INIT_HLIST_HEAD(&new->hashtable[i]); spin_lock_init(&new->lock); - new->expire = expire; - new->nextgc = jiffies + (expire >> 1); auth->au_credcache = new; return 0; } @@ -187,7 +186,11 @@ rpcauth_clear_credcache(struct rpc_cred_cache *cache) while (!hlist_empty(head)) { cred = hlist_entry(head->first, struct rpc_cred, cr_hash); get_rpccred(cred); - list_move_tail(&cred->cr_lru, &free); + if (!list_empty(&cred->cr_lru)) { + list_del(&cred->cr_lru); + number_cred_unused--; + } + list_add_tail(&cred->cr_lru, &free); rpcauth_unhash_cred_locked(cred); } } @@ -214,18 +217,16 @@ rpcauth_destroy_credcache(struct rpc_auth *auth) /* * Remove stale credentials. Avoid sleeping inside the loop. */ -static void -rpcauth_prune_expired(struct list_head *free) +static int +rpcauth_prune_expired(struct list_head *free, int nr_to_scan) { spinlock_t *cache_lock; struct rpc_cred *cred; while (!list_empty(&cred_unused)) { cred = list_entry(cred_unused.next, struct rpc_cred, cr_lru); - if (time_after(jiffies, cred->cr_expire + - cred->cr_auth->au_credcache->expire)) - break; list_del_init(&cred->cr_lru); + number_cred_unused--; if (atomic_read(&cred->cr_count) != 0) continue; cache_lock = &cred->cr_auth->au_credcache->lock; @@ -234,23 +235,32 @@ rpcauth_prune_expired(struct list_head *free) get_rpccred(cred); list_add_tail(&cred->cr_lru, free); rpcauth_unhash_cred_locked(cred); + nr_to_scan--; } spin_unlock(cache_lock); + if (nr_to_scan == 0) + break; } + return nr_to_scan; } /* - * Run garbage collector. + * Run memory cache shrinker. */ -static void -rpcauth_gc_credcache(struct rpc_cred_cache *cache, struct list_head *free) +static int +rpcauth_cache_shrinker(int nr_to_scan, gfp_t gfp_mask) { - if (list_empty(&cred_unused) || time_before(jiffies, cache->nextgc)) - return; + LIST_HEAD(free); + int res; + + if (list_empty(&cred_unused)) + return 0; spin_lock(&rpc_credcache_lock); - cache->nextgc = jiffies + cache->expire; - rpcauth_prune_expired(free); + nr_to_scan = rpcauth_prune_expired(&free, nr_to_scan); + res = (number_cred_unused / 100) * sysctl_vfs_cache_pressure; spin_unlock(&rpc_credcache_lock); + rpcauth_destroy_credlist(&free); + return res; } /* @@ -318,7 +328,6 @@ found: cred = ERR_PTR(res); } } - rpcauth_gc_credcache(cache, &free); rpcauth_destroy_credlist(&free); out: return cred; @@ -408,13 +417,16 @@ put_rpccred(struct rpc_cred *cred) need_lock: if (!atomic_dec_and_lock(&cred->cr_count, &rpc_credcache_lock)) return; - if (!list_empty(&cred->cr_lru)) + if (!list_empty(&cred->cr_lru)) { + number_cred_unused--; list_del_init(&cred->cr_lru); + } if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0) rpcauth_unhash_cred(cred); else if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) { cred->cr_expire = jiffies; list_add_tail(&cred->cr_lru, &cred_unused); + number_cred_unused++; spin_unlock(&rpc_credcache_lock); return; } @@ -520,3 +532,18 @@ rpcauth_uptodatecred(struct rpc_task *task) return cred == NULL || test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0; } + + +static struct shrinker *rpc_cred_shrinker; + +void __init rpcauth_init_module(void) +{ + rpc_init_authunix(); + rpc_cred_shrinker = set_shrinker(DEFAULT_SEEKS, rpcauth_cache_shrinker); +} + +void __exit rpcauth_remove_module(void) +{ + if (rpc_cred_shrinker != NULL) + remove_shrinker(rpc_cred_shrinker); +} diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 068fa6dfb64..8653a92144a 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -64,7 +64,6 @@ static const struct rpc_credops gss_credops; #define NFS_NGROUPS 16 -#define GSS_CRED_EXPIRE (60 * HZ) /* XXX: reasonable? */ #define GSS_CRED_SLACK 1024 /* XXX: unused */ /* length of a krb5 verifier (48), plus data added before arguments when * using integrity (two 4-byte integers): */ @@ -643,7 +642,7 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) goto err_put_mech; } - err = rpcauth_init_credcache(auth, GSS_CRED_EXPIRE); + err = rpcauth_init_credcache(auth); if (err) goto err_unlink_pipe; diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 205878a3caa..d9c50d810d1 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -21,8 +21,6 @@ struct unx_cred { }; #define uc_uid uc_base.cr_uid -#define UNX_CRED_EXPIRE (60 * HZ) - #define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2)) #ifdef RPC_DEBUG @@ -38,8 +36,7 @@ unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) { dprintk("RPC: creating UNIX authenticator for client %p\n", clnt); - if (atomic_inc_return(&unix_auth.au_count) == 1) - unix_cred_cache.nextgc = jiffies + (unix_cred_cache.expire >> 1); + atomic_inc(&unix_auth.au_count); return &unix_auth; } @@ -232,7 +229,6 @@ const struct rpc_authops authunix_ops = { static struct rpc_cred_cache unix_cred_cache = { - .expire = UNX_CRED_EXPIRE, }; static diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index 018065fca84..384c4ad5ab8 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c @@ -152,7 +152,7 @@ init_sunrpc(void) cache_register(&ip_map_cache); cache_register(&unix_gid_cache); init_socket_xprt(); - rpc_init_authunix(); + rpcauth_init_module(); out: return err; } @@ -160,6 +160,7 @@ out: static void __exit cleanup_sunrpc(void) { + rpcauth_remove_module(); cleanup_socket_xprt(); unregister_rpc_pipefs(); rpc_destroy_mempool(); -- cgit v1.2.3-70-g09d2 From 1be27f36601973815171db684c711d30557cf50c Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 27 Jun 2007 14:29:04 -0400 Subject: SUNRPC: Remove the tk_auth macro... We should almost always be deferencing the rpc_auth struct by means of the credential's cr_auth field instead of the rpc_clnt->cl_auth anyway. Fix up that historical mistake, and remove the macro that propagated it. Signed-off-by: Trond Myklebust --- fs/nfs/nfs2xdr.c | 6 +++--- fs/nfs/nfs3xdr.c | 8 ++++---- fs/nfs/nfs4xdr.c | 10 +++++----- include/linux/sunrpc/sched.h | 1 - net/sunrpc/auth.c | 25 +++++++++++++------------ net/sunrpc/auth_gss/auth_gss.c | 4 ++-- net/sunrpc/auth_unix.c | 2 +- net/sunrpc/clnt.c | 2 +- 8 files changed, 29 insertions(+), 29 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index cd3ca7b5d3d..7fcc78f2aa7 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -223,7 +223,7 @@ nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args) static int nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) { - struct rpc_auth *auth = req->rq_task->tk_auth; + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; unsigned int replen; u32 offset = (u32)args->offset; u32 count = args->count; @@ -380,7 +380,7 @@ static int nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args) { struct rpc_task *task = req->rq_task; - struct rpc_auth *auth = task->tk_auth; + struct rpc_auth *auth = task->tk_msg.rpc_cred->cr_auth; unsigned int replen; u32 count = args->count; @@ -541,7 +541,7 @@ nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res) static int nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args) { - struct rpc_auth *auth = req->rq_task->tk_auth; + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; unsigned int replen; p = xdr_encode_fhandle(p, args->fh); diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index b51df8eb9f0..b4647a22f34 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -319,7 +319,7 @@ nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *arg static int nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) { - struct rpc_auth *auth = req->rq_task->tk_auth; + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; unsigned int replen; u32 count = args->count; @@ -458,7 +458,7 @@ nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args) static int nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args) { - struct rpc_auth *auth = req->rq_task->tk_auth; + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; unsigned int replen; u32 count = args->count; @@ -643,7 +643,7 @@ static int nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p, struct nfs3_getaclargs *args) { - struct rpc_auth *auth = req->rq_task->tk_auth; + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; unsigned int replen; p = xdr_encode_fhandle(p, args->fh); @@ -773,7 +773,7 @@ nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res) static int nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args) { - struct rpc_auth *auth = req->rq_task->tk_auth; + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; unsigned int replen; p = xdr_encode_fhandle(p, args->fh); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 1fcca516e6e..859b1363325 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1071,7 +1071,7 @@ static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args) static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req) { - struct rpc_auth *auth = req->rq_task->tk_auth; + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; uint32_t attrs[2] = { FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID, FATTR4_WORD1_MOUNTED_ON_FILEID, @@ -1117,7 +1117,7 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req) { - struct rpc_auth *auth = req->rq_task->tk_auth; + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; unsigned int replen; __be32 *p; @@ -1735,7 +1735,7 @@ out: */ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) { - struct rpc_auth *auth = req->rq_task->tk_auth; + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 2, @@ -1795,7 +1795,7 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p, struct nfs_getaclargs *args) { struct xdr_stream xdr; - struct rpc_auth *auth = req->rq_task->tk_auth; + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; struct compound_hdr hdr = { .nops = 2, }; @@ -2030,7 +2030,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs struct compound_hdr hdr = { .nops = 3, }; - struct rpc_auth *auth = req->rq_task->tk_auth; + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; int replen; int status; diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 3387b008cdf..8ea077db009 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -98,7 +98,6 @@ struct rpc_task { unsigned short tk_pid; /* debugging aid */ #endif }; -#define tk_auth tk_client->cl_auth #define tk_xprt tk_client->cl_xprt /* support walking a list of tasks on a wait queue */ diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 81f4c776c55..74baf87ccff 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -371,7 +371,7 @@ EXPORT_SYMBOL(rpcauth_init_cred); struct rpc_cred * rpcauth_bindcred(struct rpc_task *task) { - struct rpc_auth *auth = task->tk_auth; + struct rpc_auth *auth = task->tk_client->cl_auth; struct auth_cred acred = { .uid = current->fsuid, .gid = current->fsgid, @@ -381,7 +381,7 @@ rpcauth_bindcred(struct rpc_task *task) int flags = 0; dprintk("RPC: %5u looking up %s cred\n", - task->tk_pid, task->tk_auth->au_ops->au_name); + task->tk_pid, task->tk_client->cl_auth->au_ops->au_name); get_group_info(acred.group_info); if (task->tk_flags & RPC_TASK_ROOTCREDS) flags |= RPCAUTH_LOOKUP_ROOTCREDS; @@ -397,11 +397,12 @@ rpcauth_bindcred(struct rpc_task *task) void rpcauth_holdcred(struct rpc_task *task) { - dprintk("RPC: %5u holding %s cred %p\n", - task->tk_pid, task->tk_auth->au_ops->au_name, - task->tk_msg.rpc_cred); - if (task->tk_msg.rpc_cred) - get_rpccred(task->tk_msg.rpc_cred); + struct rpc_cred *cred = task->tk_msg.rpc_cred; + if (cred != NULL) { + get_rpccred(cred); + dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid, + cred->cr_auth->au_ops->au_name, cred); + } } void @@ -441,7 +442,7 @@ rpcauth_unbindcred(struct rpc_task *task) struct rpc_cred *cred = task->tk_msg.rpc_cred; dprintk("RPC: %5u releasing %s cred %p\n", - task->tk_pid, task->tk_auth->au_ops->au_name, cred); + task->tk_pid, cred->cr_auth->au_ops->au_name, cred); put_rpccred(cred); task->tk_msg.rpc_cred = NULL; @@ -453,7 +454,7 @@ rpcauth_marshcred(struct rpc_task *task, __be32 *p) struct rpc_cred *cred = task->tk_msg.rpc_cred; dprintk("RPC: %5u marshaling %s cred %p\n", - task->tk_pid, task->tk_auth->au_ops->au_name, cred); + task->tk_pid, cred->cr_auth->au_ops->au_name, cred); return cred->cr_ops->crmarshal(task, p); } @@ -464,7 +465,7 @@ rpcauth_checkverf(struct rpc_task *task, __be32 *p) struct rpc_cred *cred = task->tk_msg.rpc_cred; dprintk("RPC: %5u validating %s cred %p\n", - task->tk_pid, task->tk_auth->au_ops->au_name, cred); + task->tk_pid, cred->cr_auth->au_ops->au_name, cred); return cred->cr_ops->crvalidate(task, p); } @@ -505,7 +506,7 @@ rpcauth_refreshcred(struct rpc_task *task) int err; dprintk("RPC: %5u refreshing %s cred %p\n", - task->tk_pid, task->tk_auth->au_ops->au_name, cred); + task->tk_pid, cred->cr_auth->au_ops->au_name, cred); err = cred->cr_ops->crrefresh(task); if (err < 0) @@ -519,7 +520,7 @@ rpcauth_invalcred(struct rpc_task *task) struct rpc_cred *cred = task->tk_msg.rpc_cred; dprintk("RPC: %5u invalidating %s cred %p\n", - task->tk_pid, task->tk_auth->au_ops->au_name, cred); + task->tk_pid, cred->cr_auth->au_ops->au_name, cred); if (cred) clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); } diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 15da6f82db3..debcda86467 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -906,7 +906,7 @@ gss_validate(struct rpc_task *task, __be32 *p) goto out_bad; /* We leave it to unwrap to calculate au_rslack. For now we just * calculate the length of the verifier: */ - task->tk_auth->au_verfsize = XDR_QUADLEN(len) + 2; + cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2; gss_put_ctx(ctx); dprintk("RPC: %5u gss_validate: gss_verify_mic succeeded.\n", task->tk_pid); @@ -1206,7 +1206,7 @@ gss_unwrap_resp(struct rpc_task *task, break; } /* take into account extra slack for integrity and privacy cases: */ - task->tk_auth->au_rslack = task->tk_auth->au_verfsize + (p - savedp) + cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) + (savedlen - head->iov_len); out_decode: status = decode(rqstp, p, obj); diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index d9c50d810d1..5ed91e5bcee 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -204,7 +204,7 @@ unx_validate(struct rpc_task *task, __be32 *p) printk("RPC: giant verf size: %u\n", size); return NULL; } - task->tk_auth->au_rslack = (size >> 2) + 2; + task->tk_msg.rpc_cred->cr_auth->au_rslack = (size >> 2) + 2; p += (size >> 2); return p; diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 28a789419f6..50af8bbe7f2 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -787,7 +787,7 @@ call_reserveresult(struct rpc_task *task) static void call_allocate(struct rpc_task *task) { - unsigned int slack = task->tk_auth->au_cslack; + unsigned int slack = task->tk_msg.rpc_cred->cr_auth->au_cslack; struct rpc_rqst *req = task->tk_rqstp; struct rpc_xprt *xprt = task->tk_xprt; struct rpc_procinfo *proc = task->tk_msg.rpc_proc; -- cgit v1.2.3-70-g09d2