diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2012-11-14 10:21:16 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-11-15 07:40:43 -0500 |
commit | 52e19c09a183d82d99f10c284bc8b27933b1d1fc (patch) | |
tree | 7a4f21eecd888cea675d7ccddddfd03774337af4 /fs | |
parent | c212cecfa21b3d30cd5cc2389754a46973ad9027 (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.h | 12 | ||||
-rw-r--r-- | fs/nfsd/nfs4recover.c | 100 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 42 | ||||
-rw-r--r-- | fs/nfsd/state.h | 12 |
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 | |||
27 | struct cld_net; | 32 | struct cld_net; |
28 | 33 | ||
29 | struct nfsd_net { | 34 | struct 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 | ||
43 | extern int nfsd_net_id; | 55 | extern 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 | ||
240 | typedef int (recdir_func)(struct dentry *, struct dentry *); | 241 | typedef int (recdir_func)(struct dentry *, struct dentry *, struct nfsd_net *); |
241 | 242 | ||
242 | struct name_list { | 243 | struct 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 | ||
265 | static int | 266 | static int |
266 | nfsd4_list_rec_dir(recdir_func *f) | 267 | nfsd4_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 | } |
367 | out_drop_write: | 369 | out_drop_write: |
@@ -373,11 +375,11 @@ out: | |||
373 | } | 375 | } |
374 | 376 | ||
375 | static int | 377 | static int |
376 | purge_old(struct dentry *parent, struct dentry *child) | 378 | purge_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 | |||
392 | nfsd4_recdir_purge_old(struct net *net, time_t boot_time) | 394 | nfsd4_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); |
406 | out: | 409 | out: |
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 | ||
413 | static int | 416 | static int |
414 | load_recdir(struct dentry *parent, struct dentry *child) | 417 | load_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 | ||
426 | static int | 429 | static int |
427 | nfsd4_recdir_load(void) { | 430 | nfsd4_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 | |||
482 | static int | ||
483 | nfs4_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 | |||
500 | static void | ||
501 | nfs4_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 | |||
477 | static int | 508 | static int |
478 | nfsd4_load_reboot_recovery_data(struct net *net) | 509 | nfsd4_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 | |||
523 | static int | ||
524 | nfsd4_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 | |||
544 | err: | ||
545 | nfs4_legacy_state_shutdown(net); | ||
496 | return status; | 546 | return status; |
497 | } | 547 | } |
498 | 548 | ||
@@ -508,8 +558,11 @@ nfsd4_shutdown_recdir(void) | |||
508 | static void | 558 | static void |
509 | nfsd4_legacy_tracking_exit(struct net *net) | 559 | nfsd4_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 | ||
570 | static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = { | 624 | static 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 */ |
394 | static DEFINE_SPINLOCK(client_lock); | 394 | static 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 | |||
401 | static unsigned int clientid_hashval(u32 id) | 396 | static 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 | */ |
429 | static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE]; | ||
430 | static int reclaim_str_hashtbl_size = 0; | ||
431 | static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE]; | 421 | static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE]; |
432 | static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; | 422 | static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; |
433 | static struct rb_root conf_name_tree; | 423 | static struct rb_root conf_name_tree; |
@@ -4509,11 +4499,11 @@ alloc_reclaim(void) | |||
4509 | } | 4499 | } |
4510 | 4500 | ||
4511 | bool | 4501 | bool |
4512 | nfs4_has_reclaimed_state(const char *name) | 4502 | nfs4_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 | */ |
4523 | struct nfs4_client_reclaim * | 4513 | struct nfs4_client_reclaim * |
4524 | nfs4_client_to_reclaim(const char *name) | 4514 | nfs4_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 | ||
4542 | void | 4532 | void |
4543 | nfs4_remove_reclaim_record(struct nfs4_client_reclaim *crp) | 4533 | nfs4_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 | ||
4550 | void | 4540 | void |
4551 | nfs4_release_reclaim(void) | 4541 | nfs4_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. */ |
4568 | struct nfs4_client_reclaim * | 4558 | struct nfs4_client_reclaim * |
4569 | nfsd4_find_reclaim_client(const char *recdir) | 4559 | nfsd4_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); |
467 | extern void nfs4_lock_state(void); | 467 | extern void nfs4_lock_state(void); |
468 | extern void nfs4_unlock_state(void); | 468 | extern void nfs4_unlock_state(void); |
469 | void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *); | 469 | void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *); |
470 | extern void nfs4_release_reclaim(void); | 470 | extern void nfs4_release_reclaim(struct nfsd_net *); |
471 | extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir); | 471 | extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir, |
472 | struct nfsd_net *nn); | ||
472 | extern __be32 nfs4_check_open_reclaim(clientid_t *clid, bool sessions); | 473 | extern __be32 nfs4_check_open_reclaim(clientid_t *clid, bool sessions); |
473 | extern void nfs4_free_openowner(struct nfs4_openowner *); | 474 | extern void nfs4_free_openowner(struct nfs4_openowner *); |
474 | extern void nfs4_free_lockowner(struct nfs4_lockowner *); | 475 | extern void nfs4_free_lockowner(struct nfs4_lockowner *); |
@@ -482,8 +483,9 @@ extern int nfsd4_create_callback_queue(void); | |||
482 | extern void nfsd4_destroy_callback_queue(void); | 483 | extern void nfsd4_destroy_callback_queue(void); |
483 | extern void nfsd4_shutdown_callback(struct nfs4_client *); | 484 | extern void nfsd4_shutdown_callback(struct nfs4_client *); |
484 | extern void nfs4_put_delegation(struct nfs4_delegation *dp); | 485 | extern void nfs4_put_delegation(struct nfs4_delegation *dp); |
485 | extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name); | 486 | extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name, |
486 | extern bool nfs4_has_reclaimed_state(const char *name); | 487 | struct nfsd_net *nn); |
488 | extern bool nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn); | ||
487 | extern void release_session_client(struct nfsd4_session *); | 489 | extern void release_session_client(struct nfsd4_session *); |
488 | extern void nfsd4_purge_closed_stateid(struct nfs4_stateowner *); | 490 | extern void nfsd4_purge_closed_stateid(struct nfs4_stateowner *); |
489 | 491 | ||