Commit 83107cd7 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[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: default avatarAndy Adamson <andros@citi.umich.edu>
Signed-off-by: default avatarNeil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent fb6f1510
...@@ -213,12 +213,19 @@ free_client(struct nfs4_client *clp) ...@@ -213,12 +213,19 @@ free_client(struct nfs4_client *clp)
kfree(clp); kfree(clp);
} }
void
put_nfs4_client(struct nfs4_client *clp)
{
if (atomic_dec_and_test(&clp->cl_count))
free_client(clp);
}
static void static void
expire_client(struct nfs4_client *clp) expire_client(struct nfs4_client *clp)
{ {
struct nfs4_stateowner *sop; 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_idhash);
list_del(&clp->cl_strhash); list_del(&clp->cl_strhash);
list_del(&clp->cl_lru); list_del(&clp->cl_lru);
...@@ -226,7 +233,7 @@ expire_client(struct nfs4_client *clp) ...@@ -226,7 +233,7 @@ expire_client(struct nfs4_client *clp)
sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient); sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
release_stateowner(sop); release_stateowner(sop);
} }
free_client(clp); put_nfs4_client(clp);
} }
static struct nfs4_client * static struct nfs4_client *
...@@ -235,6 +242,9 @@ create_client(struct xdr_netobj name) { ...@@ -235,6 +242,9 @@ create_client(struct xdr_netobj name) {
if (!(clp = alloc_client(name))) if (!(clp = alloc_client(name)))
goto out; 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_idhash);
INIT_LIST_HEAD(&clp->cl_strhash); INIT_LIST_HEAD(&clp->cl_strhash);
INIT_LIST_HEAD(&clp->cl_perclient); INIT_LIST_HEAD(&clp->cl_perclient);
......
...@@ -76,7 +76,7 @@ struct nfs4_callback { ...@@ -76,7 +76,7 @@ struct nfs4_callback {
u32 cb_prog; u32 cb_prog;
u32 cb_ident; u32 cb_ident;
/* RPC client info */ /* 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_program cb_program;
struct rpc_stat cb_stat; struct rpc_stat cb_stat;
struct rpc_clnt * cb_client; struct rpc_clnt * cb_client;
...@@ -106,6 +106,7 @@ struct nfs4_client { ...@@ -106,6 +106,7 @@ struct nfs4_client {
nfs4_verifier cl_confirm; /* generated by server */ nfs4_verifier cl_confirm; /* generated by server */
struct nfs4_callback cl_callback; /* callback info */ struct nfs4_callback cl_callback; /* callback info */
time_t cl_first_state; /* first state aquisition*/ time_t cl_first_state; /* first state aquisition*/
atomic_t cl_count; /* ref count */
}; };
/* struct nfs4_client_reset /* struct nfs4_client_reset
...@@ -250,6 +251,7 @@ extern void nfs4_lock_state(void); ...@@ -250,6 +251,7 @@ extern void nfs4_lock_state(void);
extern void nfs4_unlock_state(void); extern void nfs4_unlock_state(void);
extern int nfs4_in_grace(void); extern int nfs4_in_grace(void);
extern int nfs4_check_open_reclaim(clientid_t *clid); 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); extern void nfs4_free_stateowner(struct kref *kref);
static inline void static inline void
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment