diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-10-21 13:42:58 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-10-21 13:42:58 -0400 |
commit | ab27642b59b68d18df5a9aa5fa81b5ab5735aa77 (patch) | |
tree | afc2f191ef73e6eb1064de6358f44177d691aab0 /fs/nfs/nfs4state.c | |
parent | ba9b543d5bec0a7605952e2ba501fb8b0f3b6407 (diff) | |
parent | 654b1536b0927d189526b9063818e0790aa3ea23 (diff) |
Merge branch 'master' of ssh://rsync.linux-nfs.org/home/trondmy/www_sites/rsync.linux-nfs.org/pub/linux/nfs-2.6
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 23834c8fb740..2d5a6a2b9dec 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -267,6 +267,7 @@ nfs4_alloc_state_owner(void) | |||
267 | sp = kzalloc(sizeof(*sp),GFP_KERNEL); | 267 | sp = kzalloc(sizeof(*sp),GFP_KERNEL); |
268 | if (!sp) | 268 | if (!sp) |
269 | return NULL; | 269 | return NULL; |
270 | spin_lock_init(&sp->so_lock); | ||
270 | INIT_LIST_HEAD(&sp->so_states); | 271 | INIT_LIST_HEAD(&sp->so_states); |
271 | INIT_LIST_HEAD(&sp->so_delegations); | 272 | INIT_LIST_HEAD(&sp->so_delegations); |
272 | rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue"); | 273 | rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue"); |
@@ -438,20 +439,23 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner) | |||
438 | if (state) | 439 | if (state) |
439 | goto out; | 440 | goto out; |
440 | new = nfs4_alloc_open_state(); | 441 | new = nfs4_alloc_open_state(); |
442 | spin_lock(&owner->so_lock); | ||
441 | spin_lock(&inode->i_lock); | 443 | spin_lock(&inode->i_lock); |
442 | state = __nfs4_find_state_byowner(inode, owner); | 444 | state = __nfs4_find_state_byowner(inode, owner); |
443 | if (state == NULL && new != NULL) { | 445 | if (state == NULL && new != NULL) { |
444 | state = new; | 446 | state = new; |
445 | /* Note: The reclaim code dictates that we add stateless | ||
446 | * and read-only stateids to the end of the list */ | ||
447 | list_add_tail(&state->open_states, &owner->so_states); | ||
448 | state->owner = owner; | 447 | state->owner = owner; |
449 | atomic_inc(&owner->so_count); | 448 | atomic_inc(&owner->so_count); |
450 | list_add(&state->inode_states, &nfsi->open_states); | 449 | list_add(&state->inode_states, &nfsi->open_states); |
451 | state->inode = igrab(inode); | 450 | state->inode = igrab(inode); |
452 | spin_unlock(&inode->i_lock); | 451 | spin_unlock(&inode->i_lock); |
452 | /* Note: The reclaim code dictates that we add stateless | ||
453 | * and read-only stateids to the end of the list */ | ||
454 | list_add_tail(&state->open_states, &owner->so_states); | ||
455 | spin_unlock(&owner->so_lock); | ||
453 | } else { | 456 | } else { |
454 | spin_unlock(&inode->i_lock); | 457 | spin_unlock(&inode->i_lock); |
458 | spin_unlock(&owner->so_lock); | ||
455 | if (new) | 459 | if (new) |
456 | nfs4_free_open_state(new); | 460 | nfs4_free_open_state(new); |
457 | } | 461 | } |
@@ -468,12 +472,14 @@ void nfs4_put_open_state(struct nfs4_state *state) | |||
468 | struct inode *inode = state->inode; | 472 | struct inode *inode = state->inode; |
469 | struct nfs4_state_owner *owner = state->owner; | 473 | struct nfs4_state_owner *owner = state->owner; |
470 | 474 | ||
471 | if (!atomic_dec_and_lock(&state->count, &inode->i_lock)) | 475 | if (!atomic_dec_and_lock(&state->count, &owner->so_lock)) |
472 | return; | 476 | return; |
477 | spin_lock(&inode->i_lock); | ||
473 | if (!list_empty(&state->inode_states)) | 478 | if (!list_empty(&state->inode_states)) |
474 | list_del(&state->inode_states); | 479 | list_del(&state->inode_states); |
475 | spin_unlock(&inode->i_lock); | ||
476 | list_del(&state->open_states); | 480 | list_del(&state->open_states); |
481 | spin_unlock(&inode->i_lock); | ||
482 | spin_unlock(&owner->so_lock); | ||
477 | iput(inode); | 483 | iput(inode); |
478 | BUG_ON (state->state != 0); | 484 | BUG_ON (state->state != 0); |
479 | nfs4_free_open_state(state); | 485 | nfs4_free_open_state(state); |
@@ -491,6 +497,7 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode) | |||
491 | 497 | ||
492 | atomic_inc(&owner->so_count); | 498 | atomic_inc(&owner->so_count); |
493 | /* Protect against nfs4_find_state() */ | 499 | /* Protect against nfs4_find_state() */ |
500 | spin_lock(&owner->so_lock); | ||
494 | spin_lock(&inode->i_lock); | 501 | spin_lock(&inode->i_lock); |
495 | if (mode & FMODE_READ) | 502 | if (mode & FMODE_READ) |
496 | state->nreaders--; | 503 | state->nreaders--; |
@@ -503,6 +510,7 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode) | |||
503 | list_move_tail(&state->open_states, &owner->so_states); | 510 | list_move_tail(&state->open_states, &owner->so_states); |
504 | } | 511 | } |
505 | spin_unlock(&inode->i_lock); | 512 | spin_unlock(&inode->i_lock); |
513 | spin_unlock(&owner->so_lock); | ||
506 | newstate = 0; | 514 | newstate = 0; |
507 | if (state->state != 0) { | 515 | if (state->state != 0) { |
508 | if (state->nreaders) | 516 | if (state->nreaders) |
@@ -670,16 +678,12 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f | |||
670 | 678 | ||
671 | struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) | 679 | struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) |
672 | { | 680 | { |
673 | struct rpc_sequence *sequence = counter->sequence; | ||
674 | struct nfs_seqid *new; | 681 | struct nfs_seqid *new; |
675 | 682 | ||
676 | new = kmalloc(sizeof(*new), GFP_KERNEL); | 683 | new = kmalloc(sizeof(*new), GFP_KERNEL); |
677 | if (new != NULL) { | 684 | if (new != NULL) { |
678 | new->sequence = counter; | 685 | new->sequence = counter; |
679 | new->task = NULL; | 686 | INIT_LIST_HEAD(&new->list); |
680 | spin_lock(&sequence->lock); | ||
681 | list_add_tail(&new->list, &sequence->list); | ||
682 | spin_unlock(&sequence->lock); | ||
683 | } | 687 | } |
684 | return new; | 688 | return new; |
685 | } | 689 | } |
@@ -687,16 +691,13 @@ struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) | |||
687 | void nfs_free_seqid(struct nfs_seqid *seqid) | 691 | void nfs_free_seqid(struct nfs_seqid *seqid) |
688 | { | 692 | { |
689 | struct rpc_sequence *sequence = seqid->sequence->sequence; | 693 | struct rpc_sequence *sequence = seqid->sequence->sequence; |
690 | struct rpc_task *next = NULL; | ||
691 | 694 | ||
692 | spin_lock(&sequence->lock); | 695 | if (!list_empty(&seqid->list)) { |
693 | list_del(&seqid->list); | 696 | spin_lock(&sequence->lock); |
694 | if (!list_empty(&sequence->list)) { | 697 | list_del(&seqid->list); |
695 | next = list_entry(sequence->list.next, struct nfs_seqid, list)->task; | 698 | spin_unlock(&sequence->lock); |
696 | if (next) | ||
697 | rpc_wake_up_task(next); | ||
698 | } | 699 | } |
699 | spin_unlock(&sequence->lock); | 700 | rpc_wake_up_next(&sequence->wait); |
700 | kfree(seqid); | 701 | kfree(seqid); |
701 | } | 702 | } |
702 | 703 | ||
@@ -752,13 +753,16 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task) | |||
752 | struct rpc_sequence *sequence = seqid->sequence->sequence; | 753 | struct rpc_sequence *sequence = seqid->sequence->sequence; |
753 | int status = 0; | 754 | int status = 0; |
754 | 755 | ||
756 | if (sequence->list.next == &seqid->list) | ||
757 | goto out; | ||
755 | spin_lock(&sequence->lock); | 758 | spin_lock(&sequence->lock); |
756 | if (sequence->list.next != &seqid->list) { | 759 | if (!list_empty(&sequence->list)) { |
757 | seqid->task = task; | ||
758 | rpc_sleep_on(&sequence->wait, task, NULL, NULL); | 760 | rpc_sleep_on(&sequence->wait, task, NULL, NULL); |
759 | status = -EAGAIN; | 761 | status = -EAGAIN; |
760 | } | 762 | } else |
763 | list_add(&seqid->list, &sequence->list); | ||
761 | spin_unlock(&sequence->lock); | 764 | spin_unlock(&sequence->lock); |
765 | out: | ||
762 | return status; | 766 | return status; |
763 | } | 767 | } |
764 | 768 | ||
@@ -903,6 +907,7 @@ static void nfs4_state_mark_reclaim(struct nfs4_client *clp) | |||
903 | list_for_each_entry(sp, &clp->cl_state_owners, so_list) { | 907 | list_for_each_entry(sp, &clp->cl_state_owners, so_list) { |
904 | sp->so_seqid.counter = 0; | 908 | sp->so_seqid.counter = 0; |
905 | sp->so_seqid.flags = 0; | 909 | sp->so_seqid.flags = 0; |
910 | spin_lock(&sp->so_lock); | ||
906 | list_for_each_entry(state, &sp->so_states, open_states) { | 911 | list_for_each_entry(state, &sp->so_states, open_states) { |
907 | list_for_each_entry(lock, &state->lock_states, ls_locks) { | 912 | list_for_each_entry(lock, &state->lock_states, ls_locks) { |
908 | lock->ls_seqid.counter = 0; | 913 | lock->ls_seqid.counter = 0; |
@@ -910,6 +915,7 @@ static void nfs4_state_mark_reclaim(struct nfs4_client *clp) | |||
910 | lock->ls_flags &= ~NFS_LOCK_INITIALIZED; | 915 | lock->ls_flags &= ~NFS_LOCK_INITIALIZED; |
911 | } | 916 | } |
912 | } | 917 | } |
918 | spin_unlock(&sp->so_lock); | ||
913 | } | 919 | } |
914 | } | 920 | } |
915 | 921 | ||