NFSv4: Fix buggy nfs_wait_on_sequence()

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

+10 -10
+10 -10
fs/nfs/nfs4state.c
··· 644 645 struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) 646 { 647 struct nfs_seqid *new; 648 649 new = kmalloc(sizeof(*new), GFP_KERNEL); 650 if (new != NULL) { 651 new->sequence = counter; 652 - INIT_LIST_HEAD(&new->list); 653 } 654 return new; 655 } ··· 661 { 662 struct rpc_sequence *sequence = seqid->sequence->sequence; 663 664 - if (!list_empty(&seqid->list)) { 665 - spin_lock(&sequence->lock); 666 - list_del(&seqid->list); 667 - spin_unlock(&sequence->lock); 668 - } 669 - rpc_wake_up_next(&sequence->wait); 670 kfree(seqid); 671 } 672 ··· 723 if (sequence->list.next == &seqid->list) 724 goto out; 725 spin_lock(&sequence->lock); 726 - if (!list_empty(&sequence->list)) { 727 rpc_sleep_on(&sequence->wait, task, NULL, NULL); 728 status = -EAGAIN; 729 - } else 730 - list_add(&seqid->list, &sequence->list); 731 spin_unlock(&sequence->lock); 732 out: 733 return status;
··· 644 645 struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) 646 { 647 + struct rpc_sequence *sequence = counter->sequence; 648 struct nfs_seqid *new; 649 650 new = kmalloc(sizeof(*new), GFP_KERNEL); 651 if (new != NULL) { 652 new->sequence = counter; 653 + spin_lock(&sequence->lock); 654 + list_add_tail(&new->list, &sequence->list); 655 + spin_unlock(&sequence->lock); 656 } 657 return new; 658 } ··· 658 { 659 struct rpc_sequence *sequence = seqid->sequence->sequence; 660 661 + spin_lock(&sequence->lock); 662 + list_del(&seqid->list); 663 + spin_unlock(&sequence->lock); 664 + rpc_wake_up(&sequence->wait); 665 kfree(seqid); 666 } 667 ··· 722 if (sequence->list.next == &seqid->list) 723 goto out; 724 spin_lock(&sequence->lock); 725 + if (sequence->list.next != &seqid->list) { 726 rpc_sleep_on(&sequence->wait, task, NULL, NULL); 727 status = -EAGAIN; 728 + } 729 spin_unlock(&sequence->lock); 730 out: 731 return status;