From 36f20c6df75d599393d79c7feb6283b20913e3d5 Mon Sep 17 00:00:00 2001
From: Trond Myklebust <Trond.Myklebust@netapp.com>
Date: Fri, 25 Nov 2005 17:09:57 -0500
Subject: [PATCH] NFSv4: Fix buggy nfs_wait_on_sequence()

 Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
 fs/nfs/nfs4state.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 0675f3215e0a4..5ef4c57618fe8 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -644,12 +644,15 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f
 
 struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
 {
+	struct rpc_sequence *sequence = counter->sequence;
 	struct nfs_seqid *new;
 
 	new = kmalloc(sizeof(*new), GFP_KERNEL);
 	if (new != NULL) {
 		new->sequence = counter;
-		INIT_LIST_HEAD(&new->list);
+		spin_lock(&sequence->lock);
+		list_add_tail(&new->list, &sequence->list);
+		spin_unlock(&sequence->lock);
 	}
 	return new;
 }
@@ -658,12 +661,10 @@ void nfs_free_seqid(struct nfs_seqid *seqid)
 {
 	struct rpc_sequence *sequence = seqid->sequence->sequence;
 
-	if (!list_empty(&seqid->list)) {
-		spin_lock(&sequence->lock);
-		list_del(&seqid->list);
-		spin_unlock(&sequence->lock);
-	}
-	rpc_wake_up_next(&sequence->wait);
+	spin_lock(&sequence->lock);
+	list_del(&seqid->list);
+	spin_unlock(&sequence->lock);
+	rpc_wake_up(&sequence->wait);
 	kfree(seqid);
 }
 
@@ -722,11 +723,10 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
 	if (sequence->list.next == &seqid->list)
 		goto out;
 	spin_lock(&sequence->lock);
-	if (!list_empty(&sequence->list)) {
+	if (sequence->list.next != &seqid->list) {
 		rpc_sleep_on(&sequence->wait, task, NULL, NULL);
 		status = -EAGAIN;
-	} else
-		list_add(&seqid->list, &sequence->list);
+	}
 	spin_unlock(&sequence->lock);
 out:
 	return status;
-- 
2.30.2