diff options
-rw-r--r-- | fs/nfsd/nfs4callback.c | 66 |
1 files changed, 27 insertions, 39 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 54b37b1d2e3a..8583d99ee740 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -375,16 +375,28 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
375 | { | 375 | { |
376 | struct sockaddr_in addr; | 376 | struct sockaddr_in addr; |
377 | struct nfs4_callback *cb = &clp->cl_callback; | 377 | struct nfs4_callback *cb = &clp->cl_callback; |
378 | struct rpc_timeout timeparms; | 378 | struct rpc_timeout timeparms = { |
379 | struct rpc_xprt * xprt; | 379 | .to_initval = (NFSD_LEASE_TIME/4) * HZ, |
380 | .to_retries = 5, | ||
381 | .to_maxval = (NFSD_LEASE_TIME/2) * HZ, | ||
382 | .to_exponential = 1, | ||
383 | }; | ||
380 | struct rpc_program * program = &cb->cb_program; | 384 | struct rpc_program * program = &cb->cb_program; |
381 | struct rpc_stat * stat = &cb->cb_stat; | 385 | struct rpc_create_args args = { |
382 | struct rpc_clnt * clnt; | 386 | .protocol = IPPROTO_TCP, |
387 | .address = (struct sockaddr *)&addr, | ||
388 | .addrsize = sizeof(addr), | ||
389 | .timeout = &timeparms, | ||
390 | .servername = clp->cl_name.data, | ||
391 | .program = program, | ||
392 | .version = nfs_cb_version[1]->number, | ||
393 | .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ | ||
394 | .flags = (RPC_CLNT_CREATE_NOPING), | ||
395 | }; | ||
383 | struct rpc_message msg = { | 396 | struct rpc_message msg = { |
384 | .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], | 397 | .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], |
385 | .rpc_argp = clp, | 398 | .rpc_argp = clp, |
386 | }; | 399 | }; |
387 | char hostname[32]; | ||
388 | int status; | 400 | int status; |
389 | 401 | ||
390 | if (atomic_read(&cb->cb_set)) | 402 | if (atomic_read(&cb->cb_set)) |
@@ -396,51 +408,27 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
396 | addr.sin_port = htons(cb->cb_port); | 408 | addr.sin_port = htons(cb->cb_port); |
397 | addr.sin_addr.s_addr = htonl(cb->cb_addr); | 409 | addr.sin_addr.s_addr = htonl(cb->cb_addr); |
398 | 410 | ||
399 | /* Initialize timeout */ | ||
400 | timeparms.to_initval = (NFSD_LEASE_TIME/4) * HZ; | ||
401 | timeparms.to_retries = 0; | ||
402 | timeparms.to_maxval = (NFSD_LEASE_TIME/2) * HZ; | ||
403 | timeparms.to_exponential = 1; | ||
404 | |||
405 | /* Create RPC transport */ | ||
406 | xprt = xprt_create_proto(IPPROTO_TCP, &addr, &timeparms); | ||
407 | if (IS_ERR(xprt)) { | ||
408 | dprintk("NFSD: couldn't create callback transport!\n"); | ||
409 | goto out_err; | ||
410 | } | ||
411 | |||
412 | /* Initialize rpc_program */ | 411 | /* Initialize rpc_program */ |
413 | program->name = "nfs4_cb"; | 412 | program->name = "nfs4_cb"; |
414 | program->number = cb->cb_prog; | 413 | program->number = cb->cb_prog; |
415 | program->nrvers = ARRAY_SIZE(nfs_cb_version); | 414 | program->nrvers = ARRAY_SIZE(nfs_cb_version); |
416 | program->version = nfs_cb_version; | 415 | program->version = nfs_cb_version; |
417 | program->stats = stat; | 416 | program->stats = &cb->cb_stat; |
418 | 417 | ||
419 | /* Initialize rpc_stat */ | 418 | /* Initialize rpc_stat */ |
420 | memset(stat, 0, sizeof(struct rpc_stat)); | 419 | memset(program->stats, 0, sizeof(cb->cb_stat)); |
421 | stat->program = program; | 420 | program->stats->program = program; |
422 | 421 | ||
423 | /* Create RPC client | 422 | /* Create RPC client */ |
424 | * | 423 | cb->cb_client = rpc_create(&args); |
425 | * XXX AUTH_UNIX only - need AUTH_GSS.... | 424 | if (!cb->cb_client) { |
426 | */ | ||
427 | sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr)); | ||
428 | clnt = rpc_new_client(xprt, hostname, program, 1, RPC_AUTH_UNIX); | ||
429 | if (IS_ERR(clnt)) { | ||
430 | dprintk("NFSD: couldn't create callback client\n"); | 425 | dprintk("NFSD: couldn't create callback client\n"); |
431 | goto out_err; | 426 | goto out_err; |
432 | } | 427 | } |
433 | clnt->cl_intr = 0; | ||
434 | clnt->cl_softrtry = 1; | ||
435 | 428 | ||
436 | /* Kick rpciod, put the call on the wire. */ | 429 | /* Kick rpciod, put the call on the wire. */ |
437 | 430 | if (rpciod_up() != 0) | |
438 | if (rpciod_up() != 0) { | ||
439 | dprintk("nfsd: couldn't start rpciod for callbacks!\n"); | ||
440 | goto out_clnt; | 431 | goto out_clnt; |
441 | } | ||
442 | |||
443 | cb->cb_client = clnt; | ||
444 | 432 | ||
445 | /* the task holds a reference to the nfs4_client struct */ | 433 | /* the task holds a reference to the nfs4_client struct */ |
446 | atomic_inc(&clp->cl_count); | 434 | atomic_inc(&clp->cl_count); |
@@ -448,7 +436,7 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
448 | msg.rpc_cred = nfsd4_lookupcred(clp,0); | 436 | msg.rpc_cred = nfsd4_lookupcred(clp,0); |
449 | if (IS_ERR(msg.rpc_cred)) | 437 | if (IS_ERR(msg.rpc_cred)) |
450 | goto out_rpciod; | 438 | goto out_rpciod; |
451 | status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, &nfs4_cb_null_ops, NULL); | 439 | status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_ASYNC, &nfs4_cb_null_ops, NULL); |
452 | put_rpccred(msg.rpc_cred); | 440 | put_rpccred(msg.rpc_cred); |
453 | 441 | ||
454 | if (status != 0) { | 442 | if (status != 0) { |
@@ -462,7 +450,7 @@ out_rpciod: | |||
462 | rpciod_down(); | 450 | rpciod_down(); |
463 | cb->cb_client = NULL; | 451 | cb->cb_client = NULL; |
464 | out_clnt: | 452 | out_clnt: |
465 | rpc_shutdown_client(clnt); | 453 | rpc_shutdown_client(cb->cb_client); |
466 | out_err: | 454 | out_err: |
467 | dprintk("NFSD: warning: no callback path to client %.*s\n", | 455 | dprintk("NFSD: warning: no callback path to client %.*s\n", |
468 | (int)clp->cl_name.len, clp->cl_name.data); | 456 | (int)clp->cl_name.len, clp->cl_name.data); |