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: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
Trond Myklebust 2018-10-01 10:41:43 -04:00 коммит произвёл J. Bruce Fields
Родитель 7d20b6a272
Коммит 30382d6ce5
1 изменённых файлов: 34 добавлений и 18 удалений

Просмотреть файл

@ -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)
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)
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)
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);
rv = 0; if (old == NULL || old == aops)
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);
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);