|
@@ -66,6 +66,13 @@ static void svc_sock_free(struct svc_xprt *);
|
|
static struct svc_xprt *svc_create_socket(struct svc_serv *, int,
|
|
static struct svc_xprt *svc_create_socket(struct svc_serv *, int,
|
|
struct net *, struct sockaddr *,
|
|
struct net *, struct sockaddr *,
|
|
int, int);
|
|
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
|
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
static struct lock_class_key svc_key[2];
|
|
static struct lock_class_key svc_key[2];
|
|
static struct lock_class_key svc_slock_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);
|
|
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 = {
|
|
static struct svc_xprt_ops svc_tcp_ops = {
|
|
.xpo_create = svc_tcp_create,
|
|
.xpo_create = svc_tcp_create,
|
|
.xpo_recvfrom = svc_tcp_recvfrom,
|
|
.xpo_recvfrom = svc_tcp_recvfrom,
|
|
@@ -1509,41 +1549,43 @@ static void svc_sock_free(struct svc_xprt *xprt)
|
|
kfree(svsk);
|
|
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_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);
|
|
svsk = kzalloc(sizeof(*svsk), GFP_KERNEL);
|
|
if (!svsk)
|
|
if (!svsk)
|
|
- goto out;
|
|
|
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
xprt = &svsk->sk_xprt;
|
|
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;
|
|
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)
|
|
if (xprt)
|
|
kfree(container_of(xprt, struct svc_sock, sk_xprt));
|
|
kfree(container_of(xprt, struct svc_sock, sk_xprt));
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL_GPL(svc_sock_destroy);
|
|
|
|
|
|
+#endif /* CONFIG_NFS_V4_1 */
|