Commit c8475461 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust

SUNRPC: Move rpc_xprt socket connect fields into private data structure

Move the socket-specific connection management fields out of the generic
rpc_xprt structure into a private data structure maintained in
net/sunrpc/xprtsock.c.
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent e136d092
...@@ -163,8 +163,6 @@ struct rpc_xprt { ...@@ -163,8 +163,6 @@ struct rpc_xprt {
unsigned long connect_timeout, unsigned long connect_timeout,
bind_timeout, bind_timeout,
reestablish_timeout; reestablish_timeout;
struct work_struct connect_worker;
unsigned short port;
/* /*
* Disconnection of idle transports * Disconnection of idle transports
......
...@@ -145,6 +145,12 @@ struct sock_xprt { ...@@ -145,6 +145,12 @@ struct sock_xprt {
unsigned long tcp_copied, unsigned long tcp_copied,
tcp_flags; tcp_flags;
/*
* Connection of transports
*/
struct work_struct connect_worker;
unsigned short port;
}; };
/* /*
...@@ -545,9 +551,11 @@ clear_close_wait: ...@@ -545,9 +551,11 @@ clear_close_wait:
*/ */
static void xs_destroy(struct rpc_xprt *xprt) static void xs_destroy(struct rpc_xprt *xprt)
{ {
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
dprintk("RPC: xs_destroy xprt %p\n", xprt); dprintk("RPC: xs_destroy xprt %p\n", xprt);
cancel_delayed_work(&xprt->connect_worker); cancel_delayed_work(&transport->connect_worker);
flush_scheduled_work(); flush_scheduled_work();
xprt_disconnect(xprt); xprt_disconnect(xprt);
...@@ -1065,20 +1073,20 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) ...@@ -1065,20 +1073,20 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
sap->sin_port = htons(port); sap->sin_port = htons(port);
} }
static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) static int xs_bindresvport(struct sock_xprt *transport, struct socket *sock)
{ {
struct sockaddr_in myaddr = { struct sockaddr_in myaddr = {
.sin_family = AF_INET, .sin_family = AF_INET,
}; };
int err; int err;
unsigned short port = xprt->port; unsigned short port = transport->port;
do { do {
myaddr.sin_port = htons(port); myaddr.sin_port = htons(port);
err = kernel_bind(sock, (struct sockaddr *) &myaddr, err = kernel_bind(sock, (struct sockaddr *) &myaddr,
sizeof(myaddr)); sizeof(myaddr));
if (err == 0) { if (err == 0) {
xprt->port = port; transport->port = port;
dprintk("RPC: xs_bindresvport bound to port %u\n", dprintk("RPC: xs_bindresvport bound to port %u\n",
port); port);
return 0; return 0;
...@@ -1087,7 +1095,7 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) ...@@ -1087,7 +1095,7 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
port = xprt_max_resvport; port = xprt_max_resvport;
else else
port--; port--;
} while (err == -EADDRINUSE && port != xprt->port); } while (err == -EADDRINUSE && port != transport->port);
dprintk("RPC: can't bind to reserved port (%d).\n", -err); dprintk("RPC: can't bind to reserved port (%d).\n", -err);
return err; return err;
...@@ -1101,8 +1109,8 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) ...@@ -1101,8 +1109,8 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
*/ */
static void xs_udp_connect_worker(void *args) static void xs_udp_connect_worker(void *args)
{ {
struct rpc_xprt *xprt = (struct rpc_xprt *) args; struct sock_xprt *transport = (struct sock_xprt *)args;
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); struct rpc_xprt *xprt = &transport->xprt;
struct socket *sock = transport->sock; struct socket *sock = transport->sock;
int err, status = -EIO; int err, status = -EIO;
...@@ -1117,7 +1125,7 @@ static void xs_udp_connect_worker(void *args) ...@@ -1117,7 +1125,7 @@ static void xs_udp_connect_worker(void *args)
goto out; goto out;
} }
if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) { if (xprt->resvport && xs_bindresvport(transport, sock) < 0) {
sock_release(sock); sock_release(sock);
goto out; goto out;
} }
...@@ -1186,8 +1194,8 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt) ...@@ -1186,8 +1194,8 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
*/ */
static void xs_tcp_connect_worker(void *args) static void xs_tcp_connect_worker(void *args)
{ {
struct rpc_xprt *xprt = (struct rpc_xprt *)args; struct sock_xprt *transport = (struct sock_xprt *)args;
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); struct rpc_xprt *xprt = &transport->xprt;
struct socket *sock = transport->sock; struct socket *sock = transport->sock;
int err, status = -EIO; int err, status = -EIO;
...@@ -1201,7 +1209,7 @@ static void xs_tcp_connect_worker(void *args) ...@@ -1201,7 +1209,7 @@ static void xs_tcp_connect_worker(void *args)
goto out; goto out;
} }
if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) { if (xprt->resvport && xs_bindresvport(transport, sock) < 0) {
sock_release(sock); sock_release(sock);
goto out; goto out;
} }
...@@ -1293,14 +1301,14 @@ static void xs_connect(struct rpc_task *task) ...@@ -1293,14 +1301,14 @@ static void xs_connect(struct rpc_task *task)
if (transport->sock != NULL) { if (transport->sock != NULL) {
dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n", dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n",
xprt, xprt->reestablish_timeout / HZ); xprt, xprt->reestablish_timeout / HZ);
schedule_delayed_work(&xprt->connect_worker, schedule_delayed_work(&transport->connect_worker,
xprt->reestablish_timeout); xprt->reestablish_timeout);
xprt->reestablish_timeout <<= 1; xprt->reestablish_timeout <<= 1;
if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
} else { } else {
dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
schedule_work(&xprt->connect_worker); schedule_work(&transport->connect_worker);
/* flush_scheduled_work can sleep... */ /* flush_scheduled_work can sleep... */
if (!RPC_IS_ASYNC(task)) if (!RPC_IS_ASYNC(task))
...@@ -1316,8 +1324,10 @@ static void xs_connect(struct rpc_task *task) ...@@ -1316,8 +1324,10 @@ static void xs_connect(struct rpc_task *task)
*/ */
static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
{ {
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n", seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n",
xprt->port, transport->port,
xprt->stat.bind_count, xprt->stat.bind_count,
xprt->stat.sends, xprt->stat.sends,
xprt->stat.recvs, xprt->stat.recvs,
...@@ -1334,13 +1344,14 @@ static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) ...@@ -1334,13 +1344,14 @@ static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
*/ */
static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
{ {
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
long idle_time = 0; long idle_time = 0;
if (xprt_connected(xprt)) if (xprt_connected(xprt))
idle_time = (long)(jiffies - xprt->last_used) / HZ; idle_time = (long)(jiffies - xprt->last_used) / HZ;
seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n", seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n",
xprt->port, transport->port,
xprt->stat.bind_count, xprt->stat.bind_count,
xprt->stat.connect_count, xprt->stat.connect_count,
xprt->stat.connect_time, xprt->stat.connect_time,
...@@ -1414,7 +1425,7 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns ...@@ -1414,7 +1425,7 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns
memcpy(&xprt->addr, addr, addrlen); memcpy(&xprt->addr, addr, addrlen);
xprt->addrlen = addrlen; xprt->addrlen = addrlen;
xprt->port = xs_get_random_port(); new->port = xs_get_random_port();
return xprt; return xprt;
} }
...@@ -1429,10 +1440,12 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns ...@@ -1429,10 +1440,12 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns
struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to) struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
{ {
struct rpc_xprt *xprt; struct rpc_xprt *xprt;
struct sock_xprt *transport;
xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries); xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries);
if (IS_ERR(xprt)) if (IS_ERR(xprt))
return xprt; return xprt;
transport = container_of(xprt, struct sock_xprt, xprt);
if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0) if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
xprt_set_bound(xprt); xprt_set_bound(xprt);
...@@ -1442,7 +1455,7 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_ ...@@ -1442,7 +1455,7 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_
/* XXX: header size can vary due to auth type, IPv6, etc. */ /* XXX: header size can vary due to auth type, IPv6, etc. */
xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt); INIT_WORK(&transport->connect_worker, xs_udp_connect_worker, transport);
xprt->bind_timeout = XS_BIND_TO; xprt->bind_timeout = XS_BIND_TO;
xprt->connect_timeout = XS_UDP_CONN_TO; xprt->connect_timeout = XS_UDP_CONN_TO;
xprt->reestablish_timeout = XS_UDP_REEST_TO; xprt->reestablish_timeout = XS_UDP_REEST_TO;
...@@ -1472,10 +1485,12 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_ ...@@ -1472,10 +1485,12 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_
struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to) struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
{ {
struct rpc_xprt *xprt; struct rpc_xprt *xprt;
struct sock_xprt *transport;
xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries); xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries);
if (IS_ERR(xprt)) if (IS_ERR(xprt))
return xprt; return xprt;
transport = container_of(xprt, struct sock_xprt, xprt);
if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0) if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
xprt_set_bound(xprt); xprt_set_bound(xprt);
...@@ -1484,7 +1499,7 @@ struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_ ...@@ -1484,7 +1499,7 @@ struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_
xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); INIT_WORK(&transport->connect_worker, xs_tcp_connect_worker, transport);
xprt->bind_timeout = XS_BIND_TO; xprt->bind_timeout = XS_BIND_TO;
xprt->connect_timeout = XS_TCP_CONN_TO; xprt->connect_timeout = XS_TCP_CONN_TO;
xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; xprt->reestablish_timeout = XS_TCP_INIT_REEST_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