Commit a00dd564 authored by Trond Myklebust's avatar Trond Myklebust

RPC: Convert RPC credcache to use hlists

 This will make initialization of statically allocated caches simpler.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 378e5f26
...@@ -35,7 +35,7 @@ struct auth_cred { ...@@ -35,7 +35,7 @@ struct auth_cred {
* Client user credentials * Client user credentials
*/ */
struct rpc_cred { struct rpc_cred {
struct list_head cr_hash; /* hash chain */ struct hlist_node cr_hash; /* hash chain */
struct rpc_credops * cr_ops; struct rpc_credops * cr_ops;
unsigned long cr_expire; /* when to gc */ unsigned long cr_expire; /* when to gc */
atomic_t cr_count; /* ref count */ atomic_t cr_count; /* ref count */
...@@ -59,7 +59,7 @@ struct rpc_cred { ...@@ -59,7 +59,7 @@ struct rpc_cred {
#define RPC_CREDCACHE_NR 8 #define RPC_CREDCACHE_NR 8
#define RPC_CREDCACHE_MASK (RPC_CREDCACHE_NR - 1) #define RPC_CREDCACHE_MASK (RPC_CREDCACHE_NR - 1)
struct rpc_auth { struct rpc_auth {
struct list_head au_credcache[RPC_CREDCACHE_NR]; struct hlist_head au_credcache[RPC_CREDCACHE_NR];
unsigned long au_expire; /* cache expiry interval */ unsigned long au_expire; /* cache expiry interval */
unsigned long au_nextgc; /* next garbage collection */ unsigned long au_nextgc; /* next garbage collection */
unsigned int au_cslack; /* call cred size estimate */ unsigned int au_cslack; /* call cred size estimate */
......
...@@ -94,7 +94,7 @@ rpcauth_init_credcache(struct rpc_auth *auth) ...@@ -94,7 +94,7 @@ rpcauth_init_credcache(struct rpc_auth *auth)
{ {
int i; int i;
for (i = 0; i < RPC_CREDCACHE_NR; i++) for (i = 0; i < RPC_CREDCACHE_NR; i++)
INIT_LIST_HEAD(&auth->au_credcache[i]); INIT_HLIST_HEAD(&auth->au_credcache[i]);
auth->au_nextgc = jiffies + (auth->au_expire >> 1); auth->au_nextgc = jiffies + (auth->au_expire >> 1);
} }
...@@ -102,13 +102,13 @@ rpcauth_init_credcache(struct rpc_auth *auth) ...@@ -102,13 +102,13 @@ rpcauth_init_credcache(struct rpc_auth *auth)
* Destroy a list of credentials * Destroy a list of credentials
*/ */
static inline static inline
void rpcauth_destroy_credlist(struct list_head *head) void rpcauth_destroy_credlist(struct hlist_head *head)
{ {
struct rpc_cred *cred; struct rpc_cred *cred;
while (!list_empty(head)) { while (!hlist_empty(head)) {
cred = list_entry(head->next, struct rpc_cred, cr_hash); cred = hlist_entry(head->first, struct rpc_cred, cr_hash);
list_del_init(&cred->cr_hash); hlist_del_init(&cred->cr_hash);
put_rpccred(cred); put_rpccred(cred);
} }
} }
...@@ -120,16 +120,17 @@ void rpcauth_destroy_credlist(struct list_head *head) ...@@ -120,16 +120,17 @@ void rpcauth_destroy_credlist(struct list_head *head)
void void
rpcauth_free_credcache(struct rpc_auth *auth) rpcauth_free_credcache(struct rpc_auth *auth)
{ {
LIST_HEAD(free); HLIST_HEAD(free);
struct list_head *pos, *next; struct hlist_node *pos, *next;
struct rpc_cred *cred; struct rpc_cred *cred;
int i; int i;
spin_lock(&rpc_credcache_lock); spin_lock(&rpc_credcache_lock);
for (i = 0; i < RPC_CREDCACHE_NR; i++) { for (i = 0; i < RPC_CREDCACHE_NR; i++) {
list_for_each_safe(pos, next, &auth->au_credcache[i]) { hlist_for_each_safe(pos, next, &auth->au_credcache[i]) {
cred = list_entry(pos, struct rpc_cred, cr_hash); cred = hlist_entry(pos, struct rpc_cred, cr_hash);
list_move(&cred->cr_hash, &free); __hlist_del(&cred->cr_hash);
hlist_add_head(&cred->cr_hash, &free);
} }
} }
spin_unlock(&rpc_credcache_lock); spin_unlock(&rpc_credcache_lock);
...@@ -137,30 +138,32 @@ rpcauth_free_credcache(struct rpc_auth *auth) ...@@ -137,30 +138,32 @@ rpcauth_free_credcache(struct rpc_auth *auth)
} }
static void static void
rpcauth_prune_expired(struct rpc_auth *auth, struct rpc_cred *cred, struct list_head *free) rpcauth_prune_expired(struct rpc_auth *auth, struct rpc_cred *cred, struct hlist_head *free)
{ {
if (atomic_read(&cred->cr_count) != 1) if (atomic_read(&cred->cr_count) != 1)
return; return;
if (time_after(jiffies, cred->cr_expire + auth->au_expire)) if (time_after(jiffies, cred->cr_expire + auth->au_expire))
cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
if (!(cred->cr_flags & RPCAUTH_CRED_UPTODATE)) if (!(cred->cr_flags & RPCAUTH_CRED_UPTODATE)) {
list_move(&cred->cr_hash, free); __hlist_del(&cred->cr_hash);
hlist_add_head(&cred->cr_hash, free);
}
} }
/* /*
* Remove stale credentials. Avoid sleeping inside the loop. * Remove stale credentials. Avoid sleeping inside the loop.
*/ */
static void static void
rpcauth_gc_credcache(struct rpc_auth *auth, struct list_head *free) rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free)
{ {
struct list_head *pos, *next; struct hlist_node *pos, *next;
struct rpc_cred *cred; struct rpc_cred *cred;
int i; int i;
dprintk("RPC: gc'ing RPC credentials for auth %p\n", auth); dprintk("RPC: gc'ing RPC credentials for auth %p\n", auth);
for (i = 0; i < RPC_CREDCACHE_NR; i++) { for (i = 0; i < RPC_CREDCACHE_NR; i++) {
list_for_each_safe(pos, next, &auth->au_credcache[i]) { hlist_for_each_safe(pos, next, &auth->au_credcache[i]) {
cred = list_entry(pos, struct rpc_cred, cr_hash); cred = hlist_entry(pos, struct rpc_cred, cr_hash);
rpcauth_prune_expired(auth, cred, free); rpcauth_prune_expired(auth, cred, free);
} }
} }
...@@ -174,8 +177,8 @@ struct rpc_cred * ...@@ -174,8 +177,8 @@ struct rpc_cred *
rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
int taskflags) int taskflags)
{ {
LIST_HEAD(free); HLIST_HEAD(free);
struct list_head *pos, *next; struct hlist_node *pos, *next;
struct rpc_cred *new = NULL, struct rpc_cred *new = NULL,
*cred = NULL; *cred = NULL;
int nr = 0; int nr = 0;
...@@ -186,11 +189,11 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, ...@@ -186,11 +189,11 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
spin_lock(&rpc_credcache_lock); spin_lock(&rpc_credcache_lock);
if (time_before(auth->au_nextgc, jiffies)) if (time_before(auth->au_nextgc, jiffies))
rpcauth_gc_credcache(auth, &free); rpcauth_gc_credcache(auth, &free);
list_for_each_safe(pos, next, &auth->au_credcache[nr]) { hlist_for_each_safe(pos, next, &auth->au_credcache[nr]) {
struct rpc_cred *entry; struct rpc_cred *entry;
entry = list_entry(pos, struct rpc_cred, cr_hash); entry = hlist_entry(pos, struct rpc_cred, cr_hash);
if (entry->cr_ops->crmatch(acred, entry, taskflags)) { if (entry->cr_ops->crmatch(acred, entry, taskflags)) {
list_del(&entry->cr_hash); hlist_del(&entry->cr_hash);
cred = entry; cred = entry;
break; break;
} }
...@@ -198,12 +201,12 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, ...@@ -198,12 +201,12 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
} }
if (new) { if (new) {
if (cred) if (cred)
list_add(&new->cr_hash, &free); hlist_add_head(&new->cr_hash, &free);
else else
cred = new; cred = new;
} }
if (cred) { if (cred) {
list_add(&cred->cr_hash, &auth->au_credcache[nr]); hlist_add_head(&cred->cr_hash, &auth->au_credcache[nr]);
get_rpccred(cred); get_rpccred(cred);
} }
spin_unlock(&rpc_credcache_lock); spin_unlock(&rpc_credcache_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment