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 */ |
