aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprtsock.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2007-08-06 11:57:48 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-10-09 17:16:18 -0400
commit68e220bd5c9fc52d8029275cd42e08f573ce3600 (patch)
tree57ecf6ca21530662ea1a857cd467964f2eaf219e /net/sunrpc/xprtsock.c
parent9c3d72de28eed3e882becd7054da2118f8a73131 (diff)
SUNRPC: create connect workers for IPv6
Clone separate connect worker functions for connecting AF_INET6 sockets. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r--net/sunrpc/xprtsock.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index a0c26b9ebb34..cc4db1763aa4 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1393,6 +1393,47 @@ out:
1393 xprt_clear_connecting(xprt); 1393 xprt_clear_connecting(xprt);
1394} 1394}
1395 1395
1396/**
1397 * xs_udp_connect_worker6 - set up a UDP socket
1398 * @work: RPC transport to connect
1399 *
1400 * Invoked by a work queue tasklet.
1401 */
1402static void xs_udp_connect_worker6(struct work_struct *work)
1403{
1404 struct sock_xprt *transport =
1405 container_of(work, struct sock_xprt, connect_worker.work);
1406 struct rpc_xprt *xprt = &transport->xprt;
1407 struct socket *sock = transport->sock;
1408 int err, status = -EIO;
1409
1410 if (xprt->shutdown || !xprt_bound(xprt))
1411 goto out;
1412
1413 /* Start by resetting any existing state */
1414 xs_close(xprt);
1415
1416 if ((err = sock_create_kern(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
1417 dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
1418 goto out;
1419 }
1420 xs_reclassify_socket(sock);
1421
1422 if (xs_bind6(transport, sock) < 0) {
1423 sock_release(sock);
1424 goto out;
1425 }
1426
1427 dprintk("RPC: worker connecting xprt %p to address: %s\n",
1428 xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
1429
1430 xs_udp_finish_connecting(xprt, sock);
1431 status = 0;
1432out:
1433 xprt_wake_pending_tasks(xprt, status);
1434 xprt_clear_connecting(xprt);
1435}
1436
1396/* 1437/*
1397 * We need to preserve the port number so the reply cache on the server can 1438 * We need to preserve the port number so the reply cache on the server can
1398 * find our cached RPC replies when we get around to reconnecting. 1439 * find our cached RPC replies when we get around to reconnecting.
@@ -1519,6 +1560,66 @@ out_clear:
1519} 1560}
1520 1561
1521/** 1562/**
1563 * xs_tcp_connect_worker6 - connect a TCP socket to a remote endpoint
1564 * @work: RPC transport to connect
1565 *
1566 * Invoked by a work queue tasklet.
1567 */
1568static void xs_tcp_connect_worker6(struct work_struct *work)
1569{
1570 struct sock_xprt *transport =
1571 container_of(work, struct sock_xprt, connect_worker.work);
1572 struct rpc_xprt *xprt = &transport->xprt;
1573 struct socket *sock = transport->sock;
1574 int err, status = -EIO;
1575
1576 if (xprt->shutdown || !xprt_bound(xprt))
1577 goto out;
1578
1579 if (!sock) {
1580 /* start from scratch */
1581 if ((err = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
1582 dprintk("RPC: can't create TCP transport socket (%d).\n", -err);
1583 goto out;
1584 }
1585 xs_reclassify_socket(sock);
1586
1587 if (xs_bind6(transport, sock) < 0) {
1588 sock_release(sock);
1589 goto out;
1590 }
1591 } else
1592 /* "close" the socket, preserving the local port */
1593 xs_tcp_reuse_connection(xprt);
1594
1595 dprintk("RPC: worker connecting xprt %p to address: %s\n",
1596 xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
1597
1598 status = xs_tcp_finish_connecting(xprt, sock);
1599 dprintk("RPC: %p connect status %d connected %d sock state %d\n",
1600 xprt, -status, xprt_connected(xprt), sock->sk->sk_state);
1601 if (status < 0) {
1602 switch (status) {
1603 case -EINPROGRESS:
1604 case -EALREADY:
1605 goto out_clear;
1606 case -ECONNREFUSED:
1607 case -ECONNRESET:
1608 /* retry with existing socket, after a delay */
1609 break;
1610 default:
1611 /* get rid of existing socket, and retry */
1612 xs_close(xprt);
1613 break;
1614 }
1615 }
1616out:
1617 xprt_wake_pending_tasks(xprt, status);
1618out_clear:
1619 xprt_clear_connecting(xprt);
1620}
1621
1622/**
1522 * xs_connect - connect a socket to a remote endpoint 1623 * xs_connect - connect a socket to a remote endpoint
1523 * @task: address of RPC task that manages state of connect request 1624 * @task: address of RPC task that manages state of connect request
1524 * 1625 *