27
27
extern struct auth_ops svcauth_null ;
28
28
extern struct auth_ops svcauth_unix ;
29
29
30
- static DEFINE_SPINLOCK (authtab_lock );
31
- static struct auth_ops * authtab [RPC_AUTH_MAXFLAVOR ] = {
32
- [0 ] = & svcauth_null ,
33
- [1 ] = & svcauth_unix ,
30
+ static struct auth_ops __rcu * authtab [RPC_AUTH_MAXFLAVOR ] = {
31
+ [RPC_AUTH_NULL ] = (struct auth_ops __force __rcu * )& svcauth_null ,
32
+ [RPC_AUTH_UNIX ] = (struct auth_ops __force __rcu * )& 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
56
int
37
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
66
dprintk ("svc: svc_authenticate (%d)\n" , flavor );
47
67
48
- spin_lock (& authtab_lock );
49
- if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab [flavor ]) ||
50
- !try_module_get (aops -> owner )) {
51
- spin_unlock (& authtab_lock );
68
+ aops = svc_get_auth_ops (flavor );
69
+ if (aops == NULL ) {
52
70
* authp = rpc_autherr_badcred ;
53
71
return SVC_DENIED ;
54
72
}
55
- spin_unlock (& authtab_lock );
56
73
57
74
rqstp -> rq_auth_slack = 0 ;
58
75
init_svc_cred (& rqstp -> rq_cred );
@@ -82,32 +99,31 @@ int svc_authorise(struct svc_rqst *rqstp)
82
99
83
100
if (aops ) {
84
101
rv = aops -> release (rqstp );
85
- module_put (aops -> owner );
102
+ svc_put_auth_ops (aops );
86
103
}
87
104
return rv ;
88
105
}
89
106
90
107
int
91
108
svc_auth_register (rpc_authflavor_t flavor , struct auth_ops * aops )
92
109
{
110
+ struct auth_ops * old ;
93
111
int rv = - EINVAL ;
94
- spin_lock (& authtab_lock );
95
- if (flavor < RPC_AUTH_MAXFLAVOR && authtab [flavor ] == NULL ) {
96
- authtab [flavor ] = aops ;
97
- rv = 0 ;
112
+
113
+ if (flavor < RPC_AUTH_MAXFLAVOR ) {
114
+ old = cmpxchg ((struct auth_ops * * __force )& authtab [flavor ], NULL , aops );
115
+ if (old == NULL || old == aops )
116
+ rv = 0 ;
98
117
}
99
- spin_unlock (& authtab_lock );
100
118
return rv ;
101
119
}
102
120
EXPORT_SYMBOL_GPL (svc_auth_register );
103
121
104
122
void
105
123
svc_auth_unregister (rpc_authflavor_t flavor )
106
124
{
107
- spin_lock (& authtab_lock );
108
125
if (flavor < RPC_AUTH_MAXFLAVOR )
109
- authtab [flavor ] = NULL ;
110
- spin_unlock (& authtab_lock );
126
+ rcu_assign_pointer (authtab [flavor ], NULL );
111
127
}
112
128
EXPORT_SYMBOL_GPL (svc_auth_unregister );
113
129
0 commit comments