diff options
Diffstat (limited to 'fs/nfs/nfs4state.c')
| -rw-r--r-- | fs/nfs/nfs4state.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 0f43414eb25a..7f0fcfc1fe9d 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
| @@ -393,6 +393,7 @@ nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp) | |||
| 393 | static void | 393 | static void |
| 394 | nfs4_init_seqid_counter(struct nfs_seqid_counter *sc) | 394 | nfs4_init_seqid_counter(struct nfs_seqid_counter *sc) |
| 395 | { | 395 | { |
| 396 | sc->create_time = ktime_get(); | ||
| 396 | sc->flags = 0; | 397 | sc->flags = 0; |
| 397 | sc->counter = 0; | 398 | sc->counter = 0; |
| 398 | spin_lock_init(&sc->lock); | 399 | spin_lock_init(&sc->lock); |
| @@ -434,13 +435,17 @@ nfs4_alloc_state_owner(struct nfs_server *server, | |||
| 434 | static void | 435 | static void |
| 435 | nfs4_drop_state_owner(struct nfs4_state_owner *sp) | 436 | nfs4_drop_state_owner(struct nfs4_state_owner *sp) |
| 436 | { | 437 | { |
| 437 | if (!RB_EMPTY_NODE(&sp->so_server_node)) { | 438 | struct rb_node *rb_node = &sp->so_server_node; |
| 439 | |||
| 440 | if (!RB_EMPTY_NODE(rb_node)) { | ||
| 438 | struct nfs_server *server = sp->so_server; | 441 | struct nfs_server *server = sp->so_server; |
| 439 | struct nfs_client *clp = server->nfs_client; | 442 | struct nfs_client *clp = server->nfs_client; |
| 440 | 443 | ||
| 441 | spin_lock(&clp->cl_lock); | 444 | spin_lock(&clp->cl_lock); |
| 442 | rb_erase(&sp->so_server_node, &server->state_owners); | 445 | if (!RB_EMPTY_NODE(rb_node)) { |
| 443 | RB_CLEAR_NODE(&sp->so_server_node); | 446 | rb_erase(rb_node, &server->state_owners); |
| 447 | RB_CLEAR_NODE(rb_node); | ||
| 448 | } | ||
| 444 | spin_unlock(&clp->cl_lock); | 449 | spin_unlock(&clp->cl_lock); |
| 445 | } | 450 | } |
| 446 | } | 451 | } |
| @@ -516,6 +521,14 @@ out: | |||
| 516 | /** | 521 | /** |
| 517 | * nfs4_put_state_owner - Release a nfs4_state_owner | 522 | * nfs4_put_state_owner - Release a nfs4_state_owner |
| 518 | * @sp: state owner data to release | 523 | * @sp: state owner data to release |
| 524 | * | ||
| 525 | * Note that we keep released state owners on an LRU | ||
| 526 | * list. | ||
| 527 | * This caches valid state owners so that they can be | ||
| 528 | * reused, to avoid the OPEN_CONFIRM on minor version 0. | ||
| 529 | * It also pins the uniquifier of dropped state owners for | ||
| 530 | * a while, to ensure that those state owner names are | ||
| 531 | * never reused. | ||
| 519 | */ | 532 | */ |
| 520 | void nfs4_put_state_owner(struct nfs4_state_owner *sp) | 533 | void nfs4_put_state_owner(struct nfs4_state_owner *sp) |
| 521 | { | 534 | { |
| @@ -525,15 +538,9 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp) | |||
| 525 | if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) | 538 | if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) |
| 526 | return; | 539 | return; |
| 527 | 540 | ||
| 528 | if (!RB_EMPTY_NODE(&sp->so_server_node)) { | 541 | sp->so_expires = jiffies; |
| 529 | sp->so_expires = jiffies; | 542 | list_add_tail(&sp->so_lru, &server->state_owners_lru); |
| 530 | list_add_tail(&sp->so_lru, &server->state_owners_lru); | 543 | spin_unlock(&clp->cl_lock); |
| 531 | spin_unlock(&clp->cl_lock); | ||
| 532 | } else { | ||
| 533 | nfs4_remove_state_owner_locked(sp); | ||
| 534 | spin_unlock(&clp->cl_lock); | ||
| 535 | nfs4_free_state_owner(sp); | ||
| 536 | } | ||
| 537 | } | 544 | } |
| 538 | 545 | ||
| 539 | /** | 546 | /** |
