@@ -1923,7 +1923,7 @@ add_to_unconfirmed(struct nfs4_client *clp)
19231923 add_clp_to_name_tree (clp , & nn -> unconf_name_tree );
19241924 idhashval = clientid_hashval (clp -> cl_clientid .cl_id );
19251925 list_add (& clp -> cl_idhash , & nn -> unconf_id_hashtbl [idhashval ]);
1926- renew_client (clp );
1926+ renew_client_locked (clp );
19271927}
19281928
19291929static void
@@ -1937,7 +1937,7 @@ move_to_confirmed(struct nfs4_client *clp)
19371937 rb_erase (& clp -> cl_namenode , & nn -> unconf_name_tree );
19381938 add_clp_to_name_tree (clp , & nn -> conf_name_tree );
19391939 set_bit (NFSD4_CLIENT_CONFIRMED , & clp -> cl_flags );
1940- renew_client (clp );
1940+ renew_client_locked (clp );
19411941}
19421942
19431943static struct nfs4_client *
@@ -1950,7 +1950,7 @@ find_client_in_id_table(struct list_head *tbl, clientid_t *clid, bool sessions)
19501950 if (same_clid (& clp -> cl_clientid , clid )) {
19511951 if ((bool )clp -> cl_minorversion != sessions )
19521952 return NULL ;
1953- renew_client (clp );
1953+ renew_client_locked (clp );
19541954 return clp ;
19551955 }
19561956 }
@@ -2152,7 +2152,8 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
21522152 struct nfsd4_compound_state * cstate ,
21532153 struct nfsd4_exchange_id * exid )
21542154{
2155- struct nfs4_client * unconf , * conf , * new ;
2155+ struct nfs4_client * conf , * new ;
2156+ struct nfs4_client * unconf = NULL ;
21562157 __be32 status ;
21572158 char addr_str [INET6_ADDRSTRLEN ];
21582159 nfs4_verifier verf = exid -> verifier ;
@@ -2187,6 +2188,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
21872188
21882189 /* Cases below refer to rfc 5661 section 18.35.4: */
21892190 nfs4_lock_state ();
2191+ spin_lock (& nn -> client_lock );
21902192 conf = find_confirmed_client_by_name (& exid -> clname , nn );
21912193 if (conf ) {
21922194 bool creds_match = same_creds (& conf -> cl_cred , & rqstp -> rq_cred );
@@ -2218,14 +2220,14 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
22182220 status = nfserr_clid_inuse ;
22192221 goto out ;
22202222 }
2221- expire_client (conf );
22222223 goto out_new ;
22232224 }
22242225 if (verfs_match ) { /* case 2 */
22252226 conf -> cl_exchange_flags |= EXCHGID4_FLAG_CONFIRMED_R ;
22262227 goto out_copy ;
22272228 }
22282229 /* case 5, client reboot */
2230+ conf = NULL ;
22292231 goto out_new ;
22302232 }
22312233
@@ -2236,17 +2238,18 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
22362238
22372239 unconf = find_unconfirmed_client_by_name (& exid -> clname , nn );
22382240 if (unconf ) /* case 4, possible retry or client restart */
2239- expire_client (unconf );
2241+ unhash_client_locked (unconf );
22402242
22412243 /* case 1 (normal case) */
22422244out_new :
2245+ if (conf )
2246+ unhash_client_locked (conf );
22432247 new -> cl_minorversion = cstate -> minorversion ;
22442248 new -> cl_mach_cred = (exid -> spa_how == SP4_MACH_CRED );
22452249
22462250 gen_clid (new , nn );
22472251 add_to_unconfirmed (new );
2248- conf = new ;
2249- new = NULL ;
2252+ swap (new , conf );
22502253out_copy :
22512254 exid -> clientid .cl_boot = conf -> cl_clientid .cl_boot ;
22522255 exid -> clientid .cl_id = conf -> cl_clientid .cl_id ;
@@ -2259,9 +2262,12 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
22592262 status = nfs_ok ;
22602263
22612264out :
2265+ spin_unlock (& nn -> client_lock );
22622266 nfs4_unlock_state ();
22632267 if (new )
2264- free_client (new );
2268+ expire_client (new );
2269+ if (unconf )
2270+ expire_client (unconf );
22652271 return status ;
22662272}
22672273
@@ -2900,7 +2906,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
29002906{
29012907 struct xdr_netobj clname = setclid -> se_name ;
29022908 nfs4_verifier clverifier = setclid -> se_verf ;
2903- struct nfs4_client * conf , * unconf , * new ;
2909+ struct nfs4_client * conf , * new ;
2910+ struct nfs4_client * unconf = NULL ;
29042911 __be32 status ;
29052912 struct nfsd_net * nn = net_generic (SVC_NET (rqstp ), nfsd_net_id );
29062913
@@ -2909,6 +2916,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
29092916 return nfserr_jukebox ;
29102917 /* Cases below refer to rfc 3530 section 14.2.33: */
29112918 nfs4_lock_state ();
2919+ spin_lock (& nn -> client_lock );
29122920 conf = find_confirmed_client_by_name (& clname , nn );
29132921 if (conf ) {
29142922 /* case 0: */
@@ -2926,7 +2934,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
29262934 }
29272935 unconf = find_unconfirmed_client_by_name (& clname , nn );
29282936 if (unconf )
2929- expire_client (unconf );
2937+ unhash_client_locked (unconf );
29302938 if (conf && same_verf (& conf -> cl_verifier , & clverifier ))
29312939 /* case 1: probable callback update */
29322940 copy_clid (new , conf );
@@ -2941,9 +2949,12 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
29412949 new = NULL ;
29422950 status = nfs_ok ;
29432951out :
2952+ spin_unlock (& nn -> client_lock );
29442953 nfs4_unlock_state ();
29452954 if (new )
29462955 free_client (new );
2956+ if (unconf )
2957+ expire_client (unconf );
29472958 return status ;
29482959}
29492960
0 commit comments