| @@ -19,6 +19,7 @@ · 18 unmodified lines |
| 19 | */ | 19 | */ |
| 20 | | 20 | |
| 21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
| | 22 | #include <linux/string.h> |
| 22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 24 | #include <linux/capability.h> | 25 | #include <linux/capability.h> |
| @@ -28,6 +29,7 @@ · 3 unmodified lines |
| 28 | #include <linux/in.h> | 29 | #include <linux/in.h> |
| 29 | #include <linux/net.h> | 30 | #include <linux/net.h> |
| 30 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
| | 32 | #include <linux/un.h> |
| 31 | #include <linux/udp.h> | 33 | #include <linux/udp.h> |
| 32 | #include <linux/tcp.h> | 34 | #include <linux/tcp.h> |
| 33 | #include <linux/sunrpc/clnt.h> | 35 | #include <linux/sunrpc/clnt.h> |
| @@ -45,6 +47,9 @@ · 11 unmodified lines |
| 45 | #include <net/tcp.h> | 47 | #include <net/tcp.h> |
| 46 | | 48 | |
| 47 | #include "sunrpc.h" | 49 | #include "sunrpc.h" |
| | 50 | |
| | 51 | static void xs_close(struct rpc_xprt *xprt); |
| | 52 | |
| 48 | /* | 53 | /* |
| 49 | * xprtsock tunables | 54 | * xprtsock tunables |
| 50 | */ | 55 | */ |
| @@ -261,6 +266,11 @@ static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt) · 210 unmodified lines |
| 261 | return (struct sockaddr *) &xprt->addr; | 266 | return (struct sockaddr *) &xprt->addr; |
| 262 | } | 267 | } |
| 263 | | 268 | |
| | 269 | static inline struct sockaddr_un *xs_addr_un(struct rpc_xprt *xprt) |
| | 270 | { |
| | 271 | return (struct sockaddr_un *) &xprt->addr; |
| | 272 | } |
| | 273 | |
| 264 | static inline struct sockaddr_in *xs_addr_in(struct rpc_xprt *xprt) | 274 | static inline struct sockaddr_in *xs_addr_in(struct rpc_xprt *xprt) |
| 265 | { | 275 | { |
| 266 | return (struct sockaddr_in *) &xprt->addr; | 276 | return (struct sockaddr_in *) &xprt->addr; |
| @@ -276,23 +286,34 @@ static void xs_format_common_peer_addresses(struct rpc_xprt *xprt) · 9 unmodified lines |
| 276 | struct sockaddr *sap = xs_addr(xprt); | 286 | struct sockaddr *sap = xs_addr(xprt); |
| 277 | struct sockaddr_in6 *sin6; | 287 | struct sockaddr_in6 *sin6; |
| 278 | struct sockaddr_in *sin; | 288 | struct sockaddr_in *sin; |
| | 289 | struct sockaddr_un *sun; |
| 279 | char buf[128]; | 290 | char buf[128]; |
| 280 | | 291 | |
| 281 | (void)rpc_ntop(sap, buf, sizeof(buf)); | | |
| 282 | xprt->address_strings[RPC_DISPLAY_ADDR] = kstrdup(buf, GFP_KERNEL); | | |
| 283 | | | |
| 284 | switch (sap->sa_family) { | 292 | switch (sap->sa_family) { |
| | 293 | case AF_LOCAL: |
| | 294 | sun = xs_addr_un(xprt); |
| | 295 | strlcpy(buf, sun->sun_path, sizeof(buf)); |
| | 296 | xprt->address_strings[RPC_DISPLAY_ADDR] = |
| | 297 | kstrdup(buf, GFP_KERNEL); |
| | 298 | break; |
| 285 | case AF_INET: | 299 | case AF_INET: |
| | 300 | (void)rpc_ntop(sap, buf, sizeof(buf)); |
| | 301 | xprt->address_strings[RPC_DISPLAY_ADDR] = |
| | 302 | kstrdup(buf, GFP_KERNEL); |
| 286 | sin = xs_addr_in(xprt); | 303 | sin = xs_addr_in(xprt); |
| 287 | snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr)); | 304 | snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr)); |
| 288 | break; | 305 | break; |
| 289 | case AF_INET6: | 306 | case AF_INET6: |
| | 307 | (void)rpc_ntop(sap, buf, sizeof(buf)); |
| | 308 | xprt->address_strings[RPC_DISPLAY_ADDR] = |
| | 309 | kstrdup(buf, GFP_KERNEL); |
| 290 | sin6 = xs_addr_in6(xprt); | 310 | sin6 = xs_addr_in6(xprt); |
| 291 | snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr); | 311 | snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr); |
| 292 | break; | 312 | break; |
| 293 | default: | 313 | default: |
| 294 | BUG(); | 314 | BUG(); |
| 295 | } | 315 | } |
| | 316 | |
| 296 | xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL); | 317 | xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL); |
| 297 | } | 318 | } |
| 298 | | 319 | |
| @@ -495,6 +516,70 @@ static int xs_nospace(struct rpc_task *task) · 196 unmodified lines |
| 495 | return ret; | 516 | return ret; |
| 496 | } | 517 | } |
| 497 | | 518 | |
| | 519 | /* |
| | 520 | * Construct a stream transport record marker in @buf. |
| | 521 | */ |
| | 522 | static inline void xs_encode_stream_record_marker(struct xdr_buf *buf) |
| | 523 | { |
| | 524 | u32 reclen = buf->len - sizeof(rpc_fraghdr); |
| | 525 | rpc_fraghdr *base = buf->head[0].iov_base; |
| | 526 | *base = cpu_to_be32(RPC_LAST_STREAM_FRAGMENT | reclen); |
| | 527 | } |
| | 528 | |
| | 529 | /** |
| | 530 | * xs_local_send_request - write an RPC request to an AF_LOCAL socket |
| | 531 | * @task: RPC task that manages the state of an RPC request |
| | 532 | * |
| | 533 | * Return values: |
| | 534 | * 0: The request has been sent |
| | 535 | * EAGAIN: The socket was blocked, please call again later to |
| | 536 | * complete the request |
| | 537 | * ENOTCONN: Caller needs to invoke connect logic then call again |
| | 538 | * other: Some other error occured, the request was not sent |
| | 539 | */ |
| | 540 | static int xs_local_send_request(struct rpc_task *task) |
| | 541 | { |
| | 542 | struct rpc_rqst *req = task->tk_rqstp; |
| | 543 | struct rpc_xprt *xprt = req->rq_xprt; |
| | 544 | struct sock_xprt *transport = |
| | 545 | container_of(xprt, struct sock_xprt, xprt); |
| | 546 | struct xdr_buf *xdr = &req->rq_snd_buf; |
| | 547 | int status; |
| | 548 | |
| | 549 | xs_encode_stream_record_marker(&req->rq_snd_buf); |
| | 550 | |
| | 551 | xs_pktdump("packet data:", |
| | 552 | req->rq_svec->iov_base, req->rq_svec->iov_len); |
| | 553 | |
| | 554 | status = xs_sendpages(transport->sock, NULL, 0, |
| | 555 | xdr, req->rq_bytes_sent); |
| | 556 | dprintk("RPC: %s(%u) = %d\n", |
| | 557 | __func__, xdr->len - req->rq_bytes_sent, status); |
| | 558 | if (likely(status >= 0)) { |
| | 559 | req->rq_bytes_sent += status; |
| | 560 | req->rq_xmit_bytes_sent += status; |
| | 561 | if (likely(req->rq_bytes_sent >= req->rq_slen)) { |
| | 562 | req->rq_bytes_sent = 0; |
| | 563 | return 0; |
| | 564 | } |
| | 565 | status = -EAGAIN; |
| | 566 | } |
| | 567 | |
| | 568 | switch (status) { |
| | 569 | case -EAGAIN: |
| | 570 | status = xs_nospace(task); |
| | 571 | break; |
| | 572 | default: |
| | 573 | dprintk("RPC: sendmsg returned unrecognized error %d\n", |
| | 574 | -status); |
| | 575 | case -EPIPE: |
| | 576 | xs_close(xprt); |
| | 577 | status = -ENOTCONN; |
| | 578 | } |
| | 579 | |
| | 580 | return status; |
| | 581 | } |
| | 582 | |
| 498 | /** | 583 | /** |
| 499 | * xs_udp_send_request - write an RPC request to a UDP socket | 584 | * xs_udp_send_request - write an RPC request to a UDP socket |
| 500 | * @task: address of RPC task that manages the state of an RPC request | 585 | * @task: address of RPC task that manages the state of an RPC request |
| @@ -574,13 +659,6 @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt) · 73 unmodified lines |
| 574 | kernel_sock_shutdown(sock, SHUT_WR); | 659 | kernel_sock_shutdown(sock, SHUT_WR); |
| 575 | } | 660 | } |
| 576 | | 661 | |
| 577 | static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf) | | |
| 578 | { | | |
| 579 | u32 reclen = buf->len - sizeof(rpc_fraghdr); | | |
| 580 | rpc_fraghdr *base = buf->head[0].iov_base; | | |
| 581 | *base = htonl(RPC_LAST_STREAM_FRAGMENT | reclen); | | |
| 582 | } | | |
| 583 | | | |
| 584 | /** | 662 | /** |
| 585 | * xs_tcp_send_request - write an RPC request to a TCP socket | 663 | * xs_tcp_send_request - write an RPC request to a TCP socket |
| 586 | * @task: address of RPC task that manages the state of an RPC request | 664 | * @task: address of RPC task that manages the state of an RPC request |
| @@ -603,7 +681,7 @@ static int xs_tcp_send_request(struct rpc_task *task) · 16 unmodified lines |
| 603 | struct xdr_buf *xdr = &req->rq_snd_buf; | 681 | struct xdr_buf *xdr = &req->rq_snd_buf; |
| 604 | int status; | 682 | int status; |
| 605 | | 683 | |
| 606 | xs_encode_tcp_record_marker(&req->rq_snd_buf); | 684 | xs_encode_stream_record_marker(&req->rq_snd_buf); |
| 607 | | 685 | |
| 608 | xs_pktdump("packet data:", | 686 | xs_pktdump("packet data:", |
| 609 | req->rq_svec->iov_base, | 687 | req->rq_svec->iov_base, |
| @@ -785,6 +863,88 @@ static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) · 175 unmodified lines |
| 785 | return (struct rpc_xprt *) sk->sk_user_data; | 863 | return (struct rpc_xprt *) sk->sk_user_data; |
| 786 | } | 864 | } |
| 787 | | 865 | |
| | 866 | static int xs_local_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb) |
| | 867 | { |
| | 868 | struct xdr_skb_reader desc = { |
| | 869 | .skb = skb, |
| | 870 | .offset = sizeof(rpc_fraghdr), |
| | 871 | .count = skb->len - sizeof(rpc_fraghdr), |
| | 872 | }; |
| | 873 | |
| | 874 | if (xdr_partial_copy_from_skb(xdr, 0, &desc, xdr_skb_read_bits) < 0) |
| | 875 | return -1; |
| | 876 | if (desc.count) |
| | 877 | return -1; |
| | 878 | return 0; |
| | 879 | } |
| | 880 | |
| | 881 | /** |
| | 882 | * xs_local_data_ready - "data ready" callback for AF_LOCAL sockets |
| | 883 | * @sk: socket with data to read |
| | 884 | * @len: how much data to read |
| | 885 | * |
| | 886 | * Currently this assumes we can read the whole reply in a single gulp. |
| | 887 | */ |
| | 888 | static void xs_local_data_ready(struct sock *sk, int len) |
| | 889 | { |
| | 890 | struct rpc_task *task; |
| | 891 | struct rpc_xprt *xprt; |
| | 892 | struct rpc_rqst *rovr; |
| | 893 | struct sk_buff *skb; |
| | 894 | int err, repsize, copied; |
| | 895 | u32 _xid; |
| | 896 | __be32 *xp; |
| | 897 | |
| | 898 | read_lock_bh(&sk->sk_callback_lock); |
| | 899 | dprintk("RPC: %s...\n", __func__); |
| | 900 | xprt = xprt_from_sock(sk); |
| | 901 | if (xprt == NULL) |
| | 902 | goto out; |
| | 903 | |
| | 904 | skb = skb_recv_datagram(sk, 0, 1, &err); |
| | 905 | if (skb == NULL) |
| | 906 | goto out; |
| | 907 | |
| | 908 | if (xprt->shutdown) |
| | 909 | goto dropit; |
| | 910 | |
| | 911 | repsize = skb->len - sizeof(rpc_fraghdr); |
| | 912 | if (repsize < 4) { |
| | 913 | dprintk("RPC: impossible RPC reply size %d\n", repsize); |
| | 914 | goto dropit; |
| | 915 | } |
| | 916 | |
| | 917 | /* Copy the XID from the skb... */ |
| | 918 | xp = skb_header_pointer(skb, sizeof(rpc_fraghdr), sizeof(_xid), &_xid); |
| | 919 | if (xp == NULL) |
| | 920 | goto dropit; |
| | 921 | |
| | 922 | /* Look up and lock the request corresponding to the given XID */ |
| | 923 | spin_lock(&xprt->transport_lock); |
| | 924 | rovr = xprt_lookup_rqst(xprt, *xp); |
| | 925 | if (!rovr) |
| | 926 | goto out_unlock; |
| | 927 | task = rovr->rq_task; |
| | 928 | |
| | 929 | copied = rovr->rq_private_buf.buflen; |
| | 930 | if (copied > repsize) |
| | 931 | copied = repsize; |
| | 932 | |
| | 933 | if (xs_local_copy_to_xdr(&rovr->rq_private_buf, skb)) { |
| | 934 | dprintk("RPC: sk_buff copy failed\n"); |
| | 935 | goto out_unlock; |
| | 936 | } |
| | 937 | |
| | 938 | xprt_complete_rqst(task, copied); |
| | 939 | |
| | 940 | out_unlock: |
| | 941 | spin_unlock(&xprt->transport_lock); |
| | 942 | dropit: |
| | 943 | skb_free_datagram(sk, skb); |
| | 944 | out: |
| | 945 | read_unlock_bh(&sk->sk_callback_lock); |
| | 946 | } |
| | 947 | |
| 788 | /** | 948 | /** |
| 789 | * xs_udp_data_ready - "data ready" callback for UDP sockets | 949 | * xs_udp_data_ready - "data ready" callback for UDP sockets |
| 790 | * @sk: socket with data to read | 950 | * @sk: socket with data to read |
| @@ -1344,7 +1504,6 @@ static void xs_tcp_state_change(struct sock *sk) · 553 unmodified lines |
| 1344 | case TCP_CLOSE_WAIT: | 1504 | case TCP_CLOSE_WAIT: |
| 1345 | /* The server initiated a shutdown of the socket */ | 1505 | /* The server initiated a shutdown of the socket */ |
| 1346 | xprt_force_disconnect(xprt); | 1506 | xprt_force_disconnect(xprt); |
| 1347 | case TCP_SYN_SENT: | | |
| 1348 | xprt->connect_cookie++; | 1507 | xprt->connect_cookie++; |
| 1349 | case TCP_CLOSING: | 1508 | case TCP_CLOSING: |
| 1350 | /* | 1509 | /* |
| @@ -1571,11 +1730,31 @@ static int xs_bind(struct sock_xprt *transport, struct socket *sock) · 220 unmodified lines |
| 1571 | return err; | 1730 | return err; |
| 1572 | } | 1731 | } |
| 1573 | | 1732 | |
| | 1733 | /* |
| | 1734 | * We don't support autobind on AF_LOCAL sockets |
| | 1735 | */ |
| | 1736 | static void xs_local_rpcbind(struct rpc_task *task) |
| | 1737 | { |
| | 1738 | xprt_set_bound(task->tk_xprt); |
| | 1739 | } |
| | 1740 | |
| | 1741 | static void xs_local_set_port(struct rpc_xprt *xprt, unsigned short port) |
| | 1742 | { |
| | 1743 | } |
| 1574 | | 1744 | |
| 1575 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 1745 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 1576 | static struct lock_class_key xs_key[2]; | 1746 | static struct lock_class_key xs_key[2]; |
| 1577 | static struct lock_class_key xs_slock_key[2]; | 1747 | static struct lock_class_key xs_slock_key[2]; |
| 1578 | | 1748 | |
| | 1749 | static inline void xs_reclassify_socketu(struct socket *sock) |
| | 1750 | { |
| | 1751 | struct sock *sk = sock->sk; |
| | 1752 | |
| | 1753 | BUG_ON(sock_owned_by_user(sk)); |
| | 1754 | sock_lock_init_class_and_name(sk, "slock-AF_LOCAL-RPC", |
| | 1755 | &xs_slock_key[1], "sk_lock-AF_LOCAL-RPC", &xs_key[1]); |
| | 1756 | } |
| | 1757 | |
| 1579 | static inline void xs_reclassify_socket4(struct socket *sock) | 1758 | static inline void xs_reclassify_socket4(struct socket *sock) |
| 1580 | { | 1759 | { |
| 1581 | struct sock *sk = sock->sk; | 1760 | struct sock *sk = sock->sk; |
| @@ -1597,6 +1776,9 @@ static inline void xs_reclassify_socket6(struct socket *sock) · 15 unmodified lines |
| 1597 | static inline void xs_reclassify_socket(int family, struct socket *sock) | 1776 | static inline void xs_reclassify_socket(int family, struct socket *sock) |
| 1598 | { | 1777 | { |
| 1599 | switch (family) { | 1778 | switch (family) { |
| | 1779 | case AF_LOCAL: |
| | 1780 | xs_reclassify_socketu(sock); |
| | 1781 | break; |
| 1600 | case AF_INET: | 1782 | case AF_INET: |
| 1601 | xs_reclassify_socket4(sock); | 1783 | xs_reclassify_socket4(sock); |
| 1602 | break; | 1784 | break; |
| @@ -1606,6 +1788,10 @@ static inline void xs_reclassify_socket(int family, struct socket *sock) · 3 unmodified lines |
| 1606 | } | 1788 | } |
| 1607 | } | 1789 | } |
| 1608 | #else | 1790 | #else |
| | 1791 | static inline void xs_reclassify_socketu(struct socket *sock) |
| | 1792 | { |
| | 1793 | } |
| | 1794 | |
| 1609 | static inline void xs_reclassify_socket4(struct socket *sock) | 1795 | static inline void xs_reclassify_socket4(struct socket *sock) |
| 1610 | { | 1796 | { |
| 1611 | } | 1797 | } |
| @@ -1644,6 +1830,94 @@ out: · 32 unmodified lines |
| 1644 | return ERR_PTR(err); | 1830 | return ERR_PTR(err); |
| 1645 | } | 1831 | } |
| 1646 | | 1832 | |
| | 1833 | static int xs_local_finish_connecting(struct rpc_xprt *xprt, |
| | 1834 | struct socket *sock) |
| | 1835 | { |
| | 1836 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, |
| | 1837 | xprt); |
| | 1838 | |
| | 1839 | if (!transport->inet) { |
| | 1840 | struct sock *sk = sock->sk; |
| | 1841 | |
| | 1842 | write_lock_bh(&sk->sk_callback_lock); |
| | 1843 | |
| | 1844 | xs_save_old_callbacks(transport, sk); |
| | 1845 | |
| | 1846 | sk->sk_user_data = xprt; |
| | 1847 | sk->sk_data_ready = xs_local_data_ready; |
| | 1848 | sk->sk_write_space = xs_udp_write_space; |
| | 1849 | sk->sk_error_report = xs_error_report; |
| | 1850 | sk->sk_allocation = GFP_ATOMIC; |
| | 1851 | |
| | 1852 | xprt_clear_connected(xprt); |
| | 1853 | |
| | 1854 | /* Reset to new socket */ |
| | 1855 | transport->sock = sock; |
| | 1856 | transport->inet = sk; |
| | 1857 | |
| | 1858 | write_unlock_bh(&sk->sk_callback_lock); |
| | 1859 | } |
| | 1860 | |
| | 1861 | /* Tell the socket layer to start connecting... */ |
| | 1862 | xprt->stat.connect_count++; |
| | 1863 | xprt->stat.connect_start = jiffies; |
| | 1864 | return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, 0); |
| | 1865 | } |
| | 1866 | |
| | 1867 | /** |
| | 1868 | * xs_local_setup_socket - create AF_LOCAL socket, connect to a local endpoint |
| | 1869 | * @xprt: RPC transport to connect |
| | 1870 | * @transport: socket transport to connect |
| | 1871 | * @create_sock: function to create a socket of the correct type |
| | 1872 | * |
| | 1873 | * Invoked by a work queue tasklet. |
| | 1874 | */ |
| | 1875 | static void xs_local_setup_socket(struct work_struct *work) |
| | 1876 | { |
| | 1877 | struct sock_xprt *transport = |
| | 1878 | container_of(work, struct sock_xprt, connect_worker.work); |
| | 1879 | struct rpc_xprt *xprt = &transport->xprt; |
| | 1880 | struct socket *sock; |
| | 1881 | int status = -EIO; |
| | 1882 | |
| | 1883 | if (xprt->shutdown) |
| | 1884 | goto out; |
| | 1885 | |
| | 1886 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); |
| | 1887 | status = __sock_create(xprt->xprt_net, AF_LOCAL, |
| | 1888 | SOCK_STREAM, 0, &sock, 1); |
| | 1889 | if (status < 0) { |
| | 1890 | dprintk("RPC: can't create AF_LOCAL " |
| | 1891 | "transport socket (%d).\n", -status); |
| | 1892 | goto out; |
| | 1893 | } |
| | 1894 | xs_reclassify_socketu(sock); |
| | 1895 | |
| | 1896 | dprintk("RPC: worker connecting xprt %p via AF_LOCAL to %s\n", |
| | 1897 | xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); |
| | 1898 | |
| | 1899 | status = xs_local_finish_connecting(xprt, sock); |
| | 1900 | switch (status) { |
| | 1901 | case 0: |
| | 1902 | dprintk("RPC: xprt %p connected to %s\n", |
| | 1903 | xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); |
| | 1904 | xprt_set_connected(xprt); |
| | 1905 | break; |
| | 1906 | case -ENOENT: |
| | 1907 | dprintk("RPC: xprt %p: socket %s does not exist\n", |
| | 1908 | xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); |
| | 1909 | break; |
| | 1910 | default: |
| | 1911 | printk(KERN_ERR "%s: unhandled error (%d) connecting to %s\n", |
| | 1912 | __func__, -status, |
| | 1913 | xprt->address_strings[RPC_DISPLAY_ADDR]); |
| | 1914 | } |
| | 1915 | |
| | 1916 | out: |
| | 1917 | xprt_clear_connecting(xprt); |
| | 1918 | xprt_wake_pending_tasks(xprt, status); |
| | 1919 | } |
| | 1920 | |
| 1647 | static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 1921 | static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
| 1648 | { | 1922 | { |
| 1649 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 1923 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
| @@ -1758,6 +2032,7 @@ static void xs_tcp_reuse_connection(struct sock_xprt *transport) · 108 unmodified lines |
| 1758 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 2032 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
| 1759 | { | 2033 | { |
| 1760 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 2034 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
| | 2035 | int ret = -ENOTCONN; |
| 1761 | | 2036 | |
| 1762 | if (!transport->inet) { | 2037 | if (!transport->inet) { |
| 1763 | struct sock *sk = sock->sk; | 2038 | struct sock *sk = sock->sk; |
| @@ -1789,12 +2064,22 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) · 25 unmodified lines |
| 1789 | } | 2064 | } |
| 1790 | | 2065 | |
| 1791 | if (!xprt_bound(xprt)) | 2066 | if (!xprt_bound(xprt)) |
| 1792 | return -ENOTCONN; | 2067 | goto out; |
| 1793 | | 2068 | |
| 1794 | /* Tell the socket layer to start connecting... */ | 2069 | /* Tell the socket layer to start connecting... */ |
| 1795 | xprt->stat.connect_count++; | 2070 | xprt->stat.connect_count++; |
| 1796 | xprt->stat.connect_start = jiffies; | 2071 | xprt->stat.connect_start = jiffies; |
| 1797 | return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); | 2072 | ret = kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); |
| | 2073 | switch (ret) { |
| | 2074 | case 0: |
| | 2075 | case -EINPROGRESS: |
| | 2076 | /* SYN_SENT! */ |
| | 2077 | xprt->connect_cookie++; |
| | 2078 | if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) |
| | 2079 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; |
| | 2080 | } |
| | 2081 | out: |
| | 2082 | return ret; |
| 1798 | } | 2083 | } |
| 1799 | | 2084 | |
| 1800 | /** | 2085 | /** |
| @@ -1916,6 +2201,32 @@ static void xs_connect(struct rpc_task *task) · 115 unmodified lines |
| 1916 | } | 2201 | } |
| 1917 | } | 2202 | } |
| 1918 | | 2203 | |
| | 2204 | /** |
| | 2205 | * xs_local_print_stats - display AF_LOCAL socket-specifc stats |
| | 2206 | * @xprt: rpc_xprt struct containing statistics |
| | 2207 | * @seq: output file |
| | 2208 | * |
| | 2209 | */ |
| | 2210 | static void xs_local_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) |
| | 2211 | { |
| | 2212 | long idle_time = 0; |
| | 2213 | |
| | 2214 | if (xprt_connected(xprt)) |
| | 2215 | idle_time = (long)(jiffies - xprt->last_used) / HZ; |
| | 2216 | |
| | 2217 | seq_printf(seq, "\txprt:\tlocal %lu %lu %lu %ld %lu %lu %lu " |
| | 2218 | "%llu %llu\n", |
| | 2219 | xprt->stat.bind_count, |
| | 2220 | xprt->stat.connect_count, |
| | 2221 | xprt->stat.connect_time, |
| | 2222 | idle_time, |
| | 2223 | xprt->stat.sends, |
| | 2224 | xprt->stat.recvs, |
| | 2225 | xprt->stat.bad_xids, |
| | 2226 | xprt->stat.req_u, |
| | 2227 | xprt->stat.bklog_u); |
| | 2228 | } |
| | 2229 | |
| 1919 | /** | 2230 | /** |
| 1920 | * xs_udp_print_stats - display UDP socket-specifc stats | 2231 | * xs_udp_print_stats - display UDP socket-specifc stats |
| 1921 | * @xprt: rpc_xprt struct containing statistics | 2232 | * @xprt: rpc_xprt struct containing statistics |
| @@ -2014,10 +2325,7 @@ static int bc_sendto(struct rpc_rqst *req) · 92 unmodified lines |
| 2014 | unsigned long headoff; | 2325 | unsigned long headoff; |
| 2015 | unsigned long tailoff; | 2326 | unsigned long tailoff; |
| 2016 | | 2327 | |
| 2017 | /* | 2328 | xs_encode_stream_record_marker(xbufp); |
| 2018 | * Set up the rpc header and record marker stuff | | |
| 2019 | */ | | |
| 2020 | xs_encode_tcp_record_marker(xbufp); | | |
| 2021 | | 2329 | |
| 2022 | tailoff = (unsigned long)xbufp->tail[0].iov_base & ~PAGE_MASK; | 2330 | tailoff = (unsigned long)xbufp->tail[0].iov_base & ~PAGE_MASK; |
| 2023 | headoff = (unsigned long)xbufp->head[0].iov_base & ~PAGE_MASK; | 2331 | headoff = (unsigned long)xbufp->head[0].iov_base & ~PAGE_MASK; |
| @@ -2089,6 +2397,21 @@ static void bc_destroy(struct rpc_xprt *xprt) · 65 unmodified lines |
| 2089 | { | 2397 | { |
| 2090 | } | 2398 | } |
| 2091 | | 2399 | |
| | 2400 | static struct rpc_xprt_ops xs_local_ops = { |
| | 2401 | .reserve_xprt = xprt_reserve_xprt, |
| | 2402 | .release_xprt = xs_tcp_release_xprt, |
| | 2403 | .rpcbind = xs_local_rpcbind, |
| | 2404 | .set_port = xs_local_set_port, |
| | 2405 | .connect = xs_connect, |
| | 2406 | .buf_alloc = rpc_malloc, |
| | 2407 | .buf_free = rpc_free, |
| | 2408 | .send_request = xs_local_send_request, |
| | 2409 | .set_retrans_timeout = xprt_set_retrans_timeout_def, |
| | 2410 | .close = xs_close, |
| | 2411 | .destroy = xs_destroy, |
| | 2412 | .print_stats = xs_local_print_stats, |
| | 2413 | }; |
| | 2414 | |
| 2092 | static struct rpc_xprt_ops xs_udp_ops = { | 2415 | static struct rpc_xprt_ops xs_udp_ops = { |
| 2093 | .set_buffer_size = xs_udp_set_buffer_size, | 2416 | .set_buffer_size = xs_udp_set_buffer_size, |
| 2094 | .reserve_xprt = xprt_reserve_xprt_cong, | 2417 | .reserve_xprt = xprt_reserve_xprt_cong, |
| @@ -2150,6 +2473,8 @@ static int xs_init_anyaddr(const int family, struct sockaddr *sap) · 55 unmodified lines |
| 2150 | }; | 2473 | }; |
| 2151 | | 2474 | |
| 2152 | switch (family) { | 2475 | switch (family) { |
| | 2476 | case AF_LOCAL: |
| | 2477 | break; |
| 2153 | case AF_INET: | 2478 | case AF_INET: |
| 2154 | memcpy(sap, &sin, sizeof(sin)); | 2479 | memcpy(sap, &sin, sizeof(sin)); |
| 2155 | break; | 2480 | break; |
| @@ -2197,6 +2522,70 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, · 41 unmodified lines |
| 2197 | return xprt; | 2522 | return xprt; |
| 2198 | } | 2523 | } |
| 2199 | | 2524 | |
| | 2525 | static const struct rpc_timeout xs_local_default_timeout = { |
| | 2526 | .to_initval = 10 * HZ, |
| | 2527 | .to_maxval = 10 * HZ, |
| | 2528 | .to_retries = 2, |
| | 2529 | }; |
| | 2530 | |
| | 2531 | /** |
| | 2532 | * xs_setup_local - Set up transport to use an AF_LOCAL socket |
| | 2533 | * @args: rpc transport creation arguments |
| | 2534 | * |
| | 2535 | * AF_LOCAL is a "tpi_cots_ord" transport, just like TCP |
| | 2536 | */ |
| | 2537 | static struct rpc_xprt *xs_setup_local(struct xprt_create *args) |
| | 2538 | { |
| | 2539 | struct sockaddr_un *sun = (struct sockaddr_un *)args->dstaddr; |
| | 2540 | struct sock_xprt *transport; |
| | 2541 | struct rpc_xprt *xprt; |
| | 2542 | struct rpc_xprt *ret; |
| | 2543 | |
| | 2544 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); |
| | 2545 | if (IS_ERR(xprt)) |
| | 2546 | return xprt; |
| | 2547 | transport = container_of(xprt, struct sock_xprt, xprt); |
| | 2548 | |
| | 2549 | xprt->prot = 0; |
| | 2550 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); |
| | 2551 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; |
| | 2552 | |
| | 2553 | xprt->bind_timeout = XS_BIND_TO; |
| | 2554 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; |
| | 2555 | xprt->idle_timeout = XS_IDLE_DISC_TO; |
| | 2556 | |
| | 2557 | xprt->ops = &xs_local_ops; |
| | 2558 | xprt->timeout = &xs_local_default_timeout; |
| | 2559 | |
| | 2560 | switch (sun->sun_family) { |
| | 2561 | case AF_LOCAL: |
| | 2562 | if (sun->sun_path[0] != '/') { |
| | 2563 | dprintk("RPC: bad AF_LOCAL address: %s\n", |
| | 2564 | sun->sun_path); |
| | 2565 | ret = ERR_PTR(-EINVAL); |
| | 2566 | goto out_err; |
| | 2567 | } |
| | 2568 | xprt_set_bound(xprt); |
| | 2569 | INIT_DELAYED_WORK(&transport->connect_worker, |
| | 2570 | xs_local_setup_socket); |
| | 2571 | xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL); |
| | 2572 | break; |
| | 2573 | default: |
| | 2574 | ret = ERR_PTR(-EAFNOSUPPORT); |
| | 2575 | goto out_err; |
| | 2576 | } |
| | 2577 | |
| | 2578 | dprintk("RPC: set up xprt to %s via AF_LOCAL\n", |
| | 2579 | xprt->address_strings[RPC_DISPLAY_ADDR]); |
| | 2580 | |
| | 2581 | if (try_module_get(THIS_MODULE)) |
| | 2582 | return xprt; |
| | 2583 | ret = ERR_PTR(-EINVAL); |
| | 2584 | out_err: |
| | 2585 | xprt_free(xprt); |
| | 2586 | return ret; |
| | 2587 | } |
| | 2588 | |
| 2200 | static const struct rpc_timeout xs_udp_default_timeout = { | 2589 | static const struct rpc_timeout xs_udp_default_timeout = { |
| 2201 | .to_initval = 5 * HZ, | 2590 | .to_initval = 5 * HZ, |
| 2202 | .to_maxval = 30 * HZ, | 2591 | .to_maxval = 30 * HZ, |
| @@ -2438,6 +2827,14 @@ out_err: · 235 unmodified lines |
| 2438 | return ret; | 2827 | return ret; |
| 2439 | } | 2828 | } |
| 2440 | | 2829 | |
| | 2830 | static struct xprt_class xs_local_transport = { |
| | 2831 | .list = LIST_HEAD_INIT(xs_local_transport.list), |
| | 2832 | .name = "named UNIX socket", |
| | 2833 | .owner = THIS_MODULE, |
| | 2834 | .ident = XPRT_TRANSPORT_LOCAL, |
| | 2835 | .setup = xs_setup_local, |
| | 2836 | }; |
| | 2837 | |
| 2441 | static struct xprt_class xs_udp_transport = { | 2838 | static struct xprt_class xs_udp_transport = { |
| 2442 | .list = LIST_HEAD_INIT(xs_udp_transport.list), | 2839 | .list = LIST_HEAD_INIT(xs_udp_transport.list), |
| 2443 | .name = "udp", | 2840 | .name = "udp", |
| @@ -2473,6 +2870,7 @@ int init_socket_xprt(void) · 29 unmodified lines |
| 2473 | sunrpc_table_header = register_sysctl_table(sunrpc_table); | 2870 | sunrpc_table_header = register_sysctl_table(sunrpc_table); |
| 2474 | #endif | 2871 | #endif |
| 2475 | | 2872 | |
| | 2873 | xprt_register_transport(&xs_local_transport); |
| 2476 | xprt_register_transport(&xs_udp_transport); | 2874 | xprt_register_transport(&xs_udp_transport); |
| 2477 | xprt_register_transport(&xs_tcp_transport); | 2875 | xprt_register_transport(&xs_tcp_transport); |
| 2478 | xprt_register_transport(&xs_bc_tcp_transport); | 2876 | xprt_register_transport(&xs_bc_tcp_transport); |
| @@ -2493,6 +2891,7 @@ void cleanup_socket_xprt(void) · 14 unmodified lines |
| 2493 | } | 2891 | } |
| 2494 | #endif | 2892 | #endif |
| 2495 | | 2893 | |
| | 2894 | xprt_unregister_transport(&xs_local_transport); |
| 2496 | xprt_unregister_transport(&xs_udp_transport); | 2895 | xprt_unregister_transport(&xs_udp_transport); |
| 2497 | xprt_unregister_transport(&xs_tcp_transport); | 2896 | xprt_unregister_transport(&xs_tcp_transport); |
| 2498 | xprt_unregister_transport(&xs_bc_tcp_transport); | 2897 | xprt_unregister_transport(&xs_bc_tcp_transport); |