
From: NeilBrown <neilb@cse.unsw.edu.au>

Postpone the release of a stateowner on CLOSE for lease time to enable the
CLOSE replay cache.  Place stateowner on the close_lru list to be reaped by
the laundromat service.

Signed-off-by: Andy Adamson <andros@umich.edu>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/nfsd/nfs4state.c |   18 +++++++++++-------
 1 files changed, 11 insertions(+), 7 deletions(-)

diff -puN fs/nfsd/nfs4state.c~nfsd4-postpone-release-of-stateowner-on-close fs/nfsd/nfs4state.c
--- 25/fs/nfsd/nfs4state.c~nfsd4-postpone-release-of-stateowner-on-close	2004-09-02 20:29:00.363515568 -0700
+++ 25-akpm/fs/nfsd/nfs4state.c	2004-09-02 20:29:00.369514656 -0700
@@ -908,7 +908,7 @@ release_stateid_lockowner(struct nfs4_st
 }
 
 static void
-release_stateowner(struct nfs4_stateowner *sop)
+unhash_stateowner(struct nfs4_stateowner *sop)
 {
 	struct nfs4_stateid *stp;
 
@@ -916,7 +916,6 @@ release_stateowner(struct nfs4_stateowne
 	list_del(&sop->so_strhash);
 	list_del(&sop->so_perclient);
 	list_del(&sop->so_perlockowner);
-	list_del(&sop->so_close_lru);
 	del_perclient++;
 	while (!list_empty(&sop->so_perfilestate)) {
 		stp = list_entry(sop->so_perfilestate.next, 
@@ -926,6 +925,13 @@ release_stateowner(struct nfs4_stateowne
 		else
 			release_stateid(stp, LOCK_STATE);
 	}
+}
+
+static void
+release_stateowner(struct nfs4_stateowner *sop)
+{
+	unhash_stateowner(sop);
+	list_del(&sop->so_close_lru);
 	free_stateowner(sop);
 }
 
@@ -986,11 +992,8 @@ void
 move_to_close_lru(struct nfs4_stateowner *sop)
 {
 	dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop);
-	/* remove stateowner from all other hash lists except perclient */
-	list_del_init(&sop->so_idhash);
-	list_del_init(&sop->so_strhash);
-	list_del_init(&sop->so_perlockowner);
 
+	unhash_stateowner(sop);
 	list_add_tail(&sop->so_close_lru, &close_lru);
 	sop->so_time = get_seconds();
 }
@@ -1456,7 +1459,8 @@ nfs4_laundromat(void)
 		}
 		dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
 			sop->so_id);
-		release_stateowner(sop);
+		list_del(&sop->so_close_lru);
+		free_stateowner(sop);
 	}
 	if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT)
 		clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT;
_
