Commit 1e04f496 authored by Chuck Lever's avatar Chuck Lever Committed by Linus Torvalds

[PATCH] (2/2) clean up RPC over TCP transport socket connect

This renames *reconn* to *conn* since the same code now handles both
initial TCP connect, and TCP reconnection, and corrects some comments.
against 2.5.36, requires earlier patch (1/1).
parent be83269e
...@@ -190,7 +190,7 @@ void xprt_transmit(struct rpc_task *); ...@@ -190,7 +190,7 @@ void xprt_transmit(struct rpc_task *);
void xprt_receive(struct rpc_task *); void xprt_receive(struct rpc_task *);
int xprt_adjust_timeout(struct rpc_timeout *); int xprt_adjust_timeout(struct rpc_timeout *);
void xprt_release(struct rpc_task *); void xprt_release(struct rpc_task *);
void xprt_reconnect(struct rpc_task *); void xprt_connect(struct rpc_task *);
int xprt_clear_backlog(struct rpc_xprt *); int xprt_clear_backlog(struct rpc_xprt *);
void xprt_sock_setbufsize(struct rpc_xprt *); void xprt_sock_setbufsize(struct rpc_xprt *);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* - RPC header generation and argument serialization. * - RPC header generation and argument serialization.
* - Credential refresh. * - Credential refresh.
* - TCP reconnect handling (when finished). * - TCP connect handling.
* - Retry of operation when it is suspected the operation failed because * - Retry of operation when it is suspected the operation failed because
* of uid squashing on the server, or when the credentials were stale * of uid squashing on the server, or when the credentials were stale
* and need to be refreshed, or when a packet was damaged in transit. * and need to be refreshed, or when a packet was damaged in transit.
...@@ -55,9 +55,9 @@ static void call_status(struct rpc_task *task); ...@@ -55,9 +55,9 @@ static void call_status(struct rpc_task *task);
static void call_refresh(struct rpc_task *task); static void call_refresh(struct rpc_task *task);
static void call_refreshresult(struct rpc_task *task); static void call_refreshresult(struct rpc_task *task);
static void call_timeout(struct rpc_task *task); static void call_timeout(struct rpc_task *task);
static void call_reconnect(struct rpc_task *task); static void call_connect(struct rpc_task *task);
static void child_reconnect(struct rpc_task *); static void child_connect(struct rpc_task *task);
static void child_reconnect_status(struct rpc_task *); static void child_connect_status(struct rpc_task *task);
static u32 * call_header(struct rpc_task *task); static u32 * call_header(struct rpc_task *task);
static u32 * call_verify(struct rpc_task *task); static u32 * call_verify(struct rpc_task *task);
...@@ -561,51 +561,54 @@ call_bind(struct rpc_task *task) ...@@ -561,51 +561,54 @@ call_bind(struct rpc_task *task)
dprintk("RPC: %4d call_bind xprt %p %s connected\n", task->tk_pid, dprintk("RPC: %4d call_bind xprt %p %s connected\n", task->tk_pid,
xprt, (xprt_connected(xprt) ? "is" : "is not")); xprt, (xprt_connected(xprt) ? "is" : "is not"));
task->tk_action = (xprt_connected(xprt)) ? call_transmit : call_reconnect; task->tk_action = (xprt_connected(xprt)) ? call_transmit : call_connect;
if (!clnt->cl_port) { if (!clnt->cl_port) {
task->tk_action = call_reconnect; task->tk_action = call_connect;
task->tk_timeout = RPC_CONNECT_TIMEOUT; task->tk_timeout = RPC_CONNECT_TIMEOUT;
rpc_getport(task, clnt); rpc_getport(task, clnt);
} }
} }
/* /*
* 4a. Reconnect to the RPC server (TCP case) * 4a. Connect to the RPC server (TCP case)
*/ */
static void static void
call_reconnect(struct rpc_task *task) call_connect(struct rpc_task *task)
{ {
struct rpc_clnt *clnt = task->tk_client; struct rpc_clnt *clnt = task->tk_client;
struct rpc_task *child; struct rpc_task *child;
dprintk("RPC: %4d call_reconnect status %d\n", dprintk("RPC: %4d call_connect status %d\n",
task->tk_pid, task->tk_status); task->tk_pid, task->tk_status);
task->tk_action = call_transmit; task->tk_action = call_transmit;
if (task->tk_status < 0 || !clnt->cl_xprt->stream) if (task->tk_status < 0 || !clnt->cl_xprt->stream)
return; return;
/* Run as a child to ensure it runs as an rpciod task */ /* Run as a child to ensure it runs as an rpciod task. Rpciod
* guarantees we have the correct capabilities for socket bind
* to succeed. */
child = rpc_new_child(clnt, task); child = rpc_new_child(clnt, task);
if (child) { if (child) {
child->tk_action = child_reconnect; child->tk_action = child_connect;
rpc_run_child(task, child, NULL); rpc_run_child(task, child, NULL);
} }
} }
static void child_reconnect(struct rpc_task *task) static void
child_connect(struct rpc_task *task)
{ {
task->tk_client->cl_stats->netreconn++;
task->tk_status = 0; task->tk_status = 0;
task->tk_action = child_reconnect_status; task->tk_action = child_connect_status;
xprt_reconnect(task); xprt_connect(task);
} }
static void child_reconnect_status(struct rpc_task *task) static void
child_connect_status(struct rpc_task *task)
{ {
if (task->tk_status == -EAGAIN) if (task->tk_status == -EAGAIN)
task->tk_action = child_reconnect; task->tk_action = child_connect;
else else
task->tk_action = NULL; task->tk_action = NULL;
} }
......
...@@ -86,7 +86,7 @@ static void xprt_request_init(struct rpc_task *, struct rpc_xprt *); ...@@ -86,7 +86,7 @@ static void xprt_request_init(struct rpc_task *, struct rpc_xprt *);
static void do_xprt_transmit(struct rpc_task *); static void do_xprt_transmit(struct rpc_task *);
static inline void do_xprt_reserve(struct rpc_task *); static inline void do_xprt_reserve(struct rpc_task *);
static void xprt_disconnect(struct rpc_xprt *); static void xprt_disconnect(struct rpc_xprt *);
static void xprt_reconn_status(struct rpc_task *task); static void xprt_conn_status(struct rpc_task *task);
static struct rpc_xprt * xprt_setup(int proto, struct sockaddr_in *ap, static struct rpc_xprt * xprt_setup(int proto, struct sockaddr_in *ap,
struct rpc_timeout *to); struct rpc_timeout *to);
static struct socket *xprt_create_socket(int, struct rpc_timeout *); static struct socket *xprt_create_socket(int, struct rpc_timeout *);
...@@ -136,7 +136,7 @@ xprt_from_sock(struct sock *sk) ...@@ -136,7 +136,7 @@ xprt_from_sock(struct sock *sk)
/* /*
* Serialize write access to sockets, in order to prevent different * Serialize write access to sockets, in order to prevent different
* requests from interfering with each other. * requests from interfering with each other.
* Also prevents TCP socket reconnections from colliding with writes. * Also prevents TCP socket connects from colliding with writes.
*/ */
static int static int
__xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task) __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
...@@ -409,19 +409,19 @@ xprt_disconnect(struct rpc_xprt *xprt) ...@@ -409,19 +409,19 @@ xprt_disconnect(struct rpc_xprt *xprt)
} }
/* /*
* Reconnect a broken TCP connection. * Attempt to connect a TCP socket.
* *
* Note: This cannot collide with the TCP reads, as both run from rpciod * NB: This never collides with TCP reads, as both run from rpciod
*/ */
void void
xprt_reconnect(struct rpc_task *task) xprt_connect(struct rpc_task *task)
{ {
struct rpc_xprt *xprt = task->tk_xprt; struct rpc_xprt *xprt = task->tk_xprt;
struct socket *sock = xprt->sock; struct socket *sock = xprt->sock;
struct sock *inet; struct sock *inet;
int status; int status;
dprintk("RPC: %4d xprt_reconnect xprt %p %s connected\n", task->tk_pid, dprintk("RPC: %4d xprt_connect xprt %p %s connected\n", task->tk_pid,
xprt, (xprt_connected(xprt) ? "is" : "is not")); xprt, (xprt_connected(xprt) ? "is" : "is not"));
if (xprt->shutdown) { if (xprt->shutdown) {
...@@ -471,7 +471,7 @@ xprt_reconnect(struct rpc_task *task) ...@@ -471,7 +471,7 @@ xprt_reconnect(struct rpc_task *task)
/* if the socket is already closing, delay briefly */ /* if the socket is already closing, delay briefly */
if ((1 << inet->state) & ~(TCPF_SYN_SENT|TCPF_SYN_RECV)) if ((1 << inet->state) & ~(TCPF_SYN_SENT|TCPF_SYN_RECV))
task->tk_timeout = RPC_REESTABLISH_TIMEOUT; task->tk_timeout = RPC_REESTABLISH_TIMEOUT;
rpc_sleep_on(&xprt->pending, task, xprt_reconn_status, rpc_sleep_on(&xprt->pending, task, xprt_conn_status,
NULL); NULL);
release_sock(inet); release_sock(inet);
/* task status set when task wakes up again */ /* task status set when task wakes up again */
...@@ -523,21 +523,20 @@ xprt_reconnect(struct rpc_task *task) ...@@ -523,21 +523,20 @@ xprt_reconnect(struct rpc_task *task)
} }
/* /*
* Reconnect timeout. We just mark the transport as not being in the * We arrive here when awoken from waiting on connection establishment.
* process of reconnecting, and leave the rest to the upper layers.
*/ */
static void static void
xprt_reconn_status(struct rpc_task *task) xprt_conn_status(struct rpc_task *task)
{ {
struct rpc_xprt *xprt = task->tk_xprt; struct rpc_xprt *xprt = task->tk_xprt;
switch (task->tk_status) { switch (task->tk_status) {
case 0: case 0:
dprintk("RPC: %4d xprt_reconn_status: connection established\n", dprintk("RPC: %4d xprt_conn_status: connection established\n",
task->tk_pid); task->tk_pid);
goto out; goto out;
case -ETIMEDOUT: case -ETIMEDOUT:
dprintk("RPC: %4d xprt_reconn_status: timed out\n", dprintk("RPC: %4d xprt_conn_status: timed out\n",
task->tk_pid); task->tk_pid);
/* prevent TCP from continuing to retry SYNs */ /* prevent TCP from continuing to retry SYNs */
xprt_close(xprt); xprt_close(xprt);
...@@ -1487,7 +1486,8 @@ xprt_sock_setbufsize(struct rpc_xprt *xprt) ...@@ -1487,7 +1486,8 @@ xprt_sock_setbufsize(struct rpc_xprt *xprt)
} }
/* /*
* Create a client socket given the protocol and peer address. * Datastream sockets are created here, but xprt_connect will create
* and connect stream sockets.
*/ */
static struct socket * static struct socket *
xprt_create_socket(int proto, struct rpc_timeout *to) xprt_create_socket(int proto, struct rpc_timeout *to)
......
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