diff options
-rw-r--r-- | include/linux/sunrpc/svcsock.h | 1 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 4 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 82 |
3 files changed, 63 insertions, 24 deletions
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index 1b353a76c304..3a45a80760b9 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h | |||
@@ -45,6 +45,7 @@ int svc_sock_names(struct svc_serv *serv, char *buf, | |||
45 | int svc_addsock(struct svc_serv *serv, const int fd, | 45 | int svc_addsock(struct svc_serv *serv, const int fd, |
46 | char *name_return, const size_t len); | 46 | char *name_return, const size_t len); |
47 | void svc_init_xprt_sock(void); | 47 | void svc_init_xprt_sock(void); |
48 | void svc_init_bc_xprt_sock(void); | ||
48 | void svc_cleanup_xprt_sock(void); | 49 | void svc_cleanup_xprt_sock(void); |
49 | struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot); | 50 | struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot); |
50 | void svc_sock_destroy(struct svc_xprt *); | 51 | void svc_sock_destroy(struct svc_xprt *); |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 606d182895a9..261e2d1dff10 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -488,10 +488,6 @@ svc_destroy(struct svc_serv *serv) | |||
488 | if (svc_serv_is_pooled(serv)) | 488 | if (svc_serv_is_pooled(serv)) |
489 | svc_pool_map_put(); | 489 | svc_pool_map_put(); |
490 | 490 | ||
491 | #if defined(CONFIG_NFS_V4_1) | ||
492 | svc_sock_destroy(serv->bc_xprt); | ||
493 | #endif /* CONFIG_NFS_V4_1 */ | ||
494 | |||
495 | svc_unregister(serv); | 491 | svc_unregister(serv); |
496 | kfree(serv->sv_pools); | 492 | kfree(serv->sv_pools); |
497 | kfree(serv); | 493 | kfree(serv); |
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 *); | |||
66 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, | 66 | static 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) | ||
70 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, | ||
71 | struct net *, struct sockaddr *, | ||
72 | int, int); | ||
73 | static 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 |
70 | static struct lock_class_key svc_key[2]; | 77 | static struct lock_class_key svc_key[2]; |
71 | static struct lock_class_key svc_slock_key[2]; | 78 | static 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) | ||
1195 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, | ||
1196 | struct net *, struct sockaddr *, | ||
1197 | int, int); | ||
1198 | static void svc_bc_sock_free(struct svc_xprt *xprt); | ||
1199 | |||
1200 | static 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 | |||
1208 | static void svc_bc_tcp_sock_detach(struct svc_xprt *xprt) | ||
1209 | { | ||
1210 | } | ||
1211 | |||
1212 | static 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 | |||
1219 | static 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 | |||
1187 | static struct svc_xprt_ops svc_tcp_ops = { | 1227 | static 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 | */ |
1518 | struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot) | 1556 | static 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(); | ||
1535 | out: | ||
1536 | dprintk("svc: %s return %p\n", __func__, xprt); | ||
1537 | return xprt; | 1580 | return xprt; |
1538 | } | 1581 | } |
1539 | EXPORT_SYMBOL_GPL(svc_sock_create); | ||
1540 | 1582 | ||
1541 | /* | 1583 | /* |
1542 | * Destroy a svc_sock. | 1584 | * Free a back channel svc_sock. |
1543 | */ | 1585 | */ |
1544 | void svc_sock_destroy(struct svc_xprt *xprt) | 1586 | static 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 | } |
1549 | EXPORT_SYMBOL_GPL(svc_sock_destroy); | 1591 | #endif /* CONFIG_NFS_V4_1 */ |