aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svcsock.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2011-01-05 21:04:26 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-01-06 14:46:23 -0500
commit1f11a034cdc4b45ee56d51b87a9e37cb776fb15b (patch)
tree7d99e63af6a6c0b371ab1ee48da16edc73ab942c /net/sunrpc/svcsock.c
parent71e161a6a9fa021a280e564254fcda894e6fbd14 (diff)
SUNRPC new transport for the NFSv4.1 shared back channel
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>
Diffstat (limited to 'net/sunrpc/svcsock.c')
-rw-r--r--net/sunrpc/svcsock.c82
1 files changed, 62 insertions, 20 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 07919e16be3e..6630f2922f40 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -66,6 +66,13 @@ static void svc_sock_free(struct svc_xprt *);
66static struct svc_xprt *svc_create_socket(struct svc_serv *, int, 66static struct svc_xprt *svc_create_socket(struct svc_serv *, int,
67 struct net *, struct sockaddr *, 67 struct net *, struct sockaddr *,
68 int, int); 68 int, int);
69#if defined(CONFIG_NFS_V4_1)
70static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int,
71 struct net *, struct sockaddr *,
72 int, int);
73static void svc_bc_sock_free(struct svc_xprt *xprt);
74#endif /* CONFIG_NFS_V4_1 */
75
69#ifdef CONFIG_DEBUG_LOCK_ALLOC 76#ifdef CONFIG_DEBUG_LOCK_ALLOC
70static struct lock_class_key svc_key[2]; 77static struct lock_class_key svc_key[2];
71static struct lock_class_key svc_slock_key[2]; 78static struct lock_class_key svc_slock_key[2];
@@ -1184,6 +1191,39 @@ static struct svc_xprt *svc_tcp_create(struct svc_serv *serv,
1184 return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags); 1191 return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags);
1185} 1192}
1186 1193
1194#if defined(CONFIG_NFS_V4_1)
1195static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int,
1196 struct net *, struct sockaddr *,
1197 int, int);
1198static void svc_bc_sock_free(struct svc_xprt *xprt);
1199
1200static struct svc_xprt *svc_bc_tcp_create(struct svc_serv *serv,
1201 struct net *net,
1202 struct sockaddr *sa, int salen,
1203 int flags)
1204{
1205 return svc_bc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags);
1206}
1207
1208static void svc_bc_tcp_sock_detach(struct svc_xprt *xprt)
1209{
1210}
1211
1212static struct svc_xprt_ops svc_tcp_bc_ops = {
1213 .xpo_create = svc_bc_tcp_create,
1214 .xpo_detach = svc_bc_tcp_sock_detach,
1215 .xpo_free = svc_bc_sock_free,
1216 .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr,
1217};
1218
1219static struct svc_xprt_class svc_tcp_bc_class = {
1220 .xcl_name = "tcp-bc",
1221 .xcl_owner = THIS_MODULE,
1222 .xcl_ops = &svc_tcp_bc_ops,
1223 .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP,
1224};
1225#endif /* CONFIG_NFS_V4_1 */
1226
1187static struct svc_xprt_ops svc_tcp_ops = { 1227static struct svc_xprt_ops svc_tcp_ops = {
1188 .xpo_create = svc_tcp_create, 1228 .xpo_create = svc_tcp_create,
1189 .xpo_recvfrom = svc_tcp_recvfrom, 1229 .xpo_recvfrom = svc_tcp_recvfrom,
@@ -1509,41 +1549,43 @@ static void svc_sock_free(struct svc_xprt *xprt)
1509 kfree(svsk); 1549 kfree(svsk);
1510} 1550}
1511 1551
1552#if defined(CONFIG_NFS_V4_1)
1512/* 1553/*
1513 * Create a svc_xprt. 1554 * Create a back channel svc_xprt which shares the fore channel socket.
1514 *
1515 * For internal use only (e.g. nfsv4.1 backchannel).
1516 * Callers should typically use the xpo_create() method.
1517 */ 1555 */
1518struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot) 1556static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv,
1557 int protocol,
1558 struct net *net,
1559 struct sockaddr *sin, int len,
1560 int flags)
1519{ 1561{
1520 struct svc_sock *svsk; 1562 struct svc_sock *svsk;
1521 struct svc_xprt *xprt = NULL; 1563 struct svc_xprt *xprt;
1564
1565 if (protocol != IPPROTO_TCP) {
1566 printk(KERN_WARNING "svc: only TCP sockets"
1567 " supported on shared back channel\n");
1568 return ERR_PTR(-EINVAL);
1569 }
1522 1570
1523 dprintk("svc: %s\n", __func__);
1524 svsk = kzalloc(sizeof(*svsk), GFP_KERNEL); 1571 svsk = kzalloc(sizeof(*svsk), GFP_KERNEL);
1525 if (!svsk) 1572 if (!svsk)
1526 goto out; 1573 return ERR_PTR(-ENOMEM);
1527 1574
1528 xprt = &svsk->sk_xprt; 1575 xprt = &svsk->sk_xprt;
1529 if (prot == IPPROTO_TCP) 1576 svc_xprt_init(&svc_tcp_bc_class, xprt, serv);
1530 svc_xprt_init(&svc_tcp_class, xprt, serv); 1577
1531 else if (prot == IPPROTO_UDP) 1578 serv->bc_xprt = xprt;
1532 svc_xprt_init(&svc_udp_class, xprt, serv); 1579
1533 else
1534 BUG();
1535out:
1536 dprintk("svc: %s return %p\n", __func__, xprt);
1537 return xprt; 1580 return xprt;
1538} 1581}
1539EXPORT_SYMBOL_GPL(svc_sock_create);
1540 1582
1541/* 1583/*
1542 * Destroy a svc_sock. 1584 * Free a back channel svc_sock.
1543 */ 1585 */
1544void svc_sock_destroy(struct svc_xprt *xprt) 1586static void svc_bc_sock_free(struct svc_xprt *xprt)
1545{ 1587{
1546 if (xprt) 1588 if (xprt)
1547 kfree(container_of(xprt, struct svc_sock, sk_xprt)); 1589 kfree(container_of(xprt, struct svc_sock, sk_xprt));
1548} 1590}
1549EXPORT_SYMBOL_GPL(svc_sock_destroy); 1591#endif /* CONFIG_NFS_V4_1 */