Loading net/sunrpc/svcauth.c +34 −18 Original line number Diff line number Diff line Loading @@ -27,12 +27,32 @@ extern struct auth_ops svcauth_null; extern struct auth_ops svcauth_unix; static DEFINE_SPINLOCK(authtab_lock); static struct auth_ops *authtab[RPC_AUTH_MAXFLAVOR] = { [0] = &svcauth_null, [1] = &svcauth_unix, static struct auth_ops __rcu *authtab[RPC_AUTH_MAXFLAVOR] = { [RPC_AUTH_NULL] = (struct auth_ops __force __rcu *)&svcauth_null, [RPC_AUTH_UNIX] = (struct auth_ops __force __rcu *)&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 svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) { Loading @@ -45,14 +65,11 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) dprintk("svc: svc_authenticate (%d)\n", flavor); spin_lock(&authtab_lock); if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor]) || !try_module_get(aops->owner)) { spin_unlock(&authtab_lock); aops = svc_get_auth_ops(flavor); if (aops == NULL) { *authp = rpc_autherr_badcred; return SVC_DENIED; } spin_unlock(&authtab_lock); rqstp->rq_auth_slack = 0; init_svc_cred(&rqstp->rq_cred); Loading Loading @@ -82,7 +99,7 @@ int svc_authorise(struct svc_rqst *rqstp) if (aops) { rv = aops->release(rqstp); module_put(aops->owner); svc_put_auth_ops(aops); } return rv; } Loading @@ -90,13 +107,14 @@ int svc_authorise(struct svc_rqst *rqstp) int svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops) { struct auth_ops *old; int rv = -EINVAL; spin_lock(&authtab_lock); if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] == NULL) { authtab[flavor] = aops; if (flavor < RPC_AUTH_MAXFLAVOR) { old = cmpxchg((struct auth_ops ** __force)&authtab[flavor], NULL, aops); if (old == NULL || old == aops) rv = 0; } spin_unlock(&authtab_lock); return rv; } EXPORT_SYMBOL_GPL(svc_auth_register); Loading @@ -104,10 +122,8 @@ EXPORT_SYMBOL_GPL(svc_auth_register); void svc_auth_unregister(rpc_authflavor_t flavor) { spin_lock(&authtab_lock); if (flavor < RPC_AUTH_MAXFLAVOR) authtab[flavor] = NULL; spin_unlock(&authtab_lock); rcu_assign_pointer(authtab[flavor], NULL); } EXPORT_SYMBOL_GPL(svc_auth_unregister); Loading Loading
net/sunrpc/svcauth.c +34 −18 Original line number Diff line number Diff line Loading @@ -27,12 +27,32 @@ extern struct auth_ops svcauth_null; extern struct auth_ops svcauth_unix; static DEFINE_SPINLOCK(authtab_lock); static struct auth_ops *authtab[RPC_AUTH_MAXFLAVOR] = { [0] = &svcauth_null, [1] = &svcauth_unix, static struct auth_ops __rcu *authtab[RPC_AUTH_MAXFLAVOR] = { [RPC_AUTH_NULL] = (struct auth_ops __force __rcu *)&svcauth_null, [RPC_AUTH_UNIX] = (struct auth_ops __force __rcu *)&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 svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) { Loading @@ -45,14 +65,11 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) dprintk("svc: svc_authenticate (%d)\n", flavor); spin_lock(&authtab_lock); if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor]) || !try_module_get(aops->owner)) { spin_unlock(&authtab_lock); aops = svc_get_auth_ops(flavor); if (aops == NULL) { *authp = rpc_autherr_badcred; return SVC_DENIED; } spin_unlock(&authtab_lock); rqstp->rq_auth_slack = 0; init_svc_cred(&rqstp->rq_cred); Loading Loading @@ -82,7 +99,7 @@ int svc_authorise(struct svc_rqst *rqstp) if (aops) { rv = aops->release(rqstp); module_put(aops->owner); svc_put_auth_ops(aops); } return rv; } Loading @@ -90,13 +107,14 @@ int svc_authorise(struct svc_rqst *rqstp) int svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops) { struct auth_ops *old; int rv = -EINVAL; spin_lock(&authtab_lock); if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] == NULL) { authtab[flavor] = aops; if (flavor < RPC_AUTH_MAXFLAVOR) { old = cmpxchg((struct auth_ops ** __force)&authtab[flavor], NULL, aops); if (old == NULL || old == aops) rv = 0; } spin_unlock(&authtab_lock); return rv; } EXPORT_SYMBOL_GPL(svc_auth_register); Loading @@ -104,10 +122,8 @@ EXPORT_SYMBOL_GPL(svc_auth_register); void svc_auth_unregister(rpc_authflavor_t flavor) { spin_lock(&authtab_lock); if (flavor < RPC_AUTH_MAXFLAVOR) authtab[flavor] = NULL; spin_unlock(&authtab_lock); rcu_assign_pointer(authtab[flavor], NULL); } EXPORT_SYMBOL_GPL(svc_auth_unregister); Loading