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 {
* Client user credentials
*/
struct rpc_cred {
struct list_head cr_hash; /* hash chain */
struct hlist_node cr_hash; /* hash chain */
struct rpc_credops * cr_ops;
unsigned long cr_expire; /* when to gc */
atomic_t cr_count; /* ref count */
......@@ -59,7 +59,7 @@ struct rpc_cred {
#define RPC_CREDCACHE_NR 8
#define RPC_CREDCACHE_MASK (RPC_CREDCACHE_NR - 1)
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_nextgc; /* next garbage collection */
unsigned int au_cslack; /* call cred size estimate */
......
......@@ -94,7 +94,7 @@ rpcauth_init_credcache(struct rpc_auth *auth)
{
int 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);
}
......@@ -102,13 +102,13 @@ rpcauth_init_credcache(struct rpc_auth *auth)
* Destroy a list of credentials
*/
static inline
void rpcauth_destroy_credlist(struct list_head *head)
void rpcauth_destroy_credlist(struct hlist_head *head)
{
struct rpc_cred *cred;
while (!list_empty(head)) {
cred = list_entry(head->next, struct rpc_cred, cr_hash);
list_del_init(&cred->cr_hash);
while (!hlist_empty(head)) {
cred = hlist_entry(head->first, struct rpc_cred, cr_hash);
hlist_del_init(&cred->cr_hash);
put_rpccred(cred);
}
}
......@@ -120,16 +120,17 @@ void rpcauth_destroy_credlist(struct list_head *head)
void
rpcauth_free_credcache(struct rpc_auth *auth)
{
LIST_HEAD(free);
struct list_head *pos, *next;
HLIST_HEAD(free);
struct hlist_node *pos, *next;
struct rpc_cred *cred;
int i;
spin_lock(&rpc_credcache_lock);
for (i = 0; i < RPC_CREDCACHE_NR; i++) {
list_for_each_safe(pos, next, &auth->au_credcache[i]) {
cred = list_entry(pos, struct rpc_cred, cr_hash);
list_move(&cred->cr_hash, &free);
hlist_for_each_safe(pos, next, &auth->au_credcache[i]) {
cred = hlist_entry(pos, struct rpc_cred, cr_hash);
__hlist_del(&cred->cr_hash);
hlist_add_head(&cred->cr_hash, &free);
}
}
spin_unlock(&rpc_credcache_lock);
......@@ -137,30 +138,32 @@ rpcauth_free_credcache(struct rpc_auth *auth)
}
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)
return;
if (time_after(jiffies, cred->cr_expire + auth->au_expire))
cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
if (!(cred->cr_flags & RPCAUTH_CRED_UPTODATE))
list_move(&cred->cr_hash, free);
if (!(cred->cr_flags & RPCAUTH_CRED_UPTODATE)) {
__hlist_del(&cred->cr_hash);
hlist_add_head(&cred->cr_hash, free);
}
}
/*
* Remove stale credentials. Avoid sleeping inside the loop.
*/
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;
int i;
dprintk("RPC: gc'ing RPC credentials for auth %p\n", auth);
for (i = 0; i < RPC_CREDCACHE_NR; i++) {
list_for_each_safe(pos, next, &auth->au_credcache[i]) {
cred = list_entry(pos, struct rpc_cred, cr_hash);
hlist_for_each_safe(pos, next, &auth->au_credcache[i]) {
cred = hlist_entry(pos, struct rpc_cred, cr_hash);
rpcauth_prune_expired(auth, cred, free);
}
}
......@@ -174,8 +177,8 @@ struct rpc_cred *
rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
int taskflags)
{
LIST_HEAD(free);
struct list_head *pos, *next;
HLIST_HEAD(free);
struct hlist_node *pos, *next;
struct rpc_cred *new = NULL,
*cred = NULL;
int nr = 0;
......@@ -186,11 +189,11 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
spin_lock(&rpc_credcache_lock);
if (time_before(auth->au_nextgc, jiffies))
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;
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)) {
list_del(&entry->cr_hash);
hlist_del(&entry->cr_hash);
cred = entry;
break;
}
......@@ -198,12 +201,12 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
}
if (new) {
if (cred)
list_add(&new->cr_hash, &free);
hlist_add_head(&new->cr_hash, &free);
else
cred = new;
}
if (cred) {
list_add(&cred->cr_hash, &auth->au_credcache[nr]);
hlist_add_head(&cred->cr_hash, &auth->au_credcache[nr]);
get_rpccred(cred);
}
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