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 ---