mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
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: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
parent
0272e1fd9f
commit
1b1a9b3163
@ -358,9 +358,22 @@ alloc_client(struct xdr_netobj name)
|
||||
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
|
||||
free_client(struct nfs4_client *clp)
|
||||
{
|
||||
shutdown_callback_client(clp);
|
||||
if (clp->cl_cred.cr_group_info)
|
||||
put_group_info(clp->cl_cred.cr_group_info);
|
||||
kfree(clp->cl_name.data);
|
||||
@ -374,18 +387,6 @@ put_nfs4_client(struct nfs4_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
|
||||
expire_client(struct nfs4_client *clp)
|
||||
{
|
||||
@ -396,8 +397,6 @@ expire_client(struct nfs4_client *clp)
|
||||
dprintk("NFSD: expire_client cl_count %d\n",
|
||||
atomic_read(&clp->cl_count));
|
||||
|
||||
shutdown_callback_client(clp);
|
||||
|
||||
INIT_LIST_HEAD(&reaplist);
|
||||
spin_lock(&recall_lock);
|
||||
while (!list_empty(&clp->cl_delegations)) {
|
||||
|
Loading…
Reference in New Issue
Block a user