diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2012-11-14 10:21:31 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-11-15 07:40:45 -0500 |
commit | 0a7ec37727dcc3293cd4c9958b25c43f3a797d47 (patch) | |
tree | 396517a26f3363dd9bab053f82ae556d77a8cc00 /fs | |
parent | 382a62e76cbf91fb364a4cd8732761e4ecf62153 (diff) |
nfsd: make unconf_id_hashtbl allocated per net
This hash holds nfs4_clients info, which are network namespace aware.
So let's make it allocated per network namespace.
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')
-rw-r--r-- | fs/nfsd/netns.h | 1 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 25 |
2 files changed, 16 insertions, 10 deletions
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index afd91163846..1ff781f9c3d 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h | |||
@@ -55,6 +55,7 @@ struct nfsd_net { | |||
55 | int reclaim_str_hashtbl_size; | 55 | int reclaim_str_hashtbl_size; |
56 | struct list_head *conf_id_hashtbl; | 56 | struct list_head *conf_id_hashtbl; |
57 | struct rb_root conf_name_tree; | 57 | struct rb_root conf_name_tree; |
58 | struct list_head *unconf_id_hashtbl; | ||
58 | }; | 59 | }; |
59 | 60 | ||
60 | extern int nfsd_net_id; | 61 | extern int nfsd_net_id; |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index d40e57b9051..f33bbfbdc24 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -415,7 +415,6 @@ static unsigned int clientstr_hashval(const char *name) | |||
415 | * | 415 | * |
416 | * All of the above fields are protected by the client_mutex. | 416 | * All of the above fields are protected by the client_mutex. |
417 | */ | 417 | */ |
418 | static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; | ||
419 | static struct rb_root unconf_name_tree; | 418 | static struct rb_root unconf_name_tree; |
420 | static struct list_head client_lru; | 419 | static struct list_head client_lru; |
421 | static struct list_head close_lru; | 420 | static struct list_head close_lru; |
@@ -1369,11 +1368,12 @@ static void | |||
1369 | add_to_unconfirmed(struct nfs4_client *clp) | 1368 | add_to_unconfirmed(struct nfs4_client *clp) |
1370 | { | 1369 | { |
1371 | unsigned int idhashval; | 1370 | unsigned int idhashval; |
1371 | struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); | ||
1372 | 1372 | ||
1373 | clear_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags); | 1373 | clear_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags); |
1374 | add_clp_to_name_tree(clp, &unconf_name_tree); | 1374 | add_clp_to_name_tree(clp, &unconf_name_tree); |
1375 | idhashval = clientid_hashval(clp->cl_clientid.cl_id); | 1375 | idhashval = clientid_hashval(clp->cl_clientid.cl_id); |
1376 | list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]); | 1376 | list_add(&clp->cl_idhash, &nn->unconf_id_hashtbl[idhashval]); |
1377 | renew_client(clp); | 1377 | renew_client(clp); |
1378 | } | 1378 | } |
1379 | 1379 | ||
@@ -1409,12 +1409,12 @@ find_confirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn) | |||
1409 | } | 1409 | } |
1410 | 1410 | ||
1411 | static struct nfs4_client * | 1411 | static struct nfs4_client * |
1412 | find_unconfirmed_client(clientid_t *clid, bool sessions) | 1412 | find_unconfirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn) |
1413 | { | 1413 | { |
1414 | struct nfs4_client *clp; | 1414 | struct nfs4_client *clp; |
1415 | unsigned int idhashval = clientid_hashval(clid->cl_id); | 1415 | unsigned int idhashval = clientid_hashval(clid->cl_id); |
1416 | 1416 | ||
1417 | list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) { | 1417 | list_for_each_entry(clp, &nn->unconf_id_hashtbl[idhashval], cl_idhash) { |
1418 | if (same_clid(&clp->cl_clientid, clid)) { | 1418 | if (same_clid(&clp->cl_clientid, clid)) { |
1419 | if ((bool)clp->cl_minorversion != sessions) | 1419 | if ((bool)clp->cl_minorversion != sessions) |
1420 | return NULL; | 1420 | return NULL; |
@@ -1799,7 +1799,7 @@ nfsd4_create_session(struct svc_rqst *rqstp, | |||
1799 | goto out_free_session; | 1799 | goto out_free_session; |
1800 | 1800 | ||
1801 | nfs4_lock_state(); | 1801 | nfs4_lock_state(); |
1802 | unconf = find_unconfirmed_client(&cr_ses->clientid, true); | 1802 | unconf = find_unconfirmed_client(&cr_ses->clientid, true, nn); |
1803 | conf = find_confirmed_client(&cr_ses->clientid, true, nn); | 1803 | conf = find_confirmed_client(&cr_ses->clientid, true, nn); |
1804 | 1804 | ||
1805 | if (conf) { | 1805 | if (conf) { |
@@ -2143,7 +2143,7 @@ nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta | |||
2143 | struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); | 2143 | struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); |
2144 | 2144 | ||
2145 | nfs4_lock_state(); | 2145 | nfs4_lock_state(); |
2146 | unconf = find_unconfirmed_client(&dc->clientid, true); | 2146 | unconf = find_unconfirmed_client(&dc->clientid, true, nn); |
2147 | conf = find_confirmed_client(&dc->clientid, true, nn); | 2147 | conf = find_confirmed_client(&dc->clientid, true, nn); |
2148 | 2148 | ||
2149 | if (conf) { | 2149 | if (conf) { |
@@ -2280,7 +2280,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | |||
2280 | nfs4_lock_state(); | 2280 | nfs4_lock_state(); |
2281 | 2281 | ||
2282 | conf = find_confirmed_client(clid, false, nn); | 2282 | conf = find_confirmed_client(clid, false, nn); |
2283 | unconf = find_unconfirmed_client(clid, false); | 2283 | unconf = find_unconfirmed_client(clid, false, nn); |
2284 | /* | 2284 | /* |
2285 | * We try hard to give out unique clientid's, so if we get an | 2285 | * We try hard to give out unique clientid's, so if we get an |
2286 | * attempt to confirm the same clientid with a different cred, | 2286 | * attempt to confirm the same clientid with a different cred, |
@@ -4720,9 +4720,6 @@ nfs4_state_init(void) | |||
4720 | { | 4720 | { |
4721 | int i; | 4721 | int i; |
4722 | 4722 | ||
4723 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { | ||
4724 | INIT_LIST_HEAD(&unconf_id_hashtbl[i]); | ||
4725 | } | ||
4726 | unconf_name_tree = RB_ROOT; | 4723 | unconf_name_tree = RB_ROOT; |
4727 | for (i = 0; i < SESSION_HASH_SIZE; i++) | 4724 | for (i = 0; i < SESSION_HASH_SIZE; i++) |
4728 | INIT_LIST_HEAD(&sessionid_hashtbl[i]); | 4725 | INIT_LIST_HEAD(&sessionid_hashtbl[i]); |
@@ -4769,14 +4766,21 @@ static int nfs4_state_start_net(struct net *net) | |||
4769 | CLIENT_HASH_SIZE, GFP_KERNEL); | 4766 | CLIENT_HASH_SIZE, GFP_KERNEL); |
4770 | if (!nn->conf_id_hashtbl) | 4767 | if (!nn->conf_id_hashtbl) |
4771 | goto err; | 4768 | goto err; |
4769 | nn->unconf_id_hashtbl = kmalloc(sizeof(struct list_head) * | ||
4770 | CLIENT_HASH_SIZE, GFP_KERNEL); | ||
4771 | if (!nn->unconf_id_hashtbl) | ||
4772 | goto err_unconf_id; | ||
4772 | 4773 | ||
4773 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { | 4774 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { |
4774 | INIT_LIST_HEAD(&nn->conf_id_hashtbl[i]); | 4775 | INIT_LIST_HEAD(&nn->conf_id_hashtbl[i]); |
4776 | INIT_LIST_HEAD(&nn->unconf_id_hashtbl[i]); | ||
4775 | } | 4777 | } |
4776 | nn->conf_name_tree = RB_ROOT; | 4778 | nn->conf_name_tree = RB_ROOT; |
4777 | 4779 | ||
4778 | return 0; | 4780 | return 0; |
4779 | 4781 | ||
4782 | err_unconf_id: | ||
4783 | kfree(nn->conf_id_hashtbl); | ||
4780 | err: | 4784 | err: |
4781 | return -ENOMEM; | 4785 | return -ENOMEM; |
4782 | } | 4786 | } |
@@ -4794,6 +4798,7 @@ __nfs4_state_shutdown_net(struct net *net) | |||
4794 | destroy_client(clp); | 4798 | destroy_client(clp); |
4795 | } | 4799 | } |
4796 | } | 4800 | } |
4801 | kfree(nn->unconf_id_hashtbl); | ||
4797 | kfree(nn->conf_id_hashtbl); | 4802 | kfree(nn->conf_id_hashtbl); |
4798 | } | 4803 | } |
4799 | 4804 | ||