diff options
Diffstat (limited to 'net/sunrpc/svcsock.c')
-rw-r--r-- | net/sunrpc/svcsock.c | 106 |
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 *); | |||
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,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) | ||
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 | |||
1226 | static void svc_init_bc_xprt_sock(void) | ||
1227 | { | ||
1228 | svc_reg_xprt_class(&svc_tcp_bc_class); | ||
1229 | } | ||
1230 | |||
1231 | static void svc_cleanup_bc_xprt_sock(void) | ||
1232 | { | ||
1233 | svc_unreg_xprt_class(&svc_tcp_bc_class); | ||
1234 | } | ||
1235 | #else /* CONFIG_NFS_V4_1 */ | ||
1236 | static void svc_init_bc_xprt_sock(void) | ||
1237 | { | ||
1238 | } | ||
1239 | |||
1240 | static void svc_cleanup_bc_xprt_sock(void) | ||
1241 | { | ||
1242 | } | ||
1243 | #endif /* CONFIG_NFS_V4_1 */ | ||
1244 | |||
1187 | static struct svc_xprt_ops svc_tcp_ops = { | 1245 | static 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 | ||
1212 | void svc_cleanup_xprt_sock(void) | 1271 | void 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 | ||
1218 | static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) | 1278 | static 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 | */ |
1518 | struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot) | 1576 | static 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(); | ||
1535 | out: | ||
1536 | dprintk("svc: %s return %p\n", __func__, xprt); | ||
1537 | return xprt; | 1600 | return xprt; |
1538 | } | 1601 | } |
1539 | EXPORT_SYMBOL_GPL(svc_sock_create); | ||
1540 | 1602 | ||
1541 | /* | 1603 | /* |
1542 | * Destroy a svc_sock. | 1604 | * Free a back channel svc_sock. |
1543 | */ | 1605 | */ |
1544 | void svc_sock_destroy(struct svc_xprt *xprt) | 1606 | static 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 | } |
1549 | EXPORT_SYMBOL_GPL(svc_sock_destroy); | 1613 | #endif /* CONFIG_NFS_V4_1 */ |