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:
Родитель
7d20b6a272
Коммит
30382d6ce5
|
@ -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);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче