RPC: Shrink struct rpc_auth for those flavours that don't use the cache Signed-off-by: Trond Myklebust --- include/linux/sunrpc/auth.h | 12 ++++++++---- net/sunrpc/auth.c | 33 ++++++++++++++++++++++----------- net/sunrpc/auth_gss/auth_gss.c | 4 ++-- net/sunrpc/auth_unix.c | 10 ++++++++-- 4 files changed, 40 insertions(+), 19 deletions(-) Index: linux-2.6.11-rc3/net/sunrpc/auth.c =================================================================== --- linux-2.6.11-rc3.orig/net/sunrpc/auth.c +++ linux-2.6.11-rc3/net/sunrpc/auth.c @@ -89,13 +89,21 @@ static DEFINE_SPINLOCK(rpc_credcache_loc /* * Initialize RPC credential cache */ -void -rpcauth_init_credcache(struct rpc_auth *auth) +int +rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire) { + struct rpc_cred_cache *new; int i; + + new = (struct rpc_cred_cache *)kmalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return -ENOMEM; for (i = 0; i < RPC_CREDCACHE_NR; i++) - INIT_HLIST_HEAD(&auth->au_credcache[i]); - auth->au_nextgc = jiffies + (auth->au_expire >> 1); + INIT_HLIST_HEAD(&new->hashtable[i]); + new->expire = expire; + new->nextgc = jiffies + (expire >> 1); + auth->au_credcache = new; + return 0; } /* @@ -120,6 +128,7 @@ void rpcauth_destroy_credlist(struct hli void rpcauth_free_credcache(struct rpc_auth *auth) { + struct rpc_cred_cache *cache = auth->au_credcache; HLIST_HEAD(free); struct hlist_node *pos, *next; struct rpc_cred *cred; @@ -127,7 +136,7 @@ rpcauth_free_credcache(struct rpc_auth * spin_lock(&rpc_credcache_lock); for (i = 0; i < RPC_CREDCACHE_NR; i++) { - hlist_for_each_safe(pos, next, &auth->au_credcache[i]) { + hlist_for_each_safe(pos, next, &cache->hashtable[i]) { cred = hlist_entry(pos, struct rpc_cred, cr_hash); __hlist_del(&cred->cr_hash); hlist_add_head(&cred->cr_hash, &free); @@ -142,7 +151,7 @@ rpcauth_prune_expired(struct rpc_auth *a { if (atomic_read(&cred->cr_count) != 1) return; - if (time_after(jiffies, cred->cr_expire + auth->au_expire)) + if (time_after(jiffies, cred->cr_expire + auth->au_credcache->expire)) cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; if (!(cred->cr_flags & RPCAUTH_CRED_UPTODATE)) { __hlist_del(&cred->cr_hash); @@ -156,18 +165,19 @@ rpcauth_prune_expired(struct rpc_auth *a static void rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free) { + struct rpc_cred_cache *cache = auth->au_credcache; struct hlist_node *pos, *next; struct rpc_cred *cred; int i; dprintk("RPC: gc'ing RPC credentials for auth %p\n", auth); for (i = 0; i < RPC_CREDCACHE_NR; i++) { - hlist_for_each_safe(pos, next, &auth->au_credcache[i]) { + hlist_for_each_safe(pos, next, &cache->hashtable[i]) { cred = hlist_entry(pos, struct rpc_cred, cr_hash); rpcauth_prune_expired(auth, cred, free); } } - auth->au_nextgc = jiffies + auth->au_expire; + cache->nextgc = jiffies + cache->expire; } /* @@ -177,6 +187,7 @@ struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, int taskflags) { + struct rpc_cred_cache *cache = auth->au_credcache; HLIST_HEAD(free); struct hlist_node *pos, *next; struct rpc_cred *new = NULL, @@ -187,9 +198,9 @@ rpcauth_lookup_credcache(struct rpc_auth nr = acred->uid & RPC_CREDCACHE_MASK; retry: spin_lock(&rpc_credcache_lock); - if (time_before(auth->au_nextgc, jiffies)) + if (time_before(cache->nextgc, jiffies)) rpcauth_gc_credcache(auth, &free); - hlist_for_each_safe(pos, next, &auth->au_credcache[nr]) { + hlist_for_each_safe(pos, next, &cache->hashtable[nr]) { struct rpc_cred *entry; entry = hlist_entry(pos, struct rpc_cred, cr_hash); if (entry->cr_ops->crmatch(acred, entry, taskflags)) { @@ -206,7 +217,7 @@ retry: cred = new; } if (cred) { - hlist_add_head(&cred->cr_hash, &auth->au_credcache[nr]); + hlist_add_head(&cred->cr_hash, &cache->hashtable[nr]); get_rpccred(cred); } spin_unlock(&rpc_credcache_lock); Index: linux-2.6.11-rc3/include/linux/sunrpc/auth.h =================================================================== --- linux-2.6.11-rc3.orig/include/linux/sunrpc/auth.h +++ linux-2.6.11-rc3/include/linux/sunrpc/auth.h @@ -58,10 +58,13 @@ struct rpc_cred { */ #define RPC_CREDCACHE_NR 8 #define RPC_CREDCACHE_MASK (RPC_CREDCACHE_NR - 1) +struct rpc_cred_cache { + struct hlist_head hashtable[RPC_CREDCACHE_NR]; + unsigned long nextgc; /* next garbage collection */ + unsigned long expire; /* cache expiry interval */ +}; + struct rpc_auth { - struct hlist_head au_credcache[RPC_CREDCACHE_NR]; - unsigned long au_expire; /* cache expiry interval */ - unsigned long au_nextgc; /* next garbage collection */ unsigned int au_cslack; /* call cred size estimate */ unsigned int au_rslack; /* reply verf size guess */ unsigned int au_flags; /* various flags */ @@ -72,6 +75,7 @@ struct rpc_auth { * case) */ atomic_t au_count; /* Reference counter */ + struct rpc_cred_cache * au_credcache; /* per-flavor data */ }; #define RPC_AUTH_PROC_CREDS 0x0010 /* process creds (including @@ -131,7 +135,7 @@ int rpcauth_unwrap_resp(struct rpc_tas int rpcauth_refreshcred(struct rpc_task *); void rpcauth_invalcred(struct rpc_task *); int rpcauth_uptodatecred(struct rpc_task *); -void rpcauth_init_credcache(struct rpc_auth *); +int rpcauth_init_credcache(struct rpc_auth *, unsigned long); void rpcauth_free_credcache(struct rpc_auth *); static inline Index: linux-2.6.11-rc3/net/sunrpc/auth_gss/auth_gss.c =================================================================== --- linux-2.6.11-rc3.orig/net/sunrpc/auth_gss/auth_gss.c +++ linux-2.6.11-rc3/net/sunrpc/auth_gss/auth_gss.c @@ -581,12 +581,12 @@ gss_create(struct rpc_clnt *clnt, rpc_au auth = &gss_auth->rpc_auth; auth->au_cslack = GSS_CRED_SLACK >> 2; auth->au_rslack = GSS_VERF_SLACK >> 2; - auth->au_expire = GSS_CRED_EXPIRE; auth->au_ops = &authgss_ops; auth->au_flavor = flavor; atomic_set(&auth->au_count, 1); - rpcauth_init_credcache(auth); + if (rpcauth_init_credcache(auth, GSS_CRED_EXPIRE) < 0) + goto err_put_mech; snprintf(gss_auth->path, sizeof(gss_auth->path), "%s/%s", clnt->cl_pathname, Index: linux-2.6.11-rc3/net/sunrpc/auth_unix.c =================================================================== --- linux-2.6.11-rc3.orig/net/sunrpc/auth_unix.c +++ linux-2.6.11-rc3/net/sunrpc/auth_unix.c @@ -37,6 +37,7 @@ struct unx_cred { #endif static struct rpc_auth unix_auth; +static struct rpc_cred_cache unix_cred_cache; static struct rpc_credops unix_credops; static struct rpc_auth * @@ -44,7 +45,7 @@ unx_create(struct rpc_clnt *clnt, rpc_au { dprintk("RPC: creating UNIX authenticator for client %p\n", clnt); if (atomic_inc_return(&unix_auth.au_count) == 0) - unix_auth.au_nextgc = jiffies + (unix_auth.au_expire >> 1); + unix_cred_cache.nextgc = jiffies + (unix_cred_cache.expire >> 1); return &unix_auth; } @@ -229,12 +230,17 @@ struct rpc_authops authunix_ops = { }; static +struct rpc_cred_cache unix_cred_cache = { + .expire = UNX_CRED_EXPIRE, +}; + +static struct rpc_auth unix_auth = { .au_cslack = UNX_WRITESLACK, .au_rslack = 2, /* assume AUTH_NULL verf */ - .au_expire = UNX_CRED_EXPIRE, .au_ops = &authunix_ops, .au_count = ATOMIC_INIT(0), + .au_credcache = &unix_cred_cache, }; static