aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2005-01-04 05:48:20 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-04 05:48:20 -0800
commit83107cd7f181f40b0314937238eb633b59061466 (patch)
tree06a2bc690d45f272559a5b775ff3027cd52dafb9 /fs
parentfb6f151075c112daf30a2dcccd91999bff5dd034 (diff)
downloadhistory-83107cd7f181f40b0314937238eb633b59061466.tar.gz
[PATCH] knfsd: count the nfs4_client structure usage
... 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> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4state.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 8cd8199493ecc6..d363539f1b8fae 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -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);