Commit 30382d6c authored by Trond Myklebust's avatar Trond Myklebust Committed by J. Bruce Fields

SUNRPC: Remove the server 'authtab_lock' and just use RCU

Module removal is RCU safe by design, so we really have no need to
lock the 'authtab[]' array.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 7d20b6a2
...@@ -27,12 +27,32 @@ ...@@ -27,12 +27,32 @@
extern struct auth_ops svcauth_null; extern struct auth_ops svcauth_null;
extern struct auth_ops svcauth_unix; extern struct auth_ops svcauth_unix;
static DEFINE_SPINLOCK(authtab_lock); static struct auth_ops __rcu *authtab[RPC_AUTH_MAXFLAVOR] = {
static struct auth_ops *authtab[RPC_AUTH_MAXFLAVOR] = { [RPC_AUTH_NULL] = (struct auth_ops __force __rcu *)&svcauth_null,
[0] = &svcauth_null, [RPC_AUTH_UNIX] = (struct auth_ops __force __rcu *)&svcauth_unix,
[1] = &svcauth_unix,
}; };
static struct auth_ops *
svc_get_auth_ops(rpc_authflavor_t flavor)
{
struct auth_ops *aops;
if (flavor >= RPC_AUTH_MAXFLAVOR)
return NULL;
rcu_read_lock();
aops = rcu_dereference(authtab[flavor]);
if (aops != NULL && !try_module_get(aops->owner))
aops = NULL;
rcu_read_unlock();
return aops;
}
static void
svc_put_auth_ops(struct auth_ops *aops)
{
module_put(aops->owner);
}
int int
svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
{ {
...@@ -45,14 +65,11 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) ...@@ -45,14 +65,11 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
dprintk("svc: svc_authenticate (%d)\n", flavor); dprintk("svc: svc_authenticate (%d)\n", flavor);
spin_lock(&authtab_lock); aops = svc_get_auth_ops(flavor);
if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor]) || if (aops == NULL) {
!try_module_get(aops->owner)) {
spin_unlock(&authtab_lock);
*authp = rpc_autherr_badcred; *authp = rpc_autherr_badcred;
return SVC_DENIED; return SVC_DENIED;
} }
spin_unlock(&authtab_lock);
rqstp->rq_auth_slack = 0; rqstp->rq_auth_slack = 0;
init_svc_cred(&rqstp->rq_cred); init_svc_cred(&rqstp->rq_cred);
...@@ -82,7 +99,7 @@ int svc_authorise(struct svc_rqst *rqstp) ...@@ -82,7 +99,7 @@ int svc_authorise(struct svc_rqst *rqstp)
if (aops) { if (aops) {
rv = aops->release(rqstp); rv = aops->release(rqstp);
module_put(aops->owner); svc_put_auth_ops(aops);
} }
return rv; return rv;
} }
...@@ -90,13 +107,14 @@ int svc_authorise(struct svc_rqst *rqstp) ...@@ -90,13 +107,14 @@ int svc_authorise(struct svc_rqst *rqstp)
int int
svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops) svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops)
{ {
struct auth_ops *old;
int rv = -EINVAL; int rv = -EINVAL;
spin_lock(&authtab_lock);
if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] == NULL) { if (flavor < RPC_AUTH_MAXFLAVOR) {
authtab[flavor] = aops; old = cmpxchg((struct auth_ops ** __force)&authtab[flavor], NULL, aops);
if (old == NULL || old == aops)
rv = 0; rv = 0;
} }
spin_unlock(&authtab_lock);
return rv; return rv;
} }
EXPORT_SYMBOL_GPL(svc_auth_register); EXPORT_SYMBOL_GPL(svc_auth_register);
...@@ -104,10 +122,8 @@ EXPORT_SYMBOL_GPL(svc_auth_register); ...@@ -104,10 +122,8 @@ EXPORT_SYMBOL_GPL(svc_auth_register);
void void
svc_auth_unregister(rpc_authflavor_t flavor) svc_auth_unregister(rpc_authflavor_t flavor)
{ {
spin_lock(&authtab_lock);
if (flavor < RPC_AUTH_MAXFLAVOR) if (flavor < RPC_AUTH_MAXFLAVOR)
authtab[flavor] = NULL; rcu_assign_pointer(authtab[flavor], NULL);
spin_unlock(&authtab_lock);
} }
EXPORT_SYMBOL_GPL(svc_auth_unregister); EXPORT_SYMBOL_GPL(svc_auth_unregister);
......
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