aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfs4state.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 835d6cef9ae9..2313dbf086bd 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -250,6 +250,9 @@ unhash_delegation(struct nfs4_delegation *dp)
250 * SETCLIENTID state 250 * SETCLIENTID state
251 */ 251 */
252 252
253/* client_lock protects the session hash table */
254static DEFINE_SPINLOCK(client_lock);
255
253/* Hash tables for nfs4_clientid state */ 256/* Hash tables for nfs4_clientid state */
254#define CLIENT_HASH_BITS 4 257#define CLIENT_HASH_BITS 4
255#define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS) 258#define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS)
@@ -368,7 +371,6 @@ static void release_openowner(struct nfs4_stateowner *sop)
368 nfs4_put_stateowner(sop); 371 nfs4_put_stateowner(sop);
369} 372}
370 373
371static DEFINE_SPINLOCK(sessionid_lock);
372#define SESSION_HASH_SIZE 512 374#define SESSION_HASH_SIZE 512
373static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE]; 375static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE];
374 376
@@ -566,10 +568,10 @@ alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp,
566 568
567 new->se_flags = cses->flags; 569 new->se_flags = cses->flags;
568 kref_init(&new->se_ref); 570 kref_init(&new->se_ref);
569 spin_lock(&sessionid_lock); 571 spin_lock(&client_lock);
570 list_add(&new->se_hash, &sessionid_hashtbl[idx]); 572 list_add(&new->se_hash, &sessionid_hashtbl[idx]);
571 list_add(&new->se_perclnt, &clp->cl_sessions); 573 list_add(&new->se_perclnt, &clp->cl_sessions);
572 spin_unlock(&sessionid_lock); 574 spin_unlock(&client_lock);
573 575
574 status = nfs_ok; 576 status = nfs_ok;
575out: 577out:
@@ -580,7 +582,7 @@ out_free:
580 goto out; 582 goto out;
581} 583}
582 584
583/* caller must hold sessionid_lock */ 585/* caller must hold client_lock */
584static struct nfsd4_session * 586static struct nfsd4_session *
585find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid) 587find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid)
586{ 588{
@@ -603,7 +605,7 @@ find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid)
603 return NULL; 605 return NULL;
604} 606}
605 607
606/* caller must hold sessionid_lock */ 608/* caller must hold client_lock */
607static void 609static void
608unhash_session(struct nfsd4_session *ses) 610unhash_session(struct nfsd4_session *ses)
609{ 611{
@@ -614,9 +616,9 @@ unhash_session(struct nfsd4_session *ses)
614static void 616static void
615release_session(struct nfsd4_session *ses) 617release_session(struct nfsd4_session *ses)
616{ 618{
617 spin_lock(&sessionid_lock); 619 spin_lock(&client_lock);
618 unhash_session(ses); 620 unhash_session(ses);
619 spin_unlock(&sessionid_lock); 621 spin_unlock(&client_lock);
620 nfsd4_put_session(ses); 622 nfsd4_put_session(ses);
621} 623}
622 624
@@ -1379,15 +1381,15 @@ nfsd4_destroy_session(struct svc_rqst *r,
1379 return nfserr_not_only_op; 1381 return nfserr_not_only_op;
1380 } 1382 }
1381 dump_sessionid(__func__, &sessionid->sessionid); 1383 dump_sessionid(__func__, &sessionid->sessionid);
1382 spin_lock(&sessionid_lock); 1384 spin_lock(&client_lock);
1383 ses = find_in_sessionid_hashtbl(&sessionid->sessionid); 1385 ses = find_in_sessionid_hashtbl(&sessionid->sessionid);
1384 if (!ses) { 1386 if (!ses) {
1385 spin_unlock(&sessionid_lock); 1387 spin_unlock(&client_lock);
1386 goto out; 1388 goto out;
1387 } 1389 }
1388 1390
1389 unhash_session(ses); 1391 unhash_session(ses);
1390 spin_unlock(&sessionid_lock); 1392 spin_unlock(&client_lock);
1391 1393
1392 /* wait for callbacks */ 1394 /* wait for callbacks */
1393 nfsd4_set_callback_client(ses->se_client, NULL); 1395 nfsd4_set_callback_client(ses->se_client, NULL);
@@ -1411,7 +1413,7 @@ nfsd4_sequence(struct svc_rqst *rqstp,
1411 if (resp->opcnt != 1) 1413 if (resp->opcnt != 1)
1412 return nfserr_sequence_pos; 1414 return nfserr_sequence_pos;
1413 1415
1414 spin_lock(&sessionid_lock); 1416 spin_lock(&client_lock);
1415 status = nfserr_badsession; 1417 status = nfserr_badsession;
1416 session = find_in_sessionid_hashtbl(&seq->sessionid); 1418 session = find_in_sessionid_hashtbl(&seq->sessionid);
1417 if (!session) 1419 if (!session)
@@ -1454,7 +1456,7 @@ out:
1454 /* Hold a session reference until done processing the compound. */ 1456 /* Hold a session reference until done processing the compound. */
1455 if (cstate->session) 1457 if (cstate->session)
1456 nfsd4_get_session(cstate->session); 1458 nfsd4_get_session(cstate->session);
1457 spin_unlock(&sessionid_lock); 1459 spin_unlock(&client_lock);
1458 /* Renew the clientid on success and on replay */ 1460 /* Renew the clientid on success and on replay */
1459 if (cstate->session) { 1461 if (cstate->session) {
1460 nfs4_lock_state(); 1462 nfs4_lock_state();