aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svcsock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svcsock.c')
-rw-r--r--net/sunrpc/svcsock.c106
1 files changed, 85 insertions, 21 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 07919e16be3e..d265aa700bb3 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,57 @@ 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
1226static void svc_init_bc_xprt_sock(void)
1227{
1228 svc_reg_xprt_class(&svc_tcp_bc_class);
1229}
1230
1231static void svc_cleanup_bc_xprt_sock(void)
1232{
1233 svc_unreg_xprt_class(&svc_tcp_bc_class);
1234}
1235#else /* CONFIG_NFS_V4_1 */
1236static void svc_init_bc_xprt_sock(void)
1237{
1238}
1239
1240static void svc_cleanup_bc_xprt_sock(void)
1241{
1242}
1243#endif /* CONFIG_NFS_V4_1 */
1244
1187static struct svc_xprt_ops svc_tcp_ops = { 1245static struct svc_xprt_ops svc_tcp_ops = {
1188 .xpo_create = svc_tcp_create, 1246 .xpo_create = svc_tcp_create,
1189 .xpo_recvfrom = svc_tcp_recvfrom, 1247 .xpo_recvfrom = svc_tcp_recvfrom,
@@ -1207,12 +1265,14 @@ void svc_init_xprt_sock(void)
1207{ 1265{
1208 svc_reg_xprt_class(&svc_tcp_class); 1266 svc_reg_xprt_class(&svc_tcp_class);
1209 svc_reg_xprt_class(&svc_udp_class); 1267 svc_reg_xprt_class(&svc_udp_class);
1268 svc_init_bc_xprt_sock();
1210} 1269}
1211 1270
1212void svc_cleanup_xprt_sock(void) 1271void svc_cleanup_xprt_sock(void)
1213{ 1272{
1214 svc_unreg_xprt_class(&svc_tcp_class); 1273 svc_unreg_xprt_class(&svc_tcp_class);
1215 svc_unreg_xprt_class(&svc_udp_class); 1274 svc_unreg_xprt_class(&svc_udp_class);
1275 svc_cleanup_bc_xprt_sock();
1216} 1276}
1217 1277
1218static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) 1278static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
@@ -1509,41 +1569,45 @@ static void svc_sock_free(struct svc_xprt *xprt)
1509 kfree(svsk); 1569 kfree(svsk);
1510} 1570}
1511 1571
1572#if defined(CONFIG_NFS_V4_1)
1512/* 1573/*
1513 * Create a svc_xprt. 1574 * 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 */ 1575 */
1518struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot) 1576static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv,
1577 int protocol,
1578 struct net *net,
1579 struct sockaddr *sin, int len,
1580 int flags)
1519{ 1581{
1520 struct svc_sock *svsk; 1582 struct svc_sock *svsk;
1521 struct svc_xprt *xprt = NULL; 1583 struct svc_xprt *xprt;
1584
1585 if (protocol != IPPROTO_TCP) {
1586 printk(KERN_WARNING "svc: only TCP sockets"
1587 " supported on shared back channel\n");
1588 return ERR_PTR(-EINVAL);
1589 }
1522 1590
1523 dprintk("svc: %s\n", __func__);
1524 svsk = kzalloc(sizeof(*svsk), GFP_KERNEL); 1591 svsk = kzalloc(sizeof(*svsk), GFP_KERNEL);
1525 if (!svsk) 1592 if (!svsk)
1526 goto out; 1593 return ERR_PTR(-ENOMEM);
1527 1594
1528 xprt = &svsk->sk_xprt; 1595 xprt = &svsk->sk_xprt;
1529 if (prot == IPPROTO_TCP) 1596 svc_xprt_init(&svc_tcp_bc_class, xprt, serv);
1530 svc_xprt_init(&svc_tcp_class, xprt, serv); 1597
1531 else if (prot == IPPROTO_UDP) 1598 serv->sv_bc_xprt = xprt;
1532 svc_xprt_init(&svc_udp_class, xprt, serv); 1599
1533 else
1534 BUG();
1535out:
1536 dprintk("svc: %s return %p\n", __func__, xprt);
1537 return xprt; 1600 return xprt;
1538} 1601}
1539EXPORT_SYMBOL_GPL(svc_sock_create);
1540 1602
1541/* 1603/*
1542 * Destroy a svc_sock. 1604 * Free a back channel svc_sock.
1543 */ 1605 */
1544void svc_sock_destroy(struct svc_xprt *xprt) 1606static void svc_bc_sock_free(struct svc_xprt *xprt)
1545{ 1607{
1546 if (xprt) 1608 if (xprt) {
1609 kfree(xprt->xpt_bc_sid);
1547 kfree(container_of(xprt, struct svc_sock, sk_xprt)); 1610 kfree(container_of(xprt, struct svc_sock, sk_xprt));
1611 }
1548} 1612}
1549EXPORT_SYMBOL_GPL(svc_sock_destroy); 1613#endif /* CONFIG_NFS_V4_1 */