Commit 1b1a9b31 authored by J. Bruce Fields's avatar J. Bruce Fields

knfsd: don't shutdown callbacks until nfsv4 client is freed

If a callback still holds a reference on the client, then it may be
about to perform an rpc call, so it isn't safe to call rpc_shutdown().
(Though rpc_shutdown() does wait for any outstanding rpc's, it can't
know if a new rpc is about to be issued with that client.)

So, wait to shutdown the rpc_client until the reference count on the
client has gone to zero.
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent 0272e1fd
...@@ -358,9 +358,22 @@ alloc_client(struct xdr_netobj name) ...@@ -358,9 +358,22 @@ alloc_client(struct xdr_netobj name)
return clp; return clp;
} }
static void
shutdown_callback_client(struct nfs4_client *clp)
{
struct rpc_clnt *clnt = clp->cl_callback.cb_client;
/* shutdown rpc client, ending any outstanding recall rpcs */
if (clnt) {
clp->cl_callback.cb_client = NULL;
rpc_shutdown_client(clnt);
}
}
static inline void static inline void
free_client(struct nfs4_client *clp) free_client(struct nfs4_client *clp)
{ {
shutdown_callback_client(clp);
if (clp->cl_cred.cr_group_info) if (clp->cl_cred.cr_group_info)
put_group_info(clp->cl_cred.cr_group_info); put_group_info(clp->cl_cred.cr_group_info);
kfree(clp->cl_name.data); kfree(clp->cl_name.data);
...@@ -374,18 +387,6 @@ put_nfs4_client(struct nfs4_client *clp) ...@@ -374,18 +387,6 @@ put_nfs4_client(struct nfs4_client *clp)
free_client(clp); free_client(clp);
} }
static void
shutdown_callback_client(struct nfs4_client *clp)
{
struct rpc_clnt *clnt = clp->cl_callback.cb_client;
/* shutdown rpc client, ending any outstanding recall rpcs */
if (clnt) {
clp->cl_callback.cb_client = NULL;
rpc_shutdown_client(clnt);
}
}
static void static void
expire_client(struct nfs4_client *clp) expire_client(struct nfs4_client *clp)
{ {
...@@ -396,8 +397,6 @@ expire_client(struct nfs4_client *clp) ...@@ -396,8 +397,6 @@ expire_client(struct nfs4_client *clp)
dprintk("NFSD: expire_client cl_count %d\n", dprintk("NFSD: expire_client cl_count %d\n",
atomic_read(&clp->cl_count)); atomic_read(&clp->cl_count));
shutdown_callback_client(clp);
INIT_LIST_HEAD(&reaplist); INIT_LIST_HEAD(&reaplist);
spin_lock(&recall_lock); spin_lock(&recall_lock);
while (!list_empty(&clp->cl_delegations)) { while (!list_empty(&clp->cl_delegations)) {
......
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