diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2012-11-14 10:21:51 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-11-15 07:40:47 -0500 |
commit | 1872de0e8171904612ee85de218fa045bc473cad (patch) | |
tree | 807822b296dab38e1fad9ffacefe40b2757c3f1e /fs/nfsd/nfs4state.c | |
parent | 20e9e2bc98b907efe82621797c561f6169d63d96 (diff) |
nfsd: make sessionid_hashtbl allocated per net
This hash holds established sessions state and closely associated with
nfs4_clients info, which are network namespace aware. So let's make it
allocated per network namespace too.
Note: this hash can be allocated in per-net operations. But it looks
better to allocate it on nfsd state start and thus don't waste resources
if server is not running.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1e76d55a3e9a..248f217a00bc 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -632,9 +632,6 @@ static void release_openowner(struct nfs4_openowner *oo) | |||
632 | nfs4_free_openowner(oo); | 632 | nfs4_free_openowner(oo); |
633 | } | 633 | } |
634 | 634 | ||
635 | #define SESSION_HASH_SIZE 512 | ||
636 | static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE]; | ||
637 | |||
638 | static inline int | 635 | static inline int |
639 | hash_sessionid(struct nfs4_sessionid *sessionid) | 636 | hash_sessionid(struct nfs4_sessionid *sessionid) |
640 | { | 637 | { |
@@ -928,6 +925,7 @@ static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fchan) | |||
928 | static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, struct nfs4_client *clp, struct nfsd4_create_session *cses) | 925 | static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, struct nfs4_client *clp, struct nfsd4_create_session *cses) |
929 | { | 926 | { |
930 | int idx; | 927 | int idx; |
928 | struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); | ||
931 | 929 | ||
932 | new->se_client = clp; | 930 | new->se_client = clp; |
933 | gen_sessionid(new); | 931 | gen_sessionid(new); |
@@ -941,7 +939,7 @@ static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, stru | |||
941 | kref_init(&new->se_ref); | 939 | kref_init(&new->se_ref); |
942 | idx = hash_sessionid(&new->se_sessionid); | 940 | idx = hash_sessionid(&new->se_sessionid); |
943 | spin_lock(&client_lock); | 941 | spin_lock(&client_lock); |
944 | list_add(&new->se_hash, &sessionid_hashtbl[idx]); | 942 | list_add(&new->se_hash, &nn->sessionid_hashtbl[idx]); |
945 | spin_lock(&clp->cl_lock); | 943 | spin_lock(&clp->cl_lock); |
946 | list_add(&new->se_perclnt, &clp->cl_sessions); | 944 | list_add(&new->se_perclnt, &clp->cl_sessions); |
947 | spin_unlock(&clp->cl_lock); | 945 | spin_unlock(&clp->cl_lock); |
@@ -963,15 +961,16 @@ static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, stru | |||
963 | 961 | ||
964 | /* caller must hold client_lock */ | 962 | /* caller must hold client_lock */ |
965 | static struct nfsd4_session * | 963 | static struct nfsd4_session * |
966 | find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid) | 964 | find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid, struct net *net) |
967 | { | 965 | { |
968 | struct nfsd4_session *elem; | 966 | struct nfsd4_session *elem; |
969 | int idx; | 967 | int idx; |
968 | struct nfsd_net *nn = net_generic(net, nfsd_net_id); | ||
970 | 969 | ||
971 | dump_sessionid(__func__, sessionid); | 970 | dump_sessionid(__func__, sessionid); |
972 | idx = hash_sessionid(sessionid); | 971 | idx = hash_sessionid(sessionid); |
973 | /* Search in the appropriate list */ | 972 | /* Search in the appropriate list */ |
974 | list_for_each_entry(elem, &sessionid_hashtbl[idx], se_hash) { | 973 | list_for_each_entry(elem, &nn->sessionid_hashtbl[idx], se_hash) { |
975 | if (!memcmp(elem->se_sessionid.data, sessionid->data, | 974 | if (!memcmp(elem->se_sessionid.data, sessionid->data, |
976 | NFS4_MAX_SESSIONID_LEN)) { | 975 | NFS4_MAX_SESSIONID_LEN)) { |
977 | return elem; | 976 | return elem; |
@@ -1905,7 +1904,7 @@ __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp, | |||
1905 | if (!nfsd4_last_compound_op(rqstp)) | 1904 | if (!nfsd4_last_compound_op(rqstp)) |
1906 | return nfserr_not_only_op; | 1905 | return nfserr_not_only_op; |
1907 | spin_lock(&client_lock); | 1906 | spin_lock(&client_lock); |
1908 | cstate->session = find_in_sessionid_hashtbl(&bcts->sessionid); | 1907 | cstate->session = find_in_sessionid_hashtbl(&bcts->sessionid, SVC_NET(rqstp)); |
1909 | /* Sorta weird: we only need the refcnt'ing because new_conn acquires | 1908 | /* Sorta weird: we only need the refcnt'ing because new_conn acquires |
1910 | * client_lock iself: */ | 1909 | * client_lock iself: */ |
1911 | if (cstate->session) { | 1910 | if (cstate->session) { |
@@ -1954,7 +1953,7 @@ nfsd4_destroy_session(struct svc_rqst *r, | |||
1954 | } | 1953 | } |
1955 | dump_sessionid(__func__, &sessionid->sessionid); | 1954 | dump_sessionid(__func__, &sessionid->sessionid); |
1956 | spin_lock(&client_lock); | 1955 | spin_lock(&client_lock); |
1957 | ses = find_in_sessionid_hashtbl(&sessionid->sessionid); | 1956 | ses = find_in_sessionid_hashtbl(&sessionid->sessionid, SVC_NET(r)); |
1958 | if (!ses) { | 1957 | if (!ses) { |
1959 | spin_unlock(&client_lock); | 1958 | spin_unlock(&client_lock); |
1960 | goto out; | 1959 | goto out; |
@@ -2050,7 +2049,7 @@ nfsd4_sequence(struct svc_rqst *rqstp, | |||
2050 | 2049 | ||
2051 | spin_lock(&client_lock); | 2050 | spin_lock(&client_lock); |
2052 | status = nfserr_badsession; | 2051 | status = nfserr_badsession; |
2053 | session = find_in_sessionid_hashtbl(&seq->sessionid); | 2052 | session = find_in_sessionid_hashtbl(&seq->sessionid, SVC_NET(rqstp)); |
2054 | if (!session) | 2053 | if (!session) |
2055 | goto out; | 2054 | goto out; |
2056 | 2055 | ||
@@ -4719,8 +4718,6 @@ nfs4_state_init(void) | |||
4719 | { | 4718 | { |
4720 | int i; | 4719 | int i; |
4721 | 4720 | ||
4722 | for (i = 0; i < SESSION_HASH_SIZE; i++) | ||
4723 | INIT_LIST_HEAD(&sessionid_hashtbl[i]); | ||
4724 | for (i = 0; i < FILE_HASH_SIZE; i++) { | 4721 | for (i = 0; i < FILE_HASH_SIZE; i++) { |
4725 | INIT_LIST_HEAD(&file_hashtbl[i]); | 4722 | INIT_LIST_HEAD(&file_hashtbl[i]); |
4726 | } | 4723 | } |
@@ -4771,6 +4768,10 @@ static int nfs4_state_start_net(struct net *net) | |||
4771 | LOCKOWNER_INO_HASH_SIZE, GFP_KERNEL); | 4768 | LOCKOWNER_INO_HASH_SIZE, GFP_KERNEL); |
4772 | if (!nn->lockowner_ino_hashtbl) | 4769 | if (!nn->lockowner_ino_hashtbl) |
4773 | goto err_lockowner_ino; | 4770 | goto err_lockowner_ino; |
4771 | nn->sessionid_hashtbl = kmalloc(sizeof(struct list_head) * | ||
4772 | SESSION_HASH_SIZE, GFP_KERNEL); | ||
4773 | if (!nn->sessionid_hashtbl) | ||
4774 | goto err_sessionid; | ||
4774 | 4775 | ||
4775 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { | 4776 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { |
4776 | INIT_LIST_HEAD(&nn->conf_id_hashtbl[i]); | 4777 | INIT_LIST_HEAD(&nn->conf_id_hashtbl[i]); |
@@ -4780,11 +4781,15 @@ static int nfs4_state_start_net(struct net *net) | |||
4780 | INIT_LIST_HEAD(&nn->ownerstr_hashtbl[i]); | 4781 | INIT_LIST_HEAD(&nn->ownerstr_hashtbl[i]); |
4781 | for (i = 0; i < LOCKOWNER_INO_HASH_SIZE; i++) | 4782 | for (i = 0; i < LOCKOWNER_INO_HASH_SIZE; i++) |
4782 | INIT_LIST_HEAD(&nn->lockowner_ino_hashtbl[i]); | 4783 | INIT_LIST_HEAD(&nn->lockowner_ino_hashtbl[i]); |
4784 | for (i = 0; i < SESSION_HASH_SIZE; i++) | ||
4785 | INIT_LIST_HEAD(&nn->sessionid_hashtbl[i]); | ||
4783 | nn->conf_name_tree = RB_ROOT; | 4786 | nn->conf_name_tree = RB_ROOT; |
4784 | nn->unconf_name_tree = RB_ROOT; | 4787 | nn->unconf_name_tree = RB_ROOT; |
4785 | 4788 | ||
4786 | return 0; | 4789 | return 0; |
4787 | 4790 | ||
4791 | err_sessionid: | ||
4792 | kfree(nn->lockowner_ino_hashtbl); | ||
4788 | err_lockowner_ino: | 4793 | err_lockowner_ino: |
4789 | kfree(nn->ownerstr_hashtbl); | 4794 | kfree(nn->ownerstr_hashtbl); |
4790 | err_ownerstr: | 4795 | err_ownerstr: |
@@ -4819,6 +4824,7 @@ __nfs4_state_shutdown_net(struct net *net) | |||
4819 | destroy_client(clp); | 4824 | destroy_client(clp); |
4820 | } | 4825 | } |
4821 | 4826 | ||
4827 | kfree(nn->sessionid_hashtbl); | ||
4822 | kfree(nn->lockowner_ino_hashtbl); | 4828 | kfree(nn->lockowner_ino_hashtbl); |
4823 | kfree(nn->ownerstr_hashtbl); | 4829 | kfree(nn->ownerstr_hashtbl); |
4824 | kfree(nn->unconf_id_hashtbl); | 4830 | kfree(nn->unconf_id_hashtbl); |