aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-11-14 10:21:16 -0500
committerJ. Bruce Fields <bfields@redhat.com>2012-11-15 07:40:43 -0500
commit52e19c09a183d82d99f10c284bc8b27933b1d1fc (patch)
tree7a4f21eecd888cea675d7ccddddfd03774337af4 /fs
parentc212cecfa21b3d30cd5cc2389754a46973ad9027 (diff)
nfsd: make reclaim_str_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 is used only by legacy tracker. So let's allocate hash in tracker init. 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.h12
-rw-r--r--fs/nfsd/nfs4recover.c100
-rw-r--r--fs/nfsd/nfs4state.c42
-rw-r--r--fs/nfsd/state.h12
4 files changed, 111 insertions, 55 deletions
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index 65c2431ea32f..49e54790d862 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -24,6 +24,11 @@
24#include <net/net_namespace.h> 24#include <net/net_namespace.h>
25#include <net/netns/generic.h> 25#include <net/netns/generic.h>
26 26
27/* Hash tables for nfs4_clientid state */
28#define CLIENT_HASH_BITS 4
29#define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS)
30#define CLIENT_HASH_MASK (CLIENT_HASH_SIZE - 1)
31
27struct cld_net; 32struct cld_net;
28 33
29struct nfsd_net { 34struct nfsd_net {
@@ -38,6 +43,13 @@ struct nfsd_net {
38 struct lock_manager nfsd4_manager; 43 struct lock_manager nfsd4_manager;
39 bool grace_ended; 44 bool grace_ended;
40 time_t boot_time; 45 time_t boot_time;
46
47 /*
48 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
49 * used in reboot/reset lease grace period processing
50 */
51 struct list_head *reclaim_str_hashtbl;
52 int reclaim_str_hashtbl_size;
41}; 53};
42 54
43extern int nfsd_net_id; 55extern int nfsd_net_id;
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 9881bcad264b..376692ab1b3b 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -176,6 +176,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
176 struct dentry *dir, *dentry; 176 struct dentry *dir, *dentry;
177 struct nfs4_client_reclaim *crp; 177 struct nfs4_client_reclaim *crp;
178 int status; 178 int status;
179 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
179 180
180 dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname); 181 dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname);
181 182
@@ -222,7 +223,7 @@ out_unlock:
222 mutex_unlock(&dir->d_inode->i_mutex); 223 mutex_unlock(&dir->d_inode->i_mutex);
223 if (status == 0) { 224 if (status == 0) {
224 if (in_grace) { 225 if (in_grace) {
225 crp = nfs4_client_to_reclaim(dname); 226 crp = nfs4_client_to_reclaim(dname, nn);
226 if (crp) 227 if (crp)
227 crp->cr_clp = clp; 228 crp->cr_clp = clp;
228 } 229 }
@@ -237,7 +238,7 @@ out_unlock:
237 nfs4_reset_creds(original_cred); 238 nfs4_reset_creds(original_cred);
238} 239}
239 240
240typedef int (recdir_func)(struct dentry *, struct dentry *); 241typedef int (recdir_func)(struct dentry *, struct dentry *, struct nfsd_net *);
241 242
242struct name_list { 243struct name_list {
243 char name[HEXDIR_LEN]; 244 char name[HEXDIR_LEN];
@@ -263,7 +264,7 @@ nfsd4_build_namelist(void *arg, const char *name, int namlen,
263} 264}
264 265
265static int 266static int
266nfsd4_list_rec_dir(recdir_func *f) 267nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
267{ 268{
268 const struct cred *original_cred; 269 const struct cred *original_cred;
269 struct dentry *dir = rec_file->f_path.dentry; 270 struct dentry *dir = rec_file->f_path.dentry;
@@ -292,7 +293,7 @@ nfsd4_list_rec_dir(recdir_func *f)
292 status = PTR_ERR(dentry); 293 status = PTR_ERR(dentry);
293 break; 294 break;
294 } 295 }
295 status = f(dir, dentry); 296 status = f(dir, dentry, nn);
296 dput(dentry); 297 dput(dentry);
297 } 298 }
298 list_del(&entry->list); 299 list_del(&entry->list);
@@ -336,6 +337,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
336 struct nfs4_client_reclaim *crp; 337 struct nfs4_client_reclaim *crp;
337 char dname[HEXDIR_LEN]; 338 char dname[HEXDIR_LEN];
338 int status; 339 int status;
340 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
339 341
340 if (!rec_file || !test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags)) 342 if (!rec_file || !test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
341 return; 343 return;
@@ -359,9 +361,9 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
359 vfs_fsync(rec_file, 0); 361 vfs_fsync(rec_file, 0);
360 if (in_grace) { 362 if (in_grace) {
361 /* remove reclaim record */ 363 /* remove reclaim record */
362 crp = nfsd4_find_reclaim_client(dname); 364 crp = nfsd4_find_reclaim_client(dname, nn);
363 if (crp) 365 if (crp)
364 nfs4_remove_reclaim_record(crp); 366 nfs4_remove_reclaim_record(crp, nn);
365 } 367 }
366 } 368 }
367out_drop_write: 369out_drop_write:
@@ -373,11 +375,11 @@ out:
373} 375}
374 376
375static int 377static int
376purge_old(struct dentry *parent, struct dentry *child) 378purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
377{ 379{
378 int status; 380 int status;
379 381
380 if (nfs4_has_reclaimed_state(child->d_name.name)) 382 if (nfs4_has_reclaimed_state(child->d_name.name, nn))
381 return 0; 383 return 0;
382 384
383 status = vfs_rmdir(parent->d_inode, child); 385 status = vfs_rmdir(parent->d_inode, child);
@@ -392,6 +394,7 @@ static void
392nfsd4_recdir_purge_old(struct net *net, time_t boot_time) 394nfsd4_recdir_purge_old(struct net *net, time_t boot_time)
393{ 395{
394 int status; 396 int status;
397 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
395 398
396 in_grace = false; 399 in_grace = false;
397 if (!rec_file) 400 if (!rec_file)
@@ -399,19 +402,19 @@ nfsd4_recdir_purge_old(struct net *net, time_t boot_time)
399 status = mnt_want_write_file(rec_file); 402 status = mnt_want_write_file(rec_file);
400 if (status) 403 if (status)
401 goto out; 404 goto out;
402 status = nfsd4_list_rec_dir(purge_old); 405 status = nfsd4_list_rec_dir(purge_old, nn);
403 if (status == 0) 406 if (status == 0)
404 vfs_fsync(rec_file, 0); 407 vfs_fsync(rec_file, 0);
405 mnt_drop_write_file(rec_file); 408 mnt_drop_write_file(rec_file);
406out: 409out:
407 nfs4_release_reclaim(); 410 nfs4_release_reclaim(nn);
408 if (status) 411 if (status)
409 printk("nfsd4: failed to purge old clients from recovery" 412 printk("nfsd4: failed to purge old clients from recovery"
410 " directory %s\n", rec_file->f_path.dentry->d_name.name); 413 " directory %s\n", rec_file->f_path.dentry->d_name.name);
411} 414}
412 415
413static int 416static int
414load_recdir(struct dentry *parent, struct dentry *child) 417load_recdir(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
415{ 418{
416 if (child->d_name.len != HEXDIR_LEN - 1) { 419 if (child->d_name.len != HEXDIR_LEN - 1) {
417 printk("nfsd4: illegal name %s in recovery directory\n", 420 printk("nfsd4: illegal name %s in recovery directory\n",
@@ -419,18 +422,19 @@ load_recdir(struct dentry *parent, struct dentry *child)
419 /* Keep trying; maybe the others are OK: */ 422 /* Keep trying; maybe the others are OK: */
420 return 0; 423 return 0;
421 } 424 }
422 nfs4_client_to_reclaim(child->d_name.name); 425 nfs4_client_to_reclaim(child->d_name.name, nn);
423 return 0; 426 return 0;
424} 427}
425 428
426static int 429static int
427nfsd4_recdir_load(void) { 430nfsd4_recdir_load(struct net *net) {
428 int status; 431 int status;
432 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
429 433
430 if (!rec_file) 434 if (!rec_file)
431 return 0; 435 return 0;
432 436
433 status = nfsd4_list_rec_dir(load_recdir); 437 status = nfsd4_list_rec_dir(load_recdir, nn);
434 if (status) 438 if (status)
435 printk("nfsd4: failed loading clients from recovery" 439 printk("nfsd4: failed loading clients from recovery"
436 " directory %s\n", rec_file->f_path.dentry->d_name.name); 440 " directory %s\n", rec_file->f_path.dentry->d_name.name);
@@ -474,11 +478,53 @@ nfsd4_init_recdir(void)
474 return status; 478 return status;
475} 479}
476 480
481
482static int
483nfs4_legacy_state_init(struct net *net)
484{
485 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
486 int i;
487
488 nn->reclaim_str_hashtbl = kmalloc(sizeof(struct list_head) *
489 CLIENT_HASH_SIZE, GFP_KERNEL);
490 if (!nn->reclaim_str_hashtbl)
491 return -ENOMEM;
492
493 for (i = 0; i < CLIENT_HASH_SIZE; i++)
494 INIT_LIST_HEAD(&nn->reclaim_str_hashtbl[i]);
495 nn->reclaim_str_hashtbl_size = 0;
496
497 return 0;
498}
499
500static void
501nfs4_legacy_state_shutdown(struct net *net)
502{
503 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
504
505 kfree(nn->reclaim_str_hashtbl);
506}
507
477static int 508static int
478nfsd4_load_reboot_recovery_data(struct net *net) 509nfsd4_load_reboot_recovery_data(struct net *net)
479{ 510{
480 int status; 511 int status;
481 512
513 nfs4_lock_state();
514 status = nfsd4_init_recdir();
515 if (!status)
516 status = nfsd4_recdir_load(net);
517 nfs4_unlock_state();
518 if (status)
519 printk(KERN_ERR "NFSD: Failure reading reboot recovery data\n");
520 return status;
521}
522
523static int
524nfsd4_legacy_tracking_init(struct net *net)
525{
526 int status;
527
482 /* XXX: The legacy code won't work in a container */ 528 /* XXX: The legacy code won't work in a container */
483 if (net != &init_net) { 529 if (net != &init_net) {
484 WARN(1, KERN_ERR "NFSD: attempt to initialize legacy client " 530 WARN(1, KERN_ERR "NFSD: attempt to initialize legacy client "
@@ -486,13 +532,17 @@ nfsd4_load_reboot_recovery_data(struct net *net)
486 return -EINVAL; 532 return -EINVAL;
487 } 533 }
488 534
489 nfs4_lock_state(); 535 status = nfs4_legacy_state_init(net);
490 status = nfsd4_init_recdir();
491 if (!status)
492 status = nfsd4_recdir_load();
493 nfs4_unlock_state();
494 if (status) 536 if (status)
495 printk(KERN_ERR "NFSD: Failure reading reboot recovery data\n"); 537 return status;
538
539 status = nfsd4_load_reboot_recovery_data(net);
540 if (status)
541 goto err;
542 return 0;
543
544err:
545 nfs4_legacy_state_shutdown(net);
496 return status; 546 return status;
497} 547}
498 548
@@ -508,8 +558,11 @@ nfsd4_shutdown_recdir(void)
508static void 558static void
509nfsd4_legacy_tracking_exit(struct net *net) 559nfsd4_legacy_tracking_exit(struct net *net)
510{ 560{
511 nfs4_release_reclaim(); 561 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
562
563 nfs4_release_reclaim(nn);
512 nfsd4_shutdown_recdir(); 564 nfsd4_shutdown_recdir();
565 nfs4_legacy_state_shutdown(net);
513} 566}
514 567
515/* 568/*
@@ -545,6 +598,7 @@ nfsd4_check_legacy_client(struct nfs4_client *clp)
545 int status; 598 int status;
546 char dname[HEXDIR_LEN]; 599 char dname[HEXDIR_LEN];
547 struct nfs4_client_reclaim *crp; 600 struct nfs4_client_reclaim *crp;
601 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
548 602
549 /* did we already find that this client is stable? */ 603 /* did we already find that this client is stable? */
550 if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags)) 604 if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
@@ -557,7 +611,7 @@ nfsd4_check_legacy_client(struct nfs4_client *clp)
557 } 611 }
558 612
559 /* look for it in the reclaim hashtable otherwise */ 613 /* look for it in the reclaim hashtable otherwise */
560 crp = nfsd4_find_reclaim_client(dname); 614 crp = nfsd4_find_reclaim_client(dname, nn);
561 if (crp) { 615 if (crp) {
562 set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); 616 set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
563 crp->cr_clp = clp; 617 crp->cr_clp = clp;
@@ -568,7 +622,7 @@ nfsd4_check_legacy_client(struct nfs4_client *clp)
568} 622}
569 623
570static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = { 624static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
571 .init = nfsd4_load_reboot_recovery_data, 625 .init = nfsd4_legacy_tracking_init,
572 .exit = nfsd4_legacy_tracking_exit, 626 .exit = nfsd4_legacy_tracking_exit,
573 .create = nfsd4_create_clid_dir, 627 .create = nfsd4_create_clid_dir,
574 .remove = nfsd4_remove_clid_dir, 628 .remove = nfsd4_remove_clid_dir,
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 001bbc99d7a4..ba4785559509 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -393,11 +393,6 @@ unhash_delegation(struct nfs4_delegation *dp)
393/* client_lock protects the client lru list and session hash table */ 393/* client_lock protects the client lru list and session hash table */
394static DEFINE_SPINLOCK(client_lock); 394static DEFINE_SPINLOCK(client_lock);
395 395
396/* Hash tables for nfs4_clientid state */
397#define CLIENT_HASH_BITS 4
398#define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS)
399#define CLIENT_HASH_MASK (CLIENT_HASH_SIZE - 1)
400
401static unsigned int clientid_hashval(u32 id) 396static unsigned int clientid_hashval(u32 id)
402{ 397{
403 return id & CLIENT_HASH_MASK; 398 return id & CLIENT_HASH_MASK;
@@ -409,11 +404,8 @@ static unsigned int clientstr_hashval(const char *name)
409} 404}
410 405
411/* 406/*
412 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
413 * used in reboot/reset lease grace period processing
414 *
415 * conf_id_hashtbl[], and conf_name_tree hold confirmed 407 * conf_id_hashtbl[], and conf_name_tree hold confirmed
416 * setclientid_confirmed info. 408 * setclientid_confirmed info.
417 * 409 *
418 * unconf_id_hashtbl[] and unconf_name_tree hold unconfirmed 410 * unconf_id_hashtbl[] and unconf_name_tree hold unconfirmed
419 * setclientid info. 411 * setclientid info.
@@ -426,8 +418,6 @@ static unsigned int clientstr_hashval(const char *name)
426 * 418 *
427 * All of the above fields are protected by the client_mutex. 419 * All of the above fields are protected by the client_mutex.
428 */ 420 */
429static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE];
430static int reclaim_str_hashtbl_size = 0;
431static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE]; 421static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE];
432static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; 422static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
433static struct rb_root conf_name_tree; 423static struct rb_root conf_name_tree;
@@ -4509,11 +4499,11 @@ alloc_reclaim(void)
4509} 4499}
4510 4500
4511bool 4501bool
4512nfs4_has_reclaimed_state(const char *name) 4502nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn)
4513{ 4503{
4514 struct nfs4_client_reclaim *crp; 4504 struct nfs4_client_reclaim *crp;
4515 4505
4516 crp = nfsd4_find_reclaim_client(name); 4506 crp = nfsd4_find_reclaim_client(name, nn);
4517 return (crp && crp->cr_clp); 4507 return (crp && crp->cr_clp);
4518} 4508}
4519 4509
@@ -4521,7 +4511,7 @@ nfs4_has_reclaimed_state(const char *name)
4521 * failure => all reset bets are off, nfserr_no_grace... 4511 * failure => all reset bets are off, nfserr_no_grace...
4522 */ 4512 */
4523struct nfs4_client_reclaim * 4513struct nfs4_client_reclaim *
4524nfs4_client_to_reclaim(const char *name) 4514nfs4_client_to_reclaim(const char *name, struct nfsd_net *nn)
4525{ 4515{
4526 unsigned int strhashval; 4516 unsigned int strhashval;
4527 struct nfs4_client_reclaim *crp; 4517 struct nfs4_client_reclaim *crp;
@@ -4531,42 +4521,42 @@ nfs4_client_to_reclaim(const char *name)
4531 if (crp) { 4521 if (crp) {
4532 strhashval = clientstr_hashval(name); 4522 strhashval = clientstr_hashval(name);
4533 INIT_LIST_HEAD(&crp->cr_strhash); 4523 INIT_LIST_HEAD(&crp->cr_strhash);
4534 list_add(&crp->cr_strhash, &reclaim_str_hashtbl[strhashval]); 4524 list_add(&crp->cr_strhash, &nn->reclaim_str_hashtbl[strhashval]);
4535 memcpy(crp->cr_recdir, name, HEXDIR_LEN); 4525 memcpy(crp->cr_recdir, name, HEXDIR_LEN);
4536 crp->cr_clp = NULL; 4526 crp->cr_clp = NULL;
4537 reclaim_str_hashtbl_size++; 4527 nn->reclaim_str_hashtbl_size++;
4538 } 4528 }
4539 return crp; 4529 return crp;
4540} 4530}
4541 4531
4542void 4532void
4543nfs4_remove_reclaim_record(struct nfs4_client_reclaim *crp) 4533nfs4_remove_reclaim_record(struct nfs4_client_reclaim *crp, struct nfsd_net *nn)
4544{ 4534{
4545 list_del(&crp->cr_strhash); 4535 list_del(&crp->cr_strhash);
4546 kfree(crp); 4536 kfree(crp);
4547 reclaim_str_hashtbl_size--; 4537 nn->reclaim_str_hashtbl_size--;
4548} 4538}
4549 4539
4550void 4540void
4551nfs4_release_reclaim(void) 4541nfs4_release_reclaim(struct nfsd_net *nn)
4552{ 4542{
4553 struct nfs4_client_reclaim *crp = NULL; 4543 struct nfs4_client_reclaim *crp = NULL;
4554 int i; 4544 int i;
4555 4545
4556 for (i = 0; i < CLIENT_HASH_SIZE; i++) { 4546 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
4557 while (!list_empty(&reclaim_str_hashtbl[i])) { 4547 while (!list_empty(&nn->reclaim_str_hashtbl[i])) {
4558 crp = list_entry(reclaim_str_hashtbl[i].next, 4548 crp = list_entry(nn->reclaim_str_hashtbl[i].next,
4559 struct nfs4_client_reclaim, cr_strhash); 4549 struct nfs4_client_reclaim, cr_strhash);
4560 nfs4_remove_reclaim_record(crp); 4550 nfs4_remove_reclaim_record(crp, nn);
4561 } 4551 }
4562 } 4552 }
4563 BUG_ON(reclaim_str_hashtbl_size); 4553 BUG_ON(nn->reclaim_str_hashtbl_size);
4564} 4554}
4565 4555
4566/* 4556/*
4567 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */ 4557 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
4568struct nfs4_client_reclaim * 4558struct nfs4_client_reclaim *
4569nfsd4_find_reclaim_client(const char *recdir) 4559nfsd4_find_reclaim_client(const char *recdir, struct nfsd_net *nn)
4570{ 4560{
4571 unsigned int strhashval; 4561 unsigned int strhashval;
4572 struct nfs4_client_reclaim *crp = NULL; 4562 struct nfs4_client_reclaim *crp = NULL;
@@ -4574,7 +4564,7 @@ nfsd4_find_reclaim_client(const char *recdir)
4574 dprintk("NFSD: nfs4_find_reclaim_client for recdir %s\n", recdir); 4564 dprintk("NFSD: nfs4_find_reclaim_client for recdir %s\n", recdir);
4575 4565
4576 strhashval = clientstr_hashval(recdir); 4566 strhashval = clientstr_hashval(recdir);
4577 list_for_each_entry(crp, &reclaim_str_hashtbl[strhashval], cr_strhash) { 4567 list_for_each_entry(crp, &nn->reclaim_str_hashtbl[strhashval], cr_strhash) {
4578 if (same_name(crp->cr_recdir, recdir)) { 4568 if (same_name(crp->cr_recdir, recdir)) {
4579 return crp; 4569 return crp;
4580 } 4570 }
@@ -4732,7 +4722,6 @@ nfs4_state_init(void)
4732 for (i = 0; i < CLIENT_HASH_SIZE; i++) { 4722 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
4733 INIT_LIST_HEAD(&conf_id_hashtbl[i]); 4723 INIT_LIST_HEAD(&conf_id_hashtbl[i]);
4734 INIT_LIST_HEAD(&unconf_id_hashtbl[i]); 4724 INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
4735 INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
4736 } 4725 }
4737 conf_name_tree = RB_ROOT; 4726 conf_name_tree = RB_ROOT;
4738 unconf_name_tree = RB_ROOT; 4727 unconf_name_tree = RB_ROOT;
@@ -4749,7 +4738,6 @@ nfs4_state_init(void)
4749 INIT_LIST_HEAD(&close_lru); 4738 INIT_LIST_HEAD(&close_lru);
4750 INIT_LIST_HEAD(&client_lru); 4739 INIT_LIST_HEAD(&client_lru);
4751 INIT_LIST_HEAD(&del_recall_lru); 4740 INIT_LIST_HEAD(&del_recall_lru);
4752 reclaim_str_hashtbl_size = 0;
4753} 4741}
4754 4742
4755/* 4743/*
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index ca8ee8c3ae74..26a912cdfe0c 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -466,9 +466,10 @@ extern __be32 nfs4_preprocess_stateid_op(struct net *net,
466 stateid_t *stateid, int flags, struct file **filp); 466 stateid_t *stateid, int flags, struct file **filp);
467extern void nfs4_lock_state(void); 467extern void nfs4_lock_state(void);
468extern void nfs4_unlock_state(void); 468extern void nfs4_unlock_state(void);
469void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *); 469void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *);
470extern void nfs4_release_reclaim(void); 470extern void nfs4_release_reclaim(struct nfsd_net *);
471extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir); 471extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir,
472 struct nfsd_net *nn);
472extern __be32 nfs4_check_open_reclaim(clientid_t *clid, bool sessions); 473extern __be32 nfs4_check_open_reclaim(clientid_t *clid, bool sessions);
473extern void nfs4_free_openowner(struct nfs4_openowner *); 474extern void nfs4_free_openowner(struct nfs4_openowner *);
474extern void nfs4_free_lockowner(struct nfs4_lockowner *); 475extern void nfs4_free_lockowner(struct nfs4_lockowner *);
@@ -482,8 +483,9 @@ extern int nfsd4_create_callback_queue(void);
482extern void nfsd4_destroy_callback_queue(void); 483extern void nfsd4_destroy_callback_queue(void);
483extern void nfsd4_shutdown_callback(struct nfs4_client *); 484extern void nfsd4_shutdown_callback(struct nfs4_client *);
484extern void nfs4_put_delegation(struct nfs4_delegation *dp); 485extern void nfs4_put_delegation(struct nfs4_delegation *dp);
485extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name); 486extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name,
486extern bool nfs4_has_reclaimed_state(const char *name); 487 struct nfsd_net *nn);
488extern bool nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn);
487extern void release_session_client(struct nfsd4_session *); 489extern void release_session_client(struct nfsd4_session *);
488extern void nfsd4_purge_closed_stateid(struct nfs4_stateowner *); 490extern void nfsd4_purge_closed_stateid(struct nfs4_stateowner *);
489 491