diff options
author | Trond Myklebust <trondmy@gmail.com> | 2018-10-01 10:41:43 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2018-10-03 11:32:59 -0400 |
commit | 30382d6ce593f863292cd7c026a79077c4e7280f (patch) | |
tree | 27c3df5c521a0e393232006c7b1d7288f02a3431 | |
parent | 7d20b6a2728fe3ea9fa8f4fc49cd438fcc781dd1 (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.c | 52 |
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 @@ | |||
27 | extern struct auth_ops svcauth_null; | 27 | extern struct auth_ops svcauth_null; |
28 | extern struct auth_ops svcauth_unix; | 28 | extern struct auth_ops svcauth_unix; |
29 | 29 | ||
30 | static DEFINE_SPINLOCK(authtab_lock); | 30 | static struct auth_ops __rcu *authtab[RPC_AUTH_MAXFLAVOR] = { |
31 | static 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 | ||
35 | static struct auth_ops * | ||
36 | svc_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 | |||
50 | static void | ||
51 | svc_put_auth_ops(struct auth_ops *aops) | ||
52 | { | ||
53 | module_put(aops->owner); | ||
54 | } | ||
55 | |||
36 | int | 56 | int |
37 | svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) | 57 | svc_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) | |||
90 | int | 107 | int |
91 | svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops) | 108 | svc_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 | } |
102 | EXPORT_SYMBOL_GPL(svc_auth_register); | 120 | EXPORT_SYMBOL_GPL(svc_auth_register); |
@@ -104,10 +122,8 @@ EXPORT_SYMBOL_GPL(svc_auth_register); | |||
104 | void | 122 | void |
105 | svc_auth_unregister(rpc_authflavor_t flavor) | 123 | svc_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 | } |
112 | EXPORT_SYMBOL_GPL(svc_auth_unregister); | 128 | EXPORT_SYMBOL_GPL(svc_auth_unregister); |
113 | 129 | ||