aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-08 17:56:07 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-30 02:05:24 -0500
commit2f74c0a05612b9c2014b5b67833dba9b9f523948 (patch)
tree59bb49bd9a393774b65e3d39e53edfe7bab4613e /fs/nfs/nfs4state.c
parentacee478afc6ff7e1b8852d9a4dca1ff36021414d (diff)
NFSv4: Clean up the OPEN/CLOSE serialisation code
Reduce the time spent locking the rpc_sequence structure by queuing the nfs_seqid only when we are ready to take the lock (when calling nfs_wait_on_sequence). Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 5a39c6f78acf..bf94c6e0a503 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -644,27 +644,26 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f
644 644
645struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) 645struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
646{ 646{
647 struct rpc_sequence *sequence = counter->sequence;
648 struct nfs_seqid *new; 647 struct nfs_seqid *new;
649 648
650 new = kmalloc(sizeof(*new), GFP_KERNEL); 649 new = kmalloc(sizeof(*new), GFP_KERNEL);
651 if (new != NULL) { 650 if (new != NULL) {
652 new->sequence = counter; 651 new->sequence = counter;
653 spin_lock(&sequence->lock); 652 INIT_LIST_HEAD(&new->list);
654 list_add_tail(&new->list, &sequence->list);
655 spin_unlock(&sequence->lock);
656 } 653 }
657 return new; 654 return new;
658} 655}
659 656
660void nfs_free_seqid(struct nfs_seqid *seqid) 657void nfs_free_seqid(struct nfs_seqid *seqid)
661{ 658{
662 struct rpc_sequence *sequence = seqid->sequence->sequence; 659 if (!list_empty(&seqid->list)) {
660 struct rpc_sequence *sequence = seqid->sequence->sequence;
663 661
664 spin_lock(&sequence->lock); 662 spin_lock(&sequence->lock);
665 list_del(&seqid->list); 663 list_del(&seqid->list);
666 spin_unlock(&sequence->lock); 664 spin_unlock(&sequence->lock);
667 rpc_wake_up(&sequence->wait); 665 rpc_wake_up(&sequence->wait);
666 }
668 kfree(seqid); 667 kfree(seqid);
669} 668}
670 669
@@ -675,6 +674,7 @@ void nfs_free_seqid(struct nfs_seqid *seqid)
675 */ 674 */
676static void nfs_increment_seqid(int status, struct nfs_seqid *seqid) 675static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
677{ 676{
677 BUG_ON(list_first_entry(&seqid->sequence->sequence->list, struct nfs_seqid, list) != seqid);
678 switch (status) { 678 switch (status) {
679 case 0: 679 case 0:
680 break; 680 break;
@@ -726,15 +726,15 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
726 struct rpc_sequence *sequence = seqid->sequence->sequence; 726 struct rpc_sequence *sequence = seqid->sequence->sequence;
727 int status = 0; 727 int status = 0;
728 728
729 if (sequence->list.next == &seqid->list)
730 goto out;
731 spin_lock(&sequence->lock); 729 spin_lock(&sequence->lock);
732 if (sequence->list.next != &seqid->list) { 730 if (list_empty(&seqid->list))
733 rpc_sleep_on(&sequence->wait, task, NULL, NULL); 731 list_add_tail(&seqid->list, &sequence->list);
734 status = -EAGAIN; 732 if (list_first_entry(&sequence->list, struct nfs_seqid, list) == seqid)
735 } 733 goto unlock;
734 rpc_sleep_on(&sequence->wait, task, NULL, NULL);
735 status = -EAGAIN;
736unlock:
736 spin_unlock(&sequence->lock); 737 spin_unlock(&sequence->lock);
737out:
738 return status; 738 return status;
739} 739}
740 740