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

... to protect the null (probe) callback asynchronous rpc's reference.

Atomically inc and set the cb_set flag.

Signed-off-by: Andy Adamson <andros@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        |   14 ++++++++++++--
 25-akpm/include/linux/nfsd/state.h |    4 +++-
 2 files changed, 15 insertions(+), 3 deletions(-)

diff -puN fs/nfsd/nfs4state.c~knfsd-count-the-nfs4_client-structure-usage fs/nfsd/nfs4state.c
--- 25/fs/nfsd/nfs4state.c~knfsd-count-the-nfs4_client-structure-usage	Fri Dec 17 15:08:28 2004
+++ 25-akpm/fs/nfsd/nfs4state.c	Fri Dec 17 15:08:28 2004
@@ -213,12 +213,19 @@ free_client(struct nfs4_client *clp)
 	kfree(clp);
 }
 
+void
+put_nfs4_client(struct nfs4_client *clp)
+{
+	if (atomic_dec_and_test(&clp->cl_count))
+		free_client(clp);
+}
+
 static void
 expire_client(struct nfs4_client *clp)
 {
 	struct nfs4_stateowner *sop;
 
-	dprintk("NFSD: expire_client\n");
+	dprintk("NFSD: expire_client cl_count %d\n",atomic_read(&clp->cl_count));
 	list_del(&clp->cl_idhash);
 	list_del(&clp->cl_strhash);
 	list_del(&clp->cl_lru);
@@ -226,7 +233,7 @@ expire_client(struct nfs4_client *clp)
 		sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
 		release_stateowner(sop);
 	}
-	free_client(clp);
+	put_nfs4_client(clp);
 }
 
 static struct nfs4_client *
@@ -235,6 +242,9 @@ create_client(struct xdr_netobj name) {
 
 	if (!(clp = alloc_client(name)))
 		goto out;
+	atomic_set(&clp->cl_count, 1);
+	atomic_set(&clp->cl_callback.cb_set, 0);
+	clp->cl_callback.cb_parsed = 0;
 	INIT_LIST_HEAD(&clp->cl_idhash);
 	INIT_LIST_HEAD(&clp->cl_strhash);
 	INIT_LIST_HEAD(&clp->cl_perclient);
diff -puN include/linux/nfsd/state.h~knfsd-count-the-nfs4_client-structure-usage include/linux/nfsd/state.h
--- 25/include/linux/nfsd/state.h~knfsd-count-the-nfs4_client-structure-usage	Fri Dec 17 15:08:28 2004
+++ 25-akpm/include/linux/nfsd/state.h	Fri Dec 17 15:08:28 2004
@@ -76,7 +76,7 @@ struct nfs4_callback {
 	u32                     cb_prog;
 	u32                     cb_ident;
 	/* RPC client info */
-	u32			cb_set;     /* successful CB_NULL call */
+	atomic_t		cb_set;     /* successful CB_NULL call */
 	struct rpc_program      cb_program;
 	struct rpc_stat         cb_stat;
 	struct rpc_clnt *       cb_client;
@@ -106,6 +106,7 @@ struct nfs4_client {
 	nfs4_verifier		cl_confirm;	/* generated by server */
 	struct nfs4_callback	cl_callback;    /* callback info */
 	time_t			cl_first_state; /* first state aquisition*/
+	atomic_t		cl_count;	/* ref count */
 };
 
 /* struct nfs4_client_reset
@@ -250,6 +251,7 @@ extern void nfs4_lock_state(void);
 extern void nfs4_unlock_state(void);
 extern int nfs4_in_grace(void);
 extern int nfs4_check_open_reclaim(clientid_t *clid);
+extern void put_nfs4_client(struct nfs4_client *clp);
 extern void nfs4_free_stateowner(struct kref *kref);
 
 static inline void
_