SUNRPC new transport for the NFSv4.1 shared back channel
authorAndy Adamson <andros@netapp.com>
Thu, 6 Jan 2011 02:04:26 +0000 (02:04 +0000)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Thu, 6 Jan 2011 19:46:23 +0000 (14:46 -0500)
Move the current sock create and destroy routines into the new transport ops.
Back channel socket will be destroyed by the svc_closs_all call in svc_destroy.

Added check: only TCP supported on shared back channel.

Signed-off-by: Andy Adamson <andros@netapp.com>
Acked-by: Bruce Fields <bfields@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
include/linux/sunrpc/svcsock.h
net/sunrpc/svc.c
net/sunrpc/svcsock.c

index 1b353a76c30492389bad8c12fb41ffcd901a2027..3a45a80760b95aa696048f4f23dec75690ad273a 100644 (file)
@@ -45,6 +45,7 @@ int           svc_sock_names(struct svc_serv *serv, char *buf,
 int            svc_addsock(struct svc_serv *serv, const int fd,
                                        char *name_return, const size_t len);
 void           svc_init_xprt_sock(void);
+void           svc_init_bc_xprt_sock(void);
 void           svc_cleanup_xprt_sock(void);
 struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot);
 void           svc_sock_destroy(struct svc_xprt *);
index 606d182895a94c96c3c5f10d20a3092c95a1f173..261e2d1dff1037447f5e3026005afe0bc718cbdc 100644 (file)
@@ -488,10 +488,6 @@ svc_destroy(struct svc_serv *serv)
        if (svc_serv_is_pooled(serv))
                svc_pool_map_put();
 
-#if defined(CONFIG_NFS_V4_1)
-       svc_sock_destroy(serv->bc_xprt);
-#endif /* CONFIG_NFS_V4_1 */
-
        svc_unregister(serv);
        kfree(serv->sv_pools);
        kfree(serv);
index 07919e16be3ef3a274d7c099c2e58d2884067edf..6630f2922f40b642ed00d87c34a6e7ed3109abb9 100644 (file)
@@ -66,6 +66,13 @@ static void          svc_sock_free(struct svc_xprt *);
 static struct svc_xprt *svc_create_socket(struct svc_serv *, int,
                                          struct net *, struct sockaddr *,
                                          int, int);
+#if defined(CONFIG_NFS_V4_1)
+static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int,
+                                            struct net *, struct sockaddr *,
+                                            int, int);
+static void svc_bc_sock_free(struct svc_xprt *xprt);
+#endif /* CONFIG_NFS_V4_1 */
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key svc_key[2];
 static struct lock_class_key svc_slock_key[2];
@@ -1184,6 +1191,39 @@ static struct svc_xprt *svc_tcp_create(struct svc_serv *serv,
        return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags);
 }
 
+#if defined(CONFIG_NFS_V4_1)
+static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int,
+                                            struct net *, struct sockaddr *,
+                                            int, int);
+static void svc_bc_sock_free(struct svc_xprt *xprt);
+
+static struct svc_xprt *svc_bc_tcp_create(struct svc_serv *serv,
+                                      struct net *net,
+                                      struct sockaddr *sa, int salen,
+                                      int flags)
+{
+       return svc_bc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags);
+}
+
+static void svc_bc_tcp_sock_detach(struct svc_xprt *xprt)
+{
+}
+
+static struct svc_xprt_ops svc_tcp_bc_ops = {
+       .xpo_create = svc_bc_tcp_create,
+       .xpo_detach = svc_bc_tcp_sock_detach,
+       .xpo_free = svc_bc_sock_free,
+       .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr,
+};
+
+static struct svc_xprt_class svc_tcp_bc_class = {
+       .xcl_name = "tcp-bc",
+       .xcl_owner = THIS_MODULE,
+       .xcl_ops = &svc_tcp_bc_ops,
+       .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP,
+};
+#endif /* CONFIG_NFS_V4_1 */
+
 static struct svc_xprt_ops svc_tcp_ops = {
        .xpo_create = svc_tcp_create,
        .xpo_recvfrom = svc_tcp_recvfrom,
@@ -1509,41 +1549,43 @@ static void svc_sock_free(struct svc_xprt *xprt)
        kfree(svsk);
 }
 
+#if defined(CONFIG_NFS_V4_1)
 /*
- * Create a svc_xprt.
- *
- * For internal use only (e.g. nfsv4.1 backchannel).
- * Callers should typically use the xpo_create() method.
+ * Create a back channel svc_xprt which shares the fore channel socket.
  */
-struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot)
+static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv,
+                                            int protocol,
+                                            struct net *net,
+                                            struct sockaddr *sin, int len,
+                                            int flags)
 {
        struct svc_sock *svsk;
-       struct svc_xprt *xprt = NULL;
+       struct svc_xprt *xprt;
+
+       if (protocol != IPPROTO_TCP) {
+               printk(KERN_WARNING "svc: only TCP sockets"
+                       " supported on shared back channel\n");
+               return ERR_PTR(-EINVAL);
+       }
 
-       dprintk("svc: %s\n", __func__);
        svsk = kzalloc(sizeof(*svsk), GFP_KERNEL);
        if (!svsk)
-               goto out;
+               return ERR_PTR(-ENOMEM);
 
        xprt = &svsk->sk_xprt;
-       if (prot == IPPROTO_TCP)
-               svc_xprt_init(&svc_tcp_class, xprt, serv);
-       else if (prot == IPPROTO_UDP)
-               svc_xprt_init(&svc_udp_class, xprt, serv);
-       else
-               BUG();
-out:
-       dprintk("svc: %s return %p\n", __func__, xprt);
+       svc_xprt_init(&svc_tcp_bc_class, xprt, serv);
+
+       serv->bc_xprt = xprt;
+
        return xprt;
 }
-EXPORT_SYMBOL_GPL(svc_sock_create);
 
 /*
- * Destroy a svc_sock.
+ * Free a back channel svc_sock.
  */
-void svc_sock_destroy(struct svc_xprt *xprt)
+static void svc_bc_sock_free(struct svc_xprt *xprt)
 {
        if (xprt)
                kfree(container_of(xprt, struct svc_sock, sk_xprt));
 }
-EXPORT_SYMBOL_GPL(svc_sock_destroy);
+#endif /* CONFIG_NFS_V4_1 */