diff options
author | Neil Brown <neilb@cse.unsw.edu.au> | 2005-01-04 05:48:20 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-04 05:48:20 -0800 |
commit | 83107cd7f181f40b0314937238eb633b59061466 (patch) | |
tree | 06a2bc690d45f272559a5b775ff3027cd52dafb9 /fs | |
parent | fb6f151075c112daf30a2dcccd91999bff5dd034 (diff) | |
download | history-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.c | 14 |
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); |