diff options
author | Trond Myklebust <trondmy@gmail.com> | 2018-10-01 16:41:44 +0200 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2018-10-03 17:32:59 +0200 |
commit | 608a0ab2f54ab0e301ad76a41aad979ea0d02670 (patch) | |
tree | 26382fa9fd57a2f549fb991c067c72257a2b2b61 /net/sunrpc/svcauth.c | |
parent | SUNRPC: Remove the server 'authtab_lock' and just use RCU (diff) | |
download | linux-608a0ab2f54ab0e301ad76a41aad979ea0d02670.tar.xz linux-608a0ab2f54ab0e301ad76a41aad979ea0d02670.zip |
SUNRPC: Add lockless lookup of the server's auth domain
Avoid taking the global auth_domain_lock in most lookups of the auth domain
by adding an RCU protected lookup.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc/svcauth.c')
-rw-r--r-- | net/sunrpc/svcauth.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index f83443856cd1..775b8c94265b 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c @@ -143,10 +143,11 @@ static struct hlist_head auth_domain_table[DN_HASHMAX]; static DEFINE_SPINLOCK(auth_domain_lock); static void auth_domain_release(struct kref *kref) + __releases(&auth_domain_lock) { struct auth_domain *dom = container_of(kref, struct auth_domain, ref); - hlist_del(&dom->hash); + hlist_del_rcu(&dom->hash); dom->flavour->domain_release(dom); spin_unlock(&auth_domain_lock); } @@ -175,7 +176,7 @@ auth_domain_lookup(char *name, struct auth_domain *new) } } if (new) - hlist_add_head(&new->hash, head); + hlist_add_head_rcu(&new->hash, head); spin_unlock(&auth_domain_lock); return new; } @@ -183,6 +184,21 @@ EXPORT_SYMBOL_GPL(auth_domain_lookup); struct auth_domain *auth_domain_find(char *name) { - return auth_domain_lookup(name, NULL); + struct auth_domain *hp; + struct hlist_head *head; + + head = &auth_domain_table[hash_str(name, DN_HASHBITS)]; + + rcu_read_lock(); + hlist_for_each_entry_rcu(hp, head, hash) { + if (strcmp(hp->name, name)==0) { + if (!kref_get_unless_zero(&hp->ref)) + hp = NULL; + rcu_read_unlock(); + return hp; + } + } + rcu_read_unlock(); + return NULL; } EXPORT_SYMBOL_GPL(auth_domain_find); |