diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2007-10-25 19:00:26 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2008-02-01 16:42:01 -0500 |
commit | 63c86716ea34ad94d52e5b0abbda152574dc42b5 (patch) | |
tree | c92ceed9f40f43dc79e099a1f3d4da99d6f985b6 /fs/nfsd | |
parent | 46f8a64bae11f5c9b15b4401f6e9863281999b66 (diff) |
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: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4callback.c | 78 |
1 files changed, 39 insertions, 39 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index a9735a672963..6eb5cd2381ab 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -350,30 +350,6 @@ static struct rpc_version * nfs_cb_version[] = { | |||
350 | static int do_probe_callback(void *data) | 350 | static int do_probe_callback(void *data) |
351 | { | 351 | { |
352 | struct nfs4_client *clp = data; | 352 | struct nfs4_client *clp = data; |
353 | struct nfs4_callback *cb = &clp->cl_callback; | ||
354 | struct rpc_message msg = { | ||
355 | .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], | ||
356 | .rpc_argp = clp, | ||
357 | }; | ||
358 | int status; | ||
359 | |||
360 | status = rpc_call_sync(cb->cb_client, &msg, RPC_TASK_SOFT); | ||
361 | |||
362 | if (status) { | ||
363 | rpc_shutdown_client(cb->cb_client); | ||
364 | cb->cb_client = NULL; | ||
365 | } else | ||
366 | atomic_set(&cb->cb_set, 1); | ||
367 | put_nfs4_client(clp); | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * Set up the callback client and put a NFSPROC4_CB_NULL on the wire... | ||
373 | */ | ||
374 | void | ||
375 | nfsd4_probe_callback(struct nfs4_client *clp) | ||
376 | { | ||
377 | struct sockaddr_in addr; | 353 | struct sockaddr_in addr; |
378 | struct nfs4_callback *cb = &clp->cl_callback; | 354 | struct nfs4_callback *cb = &clp->cl_callback; |
379 | struct rpc_timeout timeparms = { | 355 | struct rpc_timeout timeparms = { |
@@ -390,12 +366,15 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
390 | .timeout = &timeparms, | 366 | .timeout = &timeparms, |
391 | .program = program, | 367 | .program = program, |
392 | .version = nfs_cb_version[1]->number, | 368 | .version = nfs_cb_version[1]->number, |
393 | .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ | 369 | .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ |
394 | .flags = (RPC_CLNT_CREATE_NOPING), | 370 | .flags = (RPC_CLNT_CREATE_NOPING), |
395 | }; | 371 | }; |
396 | struct task_struct *t; | 372 | struct rpc_message msg = { |
397 | 373 | .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], | |
398 | BUG_ON(atomic_read(&clp->cl_callback.cb_set)); | 374 | .rpc_argp = clp, |
375 | }; | ||
376 | struct rpc_clnt *client; | ||
377 | int status; | ||
399 | 378 | ||
400 | /* Initialize address */ | 379 | /* Initialize address */ |
401 | memset(&addr, 0, sizeof(addr)); | 380 | memset(&addr, 0, sizeof(addr)); |
@@ -415,29 +394,50 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
415 | program->stats->program = program; | 394 | program->stats->program = program; |
416 | 395 | ||
417 | /* Create RPC client */ | 396 | /* Create RPC client */ |
418 | cb->cb_client = rpc_create(&args); | 397 | client = rpc_create(&args); |
419 | if (IS_ERR(cb->cb_client)) { | 398 | if (IS_ERR(client)) { |
420 | dprintk("NFSD: couldn't create callback client\n"); | 399 | dprintk("NFSD: couldn't create callback client\n"); |
400 | status = PTR_ERR(client); | ||
421 | goto out_err; | 401 | goto out_err; |
422 | } | 402 | } |
423 | 403 | ||
404 | status = rpc_call_sync(client, &msg, RPC_TASK_SOFT); | ||
405 | |||
406 | if (status) | ||
407 | goto out_release_client; | ||
408 | |||
409 | cb->cb_client = client; | ||
410 | atomic_set(&cb->cb_set, 1); | ||
411 | put_nfs4_client(clp); | ||
412 | return 0; | ||
413 | out_release_client: | ||
414 | rpc_shutdown_client(client); | ||
415 | out_err: | ||
416 | put_nfs4_client(clp); | ||
417 | dprintk("NFSD: warning: no callback path to client %.*s\n", | ||
418 | (int)clp->cl_name.len, clp->cl_name.data); | ||
419 | return status; | ||
420 | } | ||
421 | |||
422 | /* | ||
423 | * Set up the callback client and put a NFSPROC4_CB_NULL on the wire... | ||
424 | */ | ||
425 | void | ||
426 | nfsd4_probe_callback(struct nfs4_client *clp) | ||
427 | { | ||
428 | struct task_struct *t; | ||
429 | |||
430 | BUG_ON(atomic_read(&clp->cl_callback.cb_set)); | ||
431 | |||
424 | /* the task holds a reference to the nfs4_client struct */ | 432 | /* the task holds a reference to the nfs4_client struct */ |
425 | atomic_inc(&clp->cl_count); | 433 | atomic_inc(&clp->cl_count); |
426 | 434 | ||
427 | t = kthread_run(do_probe_callback, clp, "nfs4_cb_probe"); | 435 | t = kthread_run(do_probe_callback, clp, "nfs4_cb_probe"); |
428 | 436 | ||
429 | if (IS_ERR(t)) | 437 | if (IS_ERR(t)) |
430 | goto out_release_clp; | 438 | atomic_dec(&clp->cl_count); |
431 | 439 | ||
432 | return; | 440 | return; |
433 | |||
434 | out_release_clp: | ||
435 | atomic_dec(&clp->cl_count); | ||
436 | rpc_shutdown_client(cb->cb_client); | ||
437 | out_err: | ||
438 | cb->cb_client = NULL; | ||
439 | dprintk("NFSD: warning: no callback path to client %.*s\n", | ||
440 | (int)clp->cl_name.len, clp->cl_name.data); | ||
441 | } | 441 | } |
442 | 442 | ||
443 | /* | 443 | /* |