Commit 63c86716 authored by J. Bruce Fields's avatar J. Bruce Fields

nfsd: move callback rpc_client creation into separate thread

The whole reason to move this callback-channel probe into a separate
thread was because (for now) we don't have an easy way to create the
rpc_client asynchronously.  But I forgot to move the rpc_create() to the
spawned thread.  Doh!  Fix that.
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent 46f8a64b
...@@ -350,30 +350,6 @@ static struct rpc_version * nfs_cb_version[] = { ...@@ -350,30 +350,6 @@ static struct rpc_version * nfs_cb_version[] = {
static int do_probe_callback(void *data) static int do_probe_callback(void *data)
{ {
struct nfs4_client *clp = data; struct nfs4_client *clp = data;
struct nfs4_callback *cb = &clp->cl_callback;
struct rpc_message msg = {
.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
.rpc_argp = clp,
};
int status;
status = rpc_call_sync(cb->cb_client, &msg, RPC_TASK_SOFT);
if (status) {
rpc_shutdown_client(cb->cb_client);
cb->cb_client = NULL;
} else
atomic_set(&cb->cb_set, 1);
put_nfs4_client(clp);
return 0;
}
/*
* Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
*/
void
nfsd4_probe_callback(struct nfs4_client *clp)
{
struct sockaddr_in addr; struct sockaddr_in addr;
struct nfs4_callback *cb = &clp->cl_callback; struct nfs4_callback *cb = &clp->cl_callback;
struct rpc_timeout timeparms = { struct rpc_timeout timeparms = {
...@@ -393,9 +369,12 @@ nfsd4_probe_callback(struct nfs4_client *clp) ...@@ -393,9 +369,12 @@ nfsd4_probe_callback(struct nfs4_client *clp)
.authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */
.flags = (RPC_CLNT_CREATE_NOPING), .flags = (RPC_CLNT_CREATE_NOPING),
}; };
struct task_struct *t; struct rpc_message msg = {
.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
BUG_ON(atomic_read(&clp->cl_callback.cb_set)); .rpc_argp = clp,
};
struct rpc_clnt *client;
int status;
/* Initialize address */ /* Initialize address */
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
...@@ -415,29 +394,50 @@ nfsd4_probe_callback(struct nfs4_client *clp) ...@@ -415,29 +394,50 @@ nfsd4_probe_callback(struct nfs4_client *clp)
program->stats->program = program; program->stats->program = program;
/* Create RPC client */ /* Create RPC client */
cb->cb_client = rpc_create(&args); client = rpc_create(&args);
if (IS_ERR(cb->cb_client)) { if (IS_ERR(client)) {
dprintk("NFSD: couldn't create callback client\n"); dprintk("NFSD: couldn't create callback client\n");
status = PTR_ERR(client);
goto out_err; goto out_err;
} }
status = rpc_call_sync(client, &msg, RPC_TASK_SOFT);
if (status)
goto out_release_client;
cb->cb_client = client;
atomic_set(&cb->cb_set, 1);
put_nfs4_client(clp);
return 0;
out_release_client:
rpc_shutdown_client(client);
out_err:
put_nfs4_client(clp);
dprintk("NFSD: warning: no callback path to client %.*s\n",
(int)clp->cl_name.len, clp->cl_name.data);
return status;
}
/*
* Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
*/
void
nfsd4_probe_callback(struct nfs4_client *clp)
{
struct task_struct *t;
BUG_ON(atomic_read(&clp->cl_callback.cb_set));
/* the task holds a reference to the nfs4_client struct */ /* the task holds a reference to the nfs4_client struct */
atomic_inc(&clp->cl_count); atomic_inc(&clp->cl_count);
t = kthread_run(do_probe_callback, clp, "nfs4_cb_probe"); t = kthread_run(do_probe_callback, clp, "nfs4_cb_probe");
if (IS_ERR(t)) if (IS_ERR(t))
goto out_release_clp; atomic_dec(&clp->cl_count);
return; return;
out_release_clp:
atomic_dec(&clp->cl_count);
rpc_shutdown_client(cb->cb_client);
out_err:
cb->cb_client = NULL;
dprintk("NFSD: warning: no callback path to client %.*s\n",
(int)clp->cl_name.len, clp->cl_name.data);
} }
/* /*
......
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