Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=68e220bd5c9fc52d8029275cd42e08f573ce3600
Commit:     68e220bd5c9fc52d8029275cd42e08f573ce3600
Parent:     9c3d72de28eed3e882becd7054da2118f8a73131
Author:     Chuck Lever <[EMAIL PROTECTED]>
AuthorDate: Mon Aug 6 11:57:48 2007 -0400
Committer:  Trond Myklebust <[EMAIL PROTECTED]>
CommitDate: Tue Oct 9 17:16:18 2007 -0400

    SUNRPC: create connect workers for IPv6
    
    Clone separate connect worker functions for connecting AF_INET6 sockets.
    
    Signed-off-by: Chuck Lever <[EMAIL PROTECTED]>
    Cc: Aurelien Charbon <[EMAIL PROTECTED]>
    Signed-off-by: Trond Myklebust <[EMAIL PROTECTED]>
---
 net/sunrpc/xprtsock.c |  101 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 101 insertions(+), 0 deletions(-)

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index a0c26b9..cc4db17 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1393,6 +1393,47 @@ out:
        xprt_clear_connecting(xprt);
 }
 
+/**
+ * xs_udp_connect_worker6 - set up a UDP socket
+ * @work: RPC transport to connect
+ *
+ * Invoked by a work queue tasklet.
+ */
+static void xs_udp_connect_worker6(struct work_struct *work)
+{
+       struct sock_xprt *transport =
+               container_of(work, struct sock_xprt, connect_worker.work);
+       struct rpc_xprt *xprt = &transport->xprt;
+       struct socket *sock = transport->sock;
+       int err, status = -EIO;
+
+       if (xprt->shutdown || !xprt_bound(xprt))
+               goto out;
+
+       /* Start by resetting any existing state */
+       xs_close(xprt);
+
+       if ((err = sock_create_kern(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, &sock)) 
< 0) {
+               dprintk("RPC:       can't create UDP transport socket (%d).\n", 
-err);
+               goto out;
+       }
+       xs_reclassify_socket(sock);
+
+       if (xs_bind6(transport, sock) < 0) {
+               sock_release(sock);
+               goto out;
+       }
+
+       dprintk("RPC:       worker connecting xprt %p to address: %s\n",
+                       xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
+
+       xs_udp_finish_connecting(xprt, sock);
+       status = 0;
+out:
+       xprt_wake_pending_tasks(xprt, status);
+       xprt_clear_connecting(xprt);
+}
+
 /*
  * We need to preserve the port number so the reply cache on the server can
  * find our cached RPC replies when we get around to reconnecting.
@@ -1519,6 +1560,66 @@ out_clear:
 }
 
 /**
+ * xs_tcp_connect_worker6 - connect a TCP socket to a remote endpoint
+ * @work: RPC transport to connect
+ *
+ * Invoked by a work queue tasklet.
+ */
+static void xs_tcp_connect_worker6(struct work_struct *work)
+{
+       struct sock_xprt *transport =
+               container_of(work, struct sock_xprt, connect_worker.work);
+       struct rpc_xprt *xprt = &transport->xprt;
+       struct socket *sock = transport->sock;
+       int err, status = -EIO;
+
+       if (xprt->shutdown || !xprt_bound(xprt))
+               goto out;
+
+       if (!sock) {
+               /* start from scratch */
+               if ((err = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, 
&sock)) < 0) {
+                       dprintk("RPC:       can't create TCP transport socket 
(%d).\n", -err);
+                       goto out;
+               }
+               xs_reclassify_socket(sock);
+
+               if (xs_bind6(transport, sock) < 0) {
+                       sock_release(sock);
+                       goto out;
+               }
+       } else
+               /* "close" the socket, preserving the local port */
+               xs_tcp_reuse_connection(xprt);
+
+       dprintk("RPC:       worker connecting xprt %p to address: %s\n",
+                       xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
+
+       status = xs_tcp_finish_connecting(xprt, sock);
+       dprintk("RPC:       %p connect status %d connected %d sock state %d\n",
+                       xprt, -status, xprt_connected(xprt), 
sock->sk->sk_state);
+       if (status < 0) {
+               switch (status) {
+                       case -EINPROGRESS:
+                       case -EALREADY:
+                               goto out_clear;
+                       case -ECONNREFUSED:
+                       case -ECONNRESET:
+                               /* retry with existing socket, after a delay */
+                               break;
+                       default:
+                               /* get rid of existing socket, and retry */
+                               xs_close(xprt);
+                               break;
+               }
+       }
+out:
+       xprt_wake_pending_tasks(xprt, status);
+out_clear:
+       xprt_clear_connecting(xprt);
+}
+
+/**
  * xs_connect - connect a socket to a remote endpoint
  * @task: address of RPC task that manages state of connect request
  *
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to