aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2018-10-01 10:41:43 -0400
committerJ. Bruce Fields <bfields@redhat.com>2018-10-03 11:32:59 -0400
commit30382d6ce593f863292cd7c026a79077c4e7280f (patch)
tree27c3df5c521a0e393232006c7b1d7288f02a3431
parent7d20b6a2728fe3ea9fa8f4fc49cd438fcc781dd1 (diff)
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>
-rw-r--r--net/sunrpc/svcauth.c52
1 files changed, 34 insertions, 18 deletions
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index bb8db3cb8032..f83443856cd1 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -27,12 +27,32 @@
27extern struct auth_ops svcauth_null; 27extern struct auth_ops svcauth_null;
28extern struct auth_ops svcauth_unix; 28extern struct auth_ops svcauth_unix;
29 29
30static DEFINE_SPINLOCK(authtab_lock); 30static struct auth_ops __rcu *authtab[RPC_AUTH_MAXFLAVOR] = {
31static struct auth_ops *authtab[RPC_AUTH_MAXFLAVOR] = { 31 [RPC_AUTH_NULL] = (struct auth_ops __force __rcu *)&svcauth_null,
32 [0] = &svcauth_null, 32 [RPC_AUTH_UNIX] = (struct auth_ops __force __rcu *)&svcauth_unix,
33 [1] = &svcauth_unix,
34}; 33};
35 34
35static struct auth_ops *
36svc_get_auth_ops(rpc_authflavor_t flavor)
37{
38 struct auth_ops *aops;
39
40 if (flavor >= RPC_AUTH_MAXFLAVOR)
41 return NULL;
42 rcu_read_lock();
43 aops = rcu_dereference(authtab[flavor]);
44 if (aops != NULL && !try_module_get(aops->owner))
45 aops = NULL;
46 rcu_read_unlock();
47 return aops;
48}
49
50static void
51svc_put_auth_ops(struct auth_ops *aops)
52{
53 module_put(aops->owner);
54}
55
36int 56int
37svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) 57svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
38{ 58{
@@ -45,14 +65,11 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
45 65
46 dprintk("svc: svc_authenticate (%d)\n", flavor); 66 dprintk("svc: svc_authenticate (%d)\n", flavor);
47 67
48 spin_lock(&authtab_lock); 68 aops = svc_get_auth_ops(flavor);
49 if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor]) || 69 if (aops == NULL) {
50 !try_module_get(aops->owner)) {
51 spin_unlock(&authtab_lock);
52 *authp = rpc_autherr_badcred; 70 *authp = rpc_autherr_badcred;
53 return SVC_DENIED; 71 return SVC_DENIED;
54 } 72 }
55 spin_unlock(&authtab_lock);
56 73
57 rqstp->rq_auth_slack = 0; 74 rqstp->rq_auth_slack = 0;
58 init_svc_cred(&rqstp->rq_cred); 75 init_svc_cred(&rqstp->rq_cred);
@@ -82,7 +99,7 @@ int svc_authorise(struct svc_rqst *rqstp)
82 99
83 if (aops) { 100 if (aops) {
84 rv = aops->release(rqstp); 101 rv = aops->release(rqstp);
85 module_put(aops->owner); 102 svc_put_auth_ops(aops);
86 } 103 }
87 return rv; 104 return rv;
88} 105}
@@ -90,13 +107,14 @@ int svc_authorise(struct svc_rqst *rqstp)
90int 107int
91svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops) 108svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops)
92{ 109{
110 struct auth_ops *old;
93 int rv = -EINVAL; 111 int rv = -EINVAL;
94 spin_lock(&authtab_lock); 112
95 if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] == NULL) { 113 if (flavor < RPC_AUTH_MAXFLAVOR) {
96 authtab[flavor] = aops; 114 old = cmpxchg((struct auth_ops ** __force)&authtab[flavor], NULL, aops);
97 rv = 0; 115 if (old == NULL || old == aops)
116 rv = 0;
98 } 117 }
99 spin_unlock(&authtab_lock);
100 return rv; 118 return rv;
101} 119}
102EXPORT_SYMBOL_GPL(svc_auth_register); 120EXPORT_SYMBOL_GPL(svc_auth_register);
@@ -104,10 +122,8 @@ EXPORT_SYMBOL_GPL(svc_auth_register);
104void 122void
105svc_auth_unregister(rpc_authflavor_t flavor) 123svc_auth_unregister(rpc_authflavor_t flavor)
106{ 124{
107 spin_lock(&authtab_lock);
108 if (flavor < RPC_AUTH_MAXFLAVOR) 125 if (flavor < RPC_AUTH_MAXFLAVOR)
109 authtab[flavor] = NULL; 126 rcu_assign_pointer(authtab[flavor], NULL);
110 spin_unlock(&authtab_lock);
111} 127}
112EXPORT_SYMBOL_GPL(svc_auth_unregister); 128EXPORT_SYMBOL_GPL(svc_auth_unregister);
113 129