2727extern struct auth_ops svcauth_null ;
2828extern struct auth_ops svcauth_unix ;
2929
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 ,
3433};
3534
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+
3656int
3757svc_authenticate (struct svc_rqst * rqstp , __be32 * authp )
3858{
@@ -45,14 +65,11 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
4565
4666 dprintk ("svc: svc_authenticate (%d)\n" , flavor );
4767
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 ) {
5270 * authp = rpc_autherr_badcred ;
5371 return SVC_DENIED ;
5472 }
55- spin_unlock (& authtab_lock );
5673
5774 rqstp -> rq_auth_slack = 0 ;
5875 init_svc_cred (& rqstp -> rq_cred );
@@ -82,32 +99,31 @@ int svc_authorise(struct svc_rqst *rqstp)
8299
83100 if (aops ) {
84101 rv = aops -> release (rqstp );
85- module_put (aops -> owner );
102+ svc_put_auth_ops (aops );
86103 }
87104 return rv ;
88105}
89106
90107int
91108svc_auth_register (rpc_authflavor_t flavor , struct auth_ops * aops )
92109{
110+ struct auth_ops * old ;
93111 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 ;
98117 }
99- spin_unlock (& authtab_lock );
100118 return rv ;
101119}
102120EXPORT_SYMBOL_GPL (svc_auth_register );
103121
104122void
105123svc_auth_unregister (rpc_authflavor_t flavor )
106124{
107- spin_lock (& authtab_lock );
108125 if (flavor < RPC_AUTH_MAXFLAVOR )
109- authtab [flavor ] = NULL ;
110- spin_unlock (& authtab_lock );
126+ rcu_assign_pointer (authtab [flavor ], NULL );
111127}
112128EXPORT_SYMBOL_GPL (svc_auth_unregister );
113129
0 commit comments