diff options
| -rw-r--r-- | fs/nfsd/nfs4state.c | 26 |
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 */ | ||
| 254 | static 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 | ||
| 371 | static DEFINE_SPINLOCK(sessionid_lock); | ||
| 372 | #define SESSION_HASH_SIZE 512 | 374 | #define SESSION_HASH_SIZE 512 |
| 373 | static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE]; | 375 | static 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; |
| 575 | out: | 577 | out: |
| @@ -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 */ |
| 584 | static struct nfsd4_session * | 586 | static struct nfsd4_session * |
| 585 | find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid) | 587 | find_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 */ |
| 607 | static void | 609 | static void |
| 608 | unhash_session(struct nfsd4_session *ses) | 610 | unhash_session(struct nfsd4_session *ses) |
| 609 | { | 611 | { |
| @@ -614,9 +616,9 @@ unhash_session(struct nfsd4_session *ses) | |||
| 614 | static void | 616 | static void |
| 615 | release_session(struct nfsd4_session *ses) | 617 | release_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(); |
