diff options
author | Chuck Lever <cel@netapp.com> | 2006-01-03 03:55:50 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-06 14:58:56 -0500 |
commit | 35f5a422ce1af836007f811b613c440d0e348e06 (patch) | |
tree | 25aac5cccce27a6ed5ebb4e161f813af2adbaf56 /net/sunrpc/clnt.c | |
parent | 02107148349f31eee7c0fb06fd7a880df73dbd20 (diff) |
SUNRPC: new interface to force an RPC rebind
We'd like to hide fields in rpc_xprt and rpc_clnt from upper layer protocols.
Start by creating an API to force RPC rebind, replacing logic that simply
sets cl_port to zero.
Test-plan:
Destructive testing (unplugging the network temporarily). Connectathon
with UDP and TCP. NFSv2/3 and NFSv4 mounting should be carefully checked.
Probably need to rig a server where certain services aren't running, or
that returns an error for some typical operation.
Signed-off-by: Chuck Lever <cel@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r-- | net/sunrpc/clnt.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 25cba94c5683..2789d3083fe7 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -538,6 +538,18 @@ size_t rpc_max_payload(struct rpc_clnt *clnt) | |||
538 | } | 538 | } |
539 | EXPORT_SYMBOL(rpc_max_payload); | 539 | EXPORT_SYMBOL(rpc_max_payload); |
540 | 540 | ||
541 | /** | ||
542 | * rpc_force_rebind - force transport to check that remote port is unchanged | ||
543 | * @clnt: client to rebind | ||
544 | * | ||
545 | */ | ||
546 | void rpc_force_rebind(struct rpc_clnt *clnt) | ||
547 | { | ||
548 | if (clnt->cl_autobind) | ||
549 | clnt->cl_port = 0; | ||
550 | } | ||
551 | EXPORT_SYMBOL(rpc_force_rebind); | ||
552 | |||
541 | /* | 553 | /* |
542 | * Restart an (async) RPC call. Usually called from within the | 554 | * Restart an (async) RPC call. Usually called from within the |
543 | * exit handler. | 555 | * exit handler. |
@@ -853,8 +865,7 @@ call_connect_status(struct rpc_task *task) | |||
853 | } | 865 | } |
854 | 866 | ||
855 | /* Something failed: remote service port may have changed */ | 867 | /* Something failed: remote service port may have changed */ |
856 | if (clnt->cl_autobind) | 868 | rpc_force_rebind(clnt); |
857 | clnt->cl_port = 0; | ||
858 | 869 | ||
859 | switch (status) { | 870 | switch (status) { |
860 | case -ENOTCONN: | 871 | case -ENOTCONN: |
@@ -935,8 +946,7 @@ call_status(struct rpc_task *task) | |||
935 | break; | 946 | break; |
936 | case -ECONNREFUSED: | 947 | case -ECONNREFUSED: |
937 | case -ENOTCONN: | 948 | case -ENOTCONN: |
938 | if (clnt->cl_autobind) | 949 | rpc_force_rebind(clnt); |
939 | clnt->cl_port = 0; | ||
940 | task->tk_action = call_bind; | 950 | task->tk_action = call_bind; |
941 | break; | 951 | break; |
942 | case -EAGAIN: | 952 | case -EAGAIN: |
@@ -995,8 +1005,7 @@ call_timeout(struct rpc_task *task) | |||
995 | printk(KERN_NOTICE "%s: server %s not responding, still trying\n", | 1005 | printk(KERN_NOTICE "%s: server %s not responding, still trying\n", |
996 | clnt->cl_protname, clnt->cl_server); | 1006 | clnt->cl_protname, clnt->cl_server); |
997 | } | 1007 | } |
998 | if (clnt->cl_autobind) | 1008 | rpc_force_rebind(clnt); |
999 | clnt->cl_port = 0; | ||
1000 | 1009 | ||
1001 | retry: | 1010 | retry: |
1002 | clnt->cl_stats->rpcretrans++; | 1011 | clnt->cl_stats->rpcretrans++; |