nfs4state.c (414adf14cd3b52e411f79d941a15d0fd4af427fc) | nfs4state.c (0aaaf5c424c7ffd6b0c4253251356558b16ef3a2) |
---|---|
1/* 2 * fs/nfs/nfs4state.c 3 * 4 * Client-side XDR for NFSv4. 5 * 6 * Copyright (c) 2002 The Regents of the University of Michigan. 7 * All rights reserved. 8 * --- 35 unchanged lines hidden (view full) --- 44#include <linux/nfs_fs.h> 45#include <linux/nfs_idmap.h> 46#include <linux/kthread.h> 47#include <linux/module.h> 48#include <linux/random.h> 49#include <linux/ratelimit.h> 50#include <linux/workqueue.h> 51#include <linux/bitops.h> | 1/* 2 * fs/nfs/nfs4state.c 3 * 4 * Client-side XDR for NFSv4. 5 * 6 * Copyright (c) 2002 The Regents of the University of Michigan. 7 * All rights reserved. 8 * --- 35 unchanged lines hidden (view full) --- 44#include <linux/nfs_fs.h> 45#include <linux/nfs_idmap.h> 46#include <linux/kthread.h> 47#include <linux/module.h> 48#include <linux/random.h> 49#include <linux/ratelimit.h> 50#include <linux/workqueue.h> 51#include <linux/bitops.h> |
52#include <linux/jiffies.h> |
|
52 53#include "nfs4_fs.h" 54#include "callback.h" 55#include "delegation.h" 56#include "internal.h" 57#include "pnfs.h" 58 59#define OPENOWNER_POOL_SIZE 8 --- 323 unchanged lines hidden (view full) --- 383 parent = *p; 384 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node); 385 386 if (cred < sp->so_cred) 387 p = &parent->rb_left; 388 else if (cred > sp->so_cred) 389 p = &parent->rb_right; 390 else { | 53 54#include "nfs4_fs.h" 55#include "callback.h" 56#include "delegation.h" 57#include "internal.h" 58#include "pnfs.h" 59 60#define OPENOWNER_POOL_SIZE 8 --- 323 unchanged lines hidden (view full) --- 384 parent = *p; 385 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node); 386 387 if (cred < sp->so_cred) 388 p = &parent->rb_left; 389 else if (cred > sp->so_cred) 390 p = &parent->rb_right; 391 else { |
392 if (!list_empty(&sp->so_lru)) 393 list_del_init(&sp->so_lru); |
|
391 atomic_inc(&sp->so_count); 392 return sp; 393 } 394 } 395 return NULL; 396} 397 398static struct nfs4_state_owner * --- 8 unchanged lines hidden (view full) --- 407 parent = *p; 408 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node); 409 410 if (new->so_cred < sp->so_cred) 411 p = &parent->rb_left; 412 else if (new->so_cred > sp->so_cred) 413 p = &parent->rb_right; 414 else { | 394 atomic_inc(&sp->so_count); 395 return sp; 396 } 397 } 398 return NULL; 399} 400 401static struct nfs4_state_owner * --- 8 unchanged lines hidden (view full) --- 410 parent = *p; 411 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node); 412 413 if (new->so_cred < sp->so_cred) 414 p = &parent->rb_left; 415 else if (new->so_cred > sp->so_cred) 416 p = &parent->rb_right; 417 else { |
418 if (!list_empty(&sp->so_lru)) 419 list_del_init(&sp->so_lru); |
|
415 atomic_inc(&sp->so_count); 416 return sp; 417 } 418 } 419 nfs_alloc_unique_id_locked(&server->openowner_id, 420 &new->so_owner_id, 1, 64); 421 rb_link_node(&new->so_server_node, parent, p); 422 rb_insert_color(&new->so_server_node, &server->state_owners); --- 25 unchanged lines hidden (view full) --- 448 return NULL; 449 spin_lock_init(&sp->so_lock); 450 INIT_LIST_HEAD(&sp->so_states); 451 rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue"); 452 sp->so_seqid.sequence = &sp->so_sequence; 453 spin_lock_init(&sp->so_sequence.lock); 454 INIT_LIST_HEAD(&sp->so_sequence.list); 455 atomic_set(&sp->so_count, 1); | 420 atomic_inc(&sp->so_count); 421 return sp; 422 } 423 } 424 nfs_alloc_unique_id_locked(&server->openowner_id, 425 &new->so_owner_id, 1, 64); 426 rb_link_node(&new->so_server_node, parent, p); 427 rb_insert_color(&new->so_server_node, &server->state_owners); --- 25 unchanged lines hidden (view full) --- 453 return NULL; 454 spin_lock_init(&sp->so_lock); 455 INIT_LIST_HEAD(&sp->so_states); 456 rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue"); 457 sp->so_seqid.sequence = &sp->so_sequence; 458 spin_lock_init(&sp->so_sequence.lock); 459 INIT_LIST_HEAD(&sp->so_sequence.list); 460 atomic_set(&sp->so_count, 1); |
461 INIT_LIST_HEAD(&sp->so_lru); |
|
456 return sp; 457} 458 459static void 460nfs4_drop_state_owner(struct nfs4_state_owner *sp) 461{ 462 if (!RB_EMPTY_NODE(&sp->so_server_node)) { 463 struct nfs_server *server = sp->so_server; 464 struct nfs_client *clp = server->nfs_client; 465 466 spin_lock(&clp->cl_lock); 467 rb_erase(&sp->so_server_node, &server->state_owners); 468 RB_CLEAR_NODE(&sp->so_server_node); 469 spin_unlock(&clp->cl_lock); 470 } 471} 472 | 462 return sp; 463} 464 465static void 466nfs4_drop_state_owner(struct nfs4_state_owner *sp) 467{ 468 if (!RB_EMPTY_NODE(&sp->so_server_node)) { 469 struct nfs_server *server = sp->so_server; 470 struct nfs_client *clp = server->nfs_client; 471 472 spin_lock(&clp->cl_lock); 473 rb_erase(&sp->so_server_node, &server->state_owners); 474 RB_CLEAR_NODE(&sp->so_server_node); 475 spin_unlock(&clp->cl_lock); 476 } 477} 478 |
479static void nfs4_free_state_owner(struct nfs4_state_owner *sp) 480{ 481 rpc_destroy_wait_queue(&sp->so_sequence.wait); 482 put_rpccred(sp->so_cred); 483 kfree(sp); 484} 485 486static void nfs4_gc_state_owners(struct nfs_server *server) 487{ 488 struct nfs_client *clp = server->nfs_client; 489 struct nfs4_state_owner *sp, *tmp; 490 unsigned long time_min, time_max; 491 LIST_HEAD(doomed); 492 493 spin_lock(&clp->cl_lock); 494 time_max = jiffies; 495 time_min = (long)time_max - (long)clp->cl_lease_time; 496 list_for_each_entry_safe(sp, tmp, &server->state_owners_lru, so_lru) { 497 /* NB: LRU is sorted so that oldest is at the head */ 498 if (time_in_range(sp->so_expires, time_min, time_max)) 499 break; 500 list_move(&sp->so_lru, &doomed); 501 nfs4_remove_state_owner_locked(sp); 502 } 503 spin_unlock(&clp->cl_lock); 504 505 list_for_each_entry_safe(sp, tmp, &doomed, so_lru) { 506 list_del(&sp->so_lru); 507 nfs4_free_state_owner(sp); 508 } 509} 510 |
|
473/** 474 * nfs4_get_state_owner - Look up a state owner given a credential 475 * @server: nfs_server to search 476 * @cred: RPC credential to match 477 * 478 * Returns a pointer to an instantiated nfs4_state_owner struct, or NULL. 479 */ 480struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, 481 struct rpc_cred *cred) 482{ 483 struct nfs_client *clp = server->nfs_client; 484 struct nfs4_state_owner *sp, *new; 485 486 spin_lock(&clp->cl_lock); 487 sp = nfs4_find_state_owner_locked(server, cred); 488 spin_unlock(&clp->cl_lock); 489 if (sp != NULL) | 511/** 512 * nfs4_get_state_owner - Look up a state owner given a credential 513 * @server: nfs_server to search 514 * @cred: RPC credential to match 515 * 516 * Returns a pointer to an instantiated nfs4_state_owner struct, or NULL. 517 */ 518struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, 519 struct rpc_cred *cred) 520{ 521 struct nfs_client *clp = server->nfs_client; 522 struct nfs4_state_owner *sp, *new; 523 524 spin_lock(&clp->cl_lock); 525 sp = nfs4_find_state_owner_locked(server, cred); 526 spin_unlock(&clp->cl_lock); 527 if (sp != NULL) |
490 return sp; | 528 goto out; |
491 new = nfs4_alloc_state_owner(); 492 if (new == NULL) | 529 new = nfs4_alloc_state_owner(); 530 if (new == NULL) |
493 return NULL; | 531 goto out; |
494 new->so_server = server; 495 new->so_cred = cred; 496 spin_lock(&clp->cl_lock); 497 sp = nfs4_insert_state_owner_locked(new); 498 spin_unlock(&clp->cl_lock); 499 if (sp == new) 500 get_rpccred(cred); 501 else { 502 rpc_destroy_wait_queue(&new->so_sequence.wait); 503 kfree(new); 504 } | 532 new->so_server = server; 533 new->so_cred = cred; 534 spin_lock(&clp->cl_lock); 535 sp = nfs4_insert_state_owner_locked(new); 536 spin_unlock(&clp->cl_lock); 537 if (sp == new) 538 get_rpccred(cred); 539 else { 540 rpc_destroy_wait_queue(&new->so_sequence.wait); 541 kfree(new); 542 } |
543out: 544 nfs4_gc_state_owners(server); |
|
505 return sp; 506} 507 508/** 509 * nfs4_put_state_owner - Release a nfs4_state_owner 510 * @sp: state owner data to release | 545 return sp; 546} 547 548/** 549 * nfs4_put_state_owner - Release a nfs4_state_owner 550 * @sp: state owner data to release |
511 * | |
512 */ 513void nfs4_put_state_owner(struct nfs4_state_owner *sp) 514{ | 551 */ 552void nfs4_put_state_owner(struct nfs4_state_owner *sp) 553{ |
515 struct nfs_client *clp = sp->so_server->nfs_client; 516 struct rpc_cred *cred = sp->so_cred; | 554 struct nfs_server *server = sp->so_server; 555 struct nfs_client *clp = server->nfs_client; |
517 518 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) 519 return; | 556 557 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) 558 return; |
520 nfs4_remove_state_owner_locked(sp); | 559 560 if (!RB_EMPTY_NODE(&sp->so_server_node)) { 561 sp->so_expires = jiffies; 562 list_add_tail(&sp->so_lru, &server->state_owners_lru); 563 spin_unlock(&clp->cl_lock); 564 } else { 565 nfs4_remove_state_owner_locked(sp); 566 spin_unlock(&clp->cl_lock); 567 nfs4_free_state_owner(sp); 568 } 569} 570 571/** 572 * nfs4_purge_state_owners - Release all cached state owners 573 * @server: nfs_server with cached state owners to release 574 * 575 * Called at umount time. Remaining state owners will be on 576 * the LRU with ref count of zero. 577 */ 578void nfs4_purge_state_owners(struct nfs_server *server) 579{ 580 struct nfs_client *clp = server->nfs_client; 581 struct nfs4_state_owner *sp, *tmp; 582 LIST_HEAD(doomed); 583 584 spin_lock(&clp->cl_lock); 585 list_for_each_entry_safe(sp, tmp, &server->state_owners_lru, so_lru) { 586 list_move(&sp->so_lru, &doomed); 587 nfs4_remove_state_owner_locked(sp); 588 } |
521 spin_unlock(&clp->cl_lock); | 589 spin_unlock(&clp->cl_lock); |
522 rpc_destroy_wait_queue(&sp->so_sequence.wait); 523 put_rpccred(cred); 524 kfree(sp); | 590 591 list_for_each_entry_safe(sp, tmp, &doomed, so_lru) { 592 list_del(&sp->so_lru); 593 nfs4_free_state_owner(sp); 594 } |
525} 526 527static struct nfs4_state * 528nfs4_alloc_open_state(void) 529{ 530 struct nfs4_state *state; 531 532 state = kzalloc(sizeof(*state), GFP_NOFS); --- 855 unchanged lines hidden (view full) --- 1388 struct nfs4_state_owner *sp; 1389 struct nfs_server *server; 1390 struct rb_node *pos; 1391 int status = 0; 1392 1393restart: 1394 rcu_read_lock(); 1395 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { | 595} 596 597static struct nfs4_state * 598nfs4_alloc_open_state(void) 599{ 600 struct nfs4_state *state; 601 602 state = kzalloc(sizeof(*state), GFP_NOFS); --- 855 unchanged lines hidden (view full) --- 1458 struct nfs4_state_owner *sp; 1459 struct nfs_server *server; 1460 struct rb_node *pos; 1461 int status = 0; 1462 1463restart: 1464 rcu_read_lock(); 1465 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { |
1466 nfs4_purge_state_owners(server); |
|
1396 spin_lock(&clp->cl_lock); 1397 for (pos = rb_first(&server->state_owners); 1398 pos != NULL; 1399 pos = rb_next(pos)) { 1400 sp = rb_entry(pos, 1401 struct nfs4_state_owner, so_server_node); 1402 if (!test_and_clear_bit(ops->owner_flag_bit, 1403 &sp->so_flags)) --- 349 unchanged lines hidden --- | 1467 spin_lock(&clp->cl_lock); 1468 for (pos = rb_first(&server->state_owners); 1469 pos != NULL; 1470 pos = rb_next(pos)) { 1471 sp = rb_entry(pos, 1472 struct nfs4_state_owner, so_server_node); 1473 if (!test_and_clear_bit(ops->owner_flag_bit, 1474 &sp->so_flags)) --- 349 unchanged lines hidden --- |