aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-11-14 10:21:31 -0500
committerJ. Bruce Fields <bfields@redhat.com>2012-11-15 07:40:45 -0500
commit0a7ec37727dcc3293cd4c9958b25c43f3a797d47 (patch)
tree396517a26f3363dd9bab053f82ae556d77a8cc00 /fs
parent382a62e76cbf91fb364a4cd8732761e4ecf62153 (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.h1
-rw-r--r--fs/nfsd/nfs4state.c25
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
60extern int nfsd_net_id; 61extern 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 */
418static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
419static struct rb_root unconf_name_tree; 418static struct rb_root unconf_name_tree;
420static struct list_head client_lru; 419static struct list_head client_lru;
421static struct list_head close_lru; 420static struct list_head close_lru;
@@ -1369,11 +1368,12 @@ static void
1369add_to_unconfirmed(struct nfs4_client *clp) 1368add_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
1411static struct nfs4_client * 1411static struct nfs4_client *
1412find_unconfirmed_client(clientid_t *clid, bool sessions) 1412find_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
4782err_unconf_id:
4783 kfree(nn->conf_id_hashtbl);
4780err: 4784err:
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