aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4callback.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4callback.c')
-rw-r--r--fs/nfsd/nfs4callback.c68
1 files changed, 28 insertions, 40 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 54b37b1d2e3a..f6ca9fb3fc63 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -131,7 +131,7 @@ xdr_error: \
131#define READ_BUF(nbytes) do { \ 131#define READ_BUF(nbytes) do { \
132 p = xdr_inline_decode(xdr, nbytes); \ 132 p = xdr_inline_decode(xdr, nbytes); \
133 if (!p) { \ 133 if (!p) { \
134 dprintk("NFSD: %s: reply buffer overflowed in line %d.", \ 134 dprintk("NFSD: %s: reply buffer overflowed in line %d.\n", \
135 __FUNCTION__, __LINE__); \ 135 __FUNCTION__, __LINE__); \
136 return -EIO; \ 136 return -EIO; \
137 } \ 137 } \
@@ -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;
464out_clnt: 452out_clnt:
465 rpc_shutdown_client(clnt); 453 rpc_shutdown_client(cb->cb_client);
466out_err: 454out_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);