diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-26 12:55:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-26 12:55:25 -0400 |
commit | 4390110fef9e5c64e10c6ca19d586932242c9a8a (patch) | |
tree | f2f26fe291c8b4e424b97ac57370b33e0c006568 /net/sunrpc/xprtsock.c | |
parent | a4dd8dce14014665862ce7911b38cb2c69e366dd (diff) | |
parent | 42d7ba3d6d56a6cbc773284896108b1e2ebcee81 (diff) |
Merge branch 'for-2.6.37' of git://linux-nfs.org/~bfields/linux
* 'for-2.6.37' of git://linux-nfs.org/~bfields/linux: (99 commits)
svcrpc: svc_tcp_sendto XPT_DEAD check is redundant
svcrpc: no need for XPT_DEAD check in svc_xprt_enqueue
svcrpc: assume svc_delete_xprt() called only once
svcrpc: never clear XPT_BUSY on dead xprt
nfsd4: fix connection allocation in sequence()
nfsd4: only require krb5 principal for NFSv4.0 callbacks
nfsd4: move minorversion to client
nfsd4: delay session removal till free_client
nfsd4: separate callback change and callback probe
nfsd4: callback program number is per-session
nfsd4: track backchannel connections
nfsd4: confirm only on succesful create_session
nfsd4: make backchannel sequence number per-session
nfsd4: use client pointer to backchannel session
nfsd4: move callback setup into session init code
nfsd4: don't cache seq_misordered replies
SUNRPC: Properly initialize sock_xprt.srcaddr in all cases
SUNRPC: Use conventional switch statement when reclassifying sockets
sunrpc/xprtrdma: clean up workqueue usage
sunrpc: Turn list_for_each-s into the ..._entry-s
...
Fix up trivial conflicts (two different deprecation notices added in
separate branches) in Documentation/feature-removal-schedule.txt
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 358 |
1 files changed, 123 insertions, 235 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index fe9306bf10cc..dfcab5ac65af 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -774,8 +774,7 @@ static void xs_destroy(struct rpc_xprt *xprt) | |||
774 | 774 | ||
775 | xs_close(xprt); | 775 | xs_close(xprt); |
776 | xs_free_peer_addresses(xprt); | 776 | xs_free_peer_addresses(xprt); |
777 | kfree(xprt->slot); | 777 | xprt_free(xprt); |
778 | kfree(xprt); | ||
779 | module_put(THIS_MODULE); | 778 | module_put(THIS_MODULE); |
780 | } | 779 | } |
781 | 780 | ||
@@ -1516,7 +1515,7 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) | |||
1516 | xs_update_peer_port(xprt); | 1515 | xs_update_peer_port(xprt); |
1517 | } | 1516 | } |
1518 | 1517 | ||
1519 | static unsigned short xs_get_srcport(struct sock_xprt *transport, struct socket *sock) | 1518 | static unsigned short xs_get_srcport(struct sock_xprt *transport) |
1520 | { | 1519 | { |
1521 | unsigned short port = transport->srcport; | 1520 | unsigned short port = transport->srcport; |
1522 | 1521 | ||
@@ -1525,7 +1524,7 @@ static unsigned short xs_get_srcport(struct sock_xprt *transport, struct socket | |||
1525 | return port; | 1524 | return port; |
1526 | } | 1525 | } |
1527 | 1526 | ||
1528 | static unsigned short xs_next_srcport(struct sock_xprt *transport, struct socket *sock, unsigned short port) | 1527 | static unsigned short xs_next_srcport(struct sock_xprt *transport, unsigned short port) |
1529 | { | 1528 | { |
1530 | if (transport->srcport != 0) | 1529 | if (transport->srcport != 0) |
1531 | transport->srcport = 0; | 1530 | transport->srcport = 0; |
@@ -1535,23 +1534,18 @@ static unsigned short xs_next_srcport(struct sock_xprt *transport, struct socket | |||
1535 | return xprt_max_resvport; | 1534 | return xprt_max_resvport; |
1536 | return --port; | 1535 | return --port; |
1537 | } | 1536 | } |
1538 | 1537 | static int xs_bind(struct sock_xprt *transport, struct socket *sock) | |
1539 | static int xs_bind4(struct sock_xprt *transport, struct socket *sock) | ||
1540 | { | 1538 | { |
1541 | struct sockaddr_in myaddr = { | 1539 | struct sockaddr_storage myaddr; |
1542 | .sin_family = AF_INET, | ||
1543 | }; | ||
1544 | struct sockaddr_in *sa; | ||
1545 | int err, nloop = 0; | 1540 | int err, nloop = 0; |
1546 | unsigned short port = xs_get_srcport(transport, sock); | 1541 | unsigned short port = xs_get_srcport(transport); |
1547 | unsigned short last; | 1542 | unsigned short last; |
1548 | 1543 | ||
1549 | sa = (struct sockaddr_in *)&transport->srcaddr; | 1544 | memcpy(&myaddr, &transport->srcaddr, transport->xprt.addrlen); |
1550 | myaddr.sin_addr = sa->sin_addr; | ||
1551 | do { | 1545 | do { |
1552 | myaddr.sin_port = htons(port); | 1546 | rpc_set_port((struct sockaddr *)&myaddr, port); |
1553 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, | 1547 | err = kernel_bind(sock, (struct sockaddr *)&myaddr, |
1554 | sizeof(myaddr)); | 1548 | transport->xprt.addrlen); |
1555 | if (port == 0) | 1549 | if (port == 0) |
1556 | break; | 1550 | break; |
1557 | if (err == 0) { | 1551 | if (err == 0) { |
@@ -1559,48 +1553,23 @@ static int xs_bind4(struct sock_xprt *transport, struct socket *sock) | |||
1559 | break; | 1553 | break; |
1560 | } | 1554 | } |
1561 | last = port; | 1555 | last = port; |
1562 | port = xs_next_srcport(transport, sock, port); | 1556 | port = xs_next_srcport(transport, port); |
1563 | if (port > last) | 1557 | if (port > last) |
1564 | nloop++; | 1558 | nloop++; |
1565 | } while (err == -EADDRINUSE && nloop != 2); | 1559 | } while (err == -EADDRINUSE && nloop != 2); |
1566 | dprintk("RPC: %s %pI4:%u: %s (%d)\n", | ||
1567 | __func__, &myaddr.sin_addr, | ||
1568 | port, err ? "failed" : "ok", err); | ||
1569 | return err; | ||
1570 | } | ||
1571 | |||
1572 | static int xs_bind6(struct sock_xprt *transport, struct socket *sock) | ||
1573 | { | ||
1574 | struct sockaddr_in6 myaddr = { | ||
1575 | .sin6_family = AF_INET6, | ||
1576 | }; | ||
1577 | struct sockaddr_in6 *sa; | ||
1578 | int err, nloop = 0; | ||
1579 | unsigned short port = xs_get_srcport(transport, sock); | ||
1580 | unsigned short last; | ||
1581 | 1560 | ||
1582 | sa = (struct sockaddr_in6 *)&transport->srcaddr; | 1561 | if (myaddr.ss_family == AF_INET) |
1583 | myaddr.sin6_addr = sa->sin6_addr; | 1562 | dprintk("RPC: %s %pI4:%u: %s (%d)\n", __func__, |
1584 | do { | 1563 | &((struct sockaddr_in *)&myaddr)->sin_addr, |
1585 | myaddr.sin6_port = htons(port); | 1564 | port, err ? "failed" : "ok", err); |
1586 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, | 1565 | else |
1587 | sizeof(myaddr)); | 1566 | dprintk("RPC: %s %pI6:%u: %s (%d)\n", __func__, |
1588 | if (port == 0) | 1567 | &((struct sockaddr_in6 *)&myaddr)->sin6_addr, |
1589 | break; | 1568 | port, err ? "failed" : "ok", err); |
1590 | if (err == 0) { | ||
1591 | transport->srcport = port; | ||
1592 | break; | ||
1593 | } | ||
1594 | last = port; | ||
1595 | port = xs_next_srcport(transport, sock, port); | ||
1596 | if (port > last) | ||
1597 | nloop++; | ||
1598 | } while (err == -EADDRINUSE && nloop != 2); | ||
1599 | dprintk("RPC: xs_bind6 %pI6:%u: %s (%d)\n", | ||
1600 | &myaddr.sin6_addr, port, err ? "failed" : "ok", err); | ||
1601 | return err; | 1569 | return err; |
1602 | } | 1570 | } |
1603 | 1571 | ||
1572 | |||
1604 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 1573 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
1605 | static struct lock_class_key xs_key[2]; | 1574 | static struct lock_class_key xs_key[2]; |
1606 | static struct lock_class_key xs_slock_key[2]; | 1575 | static struct lock_class_key xs_slock_key[2]; |
@@ -1622,6 +1591,18 @@ static inline void xs_reclassify_socket6(struct socket *sock) | |||
1622 | sock_lock_init_class_and_name(sk, "slock-AF_INET6-RPC", | 1591 | sock_lock_init_class_and_name(sk, "slock-AF_INET6-RPC", |
1623 | &xs_slock_key[1], "sk_lock-AF_INET6-RPC", &xs_key[1]); | 1592 | &xs_slock_key[1], "sk_lock-AF_INET6-RPC", &xs_key[1]); |
1624 | } | 1593 | } |
1594 | |||
1595 | static inline void xs_reclassify_socket(int family, struct socket *sock) | ||
1596 | { | ||
1597 | switch (family) { | ||
1598 | case AF_INET: | ||
1599 | xs_reclassify_socket4(sock); | ||
1600 | break; | ||
1601 | case AF_INET6: | ||
1602 | xs_reclassify_socket6(sock); | ||
1603 | break; | ||
1604 | } | ||
1605 | } | ||
1625 | #else | 1606 | #else |
1626 | static inline void xs_reclassify_socket4(struct socket *sock) | 1607 | static inline void xs_reclassify_socket4(struct socket *sock) |
1627 | { | 1608 | { |
@@ -1630,8 +1611,36 @@ static inline void xs_reclassify_socket4(struct socket *sock) | |||
1630 | static inline void xs_reclassify_socket6(struct socket *sock) | 1611 | static inline void xs_reclassify_socket6(struct socket *sock) |
1631 | { | 1612 | { |
1632 | } | 1613 | } |
1614 | |||
1615 | static inline void xs_reclassify_socket(int family, struct socket *sock) | ||
1616 | { | ||
1617 | } | ||
1633 | #endif | 1618 | #endif |
1634 | 1619 | ||
1620 | static struct socket *xs_create_sock(struct rpc_xprt *xprt, | ||
1621 | struct sock_xprt *transport, int family, int type, int protocol) | ||
1622 | { | ||
1623 | struct socket *sock; | ||
1624 | int err; | ||
1625 | |||
1626 | err = __sock_create(xprt->xprt_net, family, type, protocol, &sock, 1); | ||
1627 | if (err < 0) { | ||
1628 | dprintk("RPC: can't create %d transport socket (%d).\n", | ||
1629 | protocol, -err); | ||
1630 | goto out; | ||
1631 | } | ||
1632 | xs_reclassify_socket(family, sock); | ||
1633 | |||
1634 | if (xs_bind(transport, sock)) { | ||
1635 | sock_release(sock); | ||
1636 | goto out; | ||
1637 | } | ||
1638 | |||
1639 | return sock; | ||
1640 | out: | ||
1641 | return ERR_PTR(err); | ||
1642 | } | ||
1643 | |||
1635 | static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 1644 | static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
1636 | { | 1645 | { |
1637 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 1646 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -1661,82 +1670,23 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
1661 | xs_udp_do_set_buffer_size(xprt); | 1670 | xs_udp_do_set_buffer_size(xprt); |
1662 | } | 1671 | } |
1663 | 1672 | ||
1664 | /** | 1673 | static void xs_udp_setup_socket(struct work_struct *work) |
1665 | * xs_udp_connect_worker4 - set up a UDP socket | ||
1666 | * @work: RPC transport to connect | ||
1667 | * | ||
1668 | * Invoked by a work queue tasklet. | ||
1669 | */ | ||
1670 | static void xs_udp_connect_worker4(struct work_struct *work) | ||
1671 | { | 1674 | { |
1672 | struct sock_xprt *transport = | 1675 | struct sock_xprt *transport = |
1673 | container_of(work, struct sock_xprt, connect_worker.work); | 1676 | container_of(work, struct sock_xprt, connect_worker.work); |
1674 | struct rpc_xprt *xprt = &transport->xprt; | 1677 | struct rpc_xprt *xprt = &transport->xprt; |
1675 | struct socket *sock = transport->sock; | 1678 | struct socket *sock = transport->sock; |
1676 | int err, status = -EIO; | 1679 | int status = -EIO; |
1677 | 1680 | ||
1678 | if (xprt->shutdown) | 1681 | if (xprt->shutdown) |
1679 | goto out; | 1682 | goto out; |
1680 | 1683 | ||
1681 | /* Start by resetting any existing state */ | 1684 | /* Start by resetting any existing state */ |
1682 | xs_reset_transport(transport); | 1685 | xs_reset_transport(transport); |
1683 | 1686 | sock = xs_create_sock(xprt, transport, | |
1684 | err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock); | 1687 | xs_addr(xprt)->sa_family, SOCK_DGRAM, IPPROTO_UDP); |
1685 | if (err < 0) { | 1688 | if (IS_ERR(sock)) |
1686 | dprintk("RPC: can't create UDP transport socket (%d).\n", -err); | ||
1687 | goto out; | 1689 | goto out; |
1688 | } | ||
1689 | xs_reclassify_socket4(sock); | ||
1690 | |||
1691 | if (xs_bind4(transport, sock)) { | ||
1692 | sock_release(sock); | ||
1693 | goto out; | ||
1694 | } | ||
1695 | |||
1696 | dprintk("RPC: worker connecting xprt %p via %s to " | ||
1697 | "%s (port %s)\n", xprt, | ||
1698 | xprt->address_strings[RPC_DISPLAY_PROTO], | ||
1699 | xprt->address_strings[RPC_DISPLAY_ADDR], | ||
1700 | xprt->address_strings[RPC_DISPLAY_PORT]); | ||
1701 | |||
1702 | xs_udp_finish_connecting(xprt, sock); | ||
1703 | status = 0; | ||
1704 | out: | ||
1705 | xprt_clear_connecting(xprt); | ||
1706 | xprt_wake_pending_tasks(xprt, status); | ||
1707 | } | ||
1708 | |||
1709 | /** | ||
1710 | * xs_udp_connect_worker6 - set up a UDP socket | ||
1711 | * @work: RPC transport to connect | ||
1712 | * | ||
1713 | * Invoked by a work queue tasklet. | ||
1714 | */ | ||
1715 | static void xs_udp_connect_worker6(struct work_struct *work) | ||
1716 | { | ||
1717 | struct sock_xprt *transport = | ||
1718 | container_of(work, struct sock_xprt, connect_worker.work); | ||
1719 | struct rpc_xprt *xprt = &transport->xprt; | ||
1720 | struct socket *sock = transport->sock; | ||
1721 | int err, status = -EIO; | ||
1722 | |||
1723 | if (xprt->shutdown) | ||
1724 | goto out; | ||
1725 | |||
1726 | /* Start by resetting any existing state */ | ||
1727 | xs_reset_transport(transport); | ||
1728 | |||
1729 | err = sock_create_kern(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, &sock); | ||
1730 | if (err < 0) { | ||
1731 | dprintk("RPC: can't create UDP transport socket (%d).\n", -err); | ||
1732 | goto out; | ||
1733 | } | ||
1734 | xs_reclassify_socket6(sock); | ||
1735 | |||
1736 | if (xs_bind6(transport, sock) < 0) { | ||
1737 | sock_release(sock); | ||
1738 | goto out; | ||
1739 | } | ||
1740 | 1690 | ||
1741 | dprintk("RPC: worker connecting xprt %p via %s to " | 1691 | dprintk("RPC: worker connecting xprt %p via %s to " |
1742 | "%s (port %s)\n", xprt, | 1692 | "%s (port %s)\n", xprt, |
@@ -1755,12 +1705,12 @@ out: | |||
1755 | * We need to preserve the port number so the reply cache on the server can | 1705 | * We need to preserve the port number so the reply cache on the server can |
1756 | * find our cached RPC replies when we get around to reconnecting. | 1706 | * find our cached RPC replies when we get around to reconnecting. |
1757 | */ | 1707 | */ |
1758 | static void xs_abort_connection(struct rpc_xprt *xprt, struct sock_xprt *transport) | 1708 | static void xs_abort_connection(struct sock_xprt *transport) |
1759 | { | 1709 | { |
1760 | int result; | 1710 | int result; |
1761 | struct sockaddr any; | 1711 | struct sockaddr any; |
1762 | 1712 | ||
1763 | dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt); | 1713 | dprintk("RPC: disconnecting xprt %p to reuse port\n", transport); |
1764 | 1714 | ||
1765 | /* | 1715 | /* |
1766 | * Disconnect the transport socket by doing a connect operation | 1716 | * Disconnect the transport socket by doing a connect operation |
@@ -1770,13 +1720,13 @@ static void xs_abort_connection(struct rpc_xprt *xprt, struct sock_xprt *transpo | |||
1770 | any.sa_family = AF_UNSPEC; | 1720 | any.sa_family = AF_UNSPEC; |
1771 | result = kernel_connect(transport->sock, &any, sizeof(any), 0); | 1721 | result = kernel_connect(transport->sock, &any, sizeof(any), 0); |
1772 | if (!result) | 1722 | if (!result) |
1773 | xs_sock_mark_closed(xprt); | 1723 | xs_sock_mark_closed(&transport->xprt); |
1774 | else | 1724 | else |
1775 | dprintk("RPC: AF_UNSPEC connect return code %d\n", | 1725 | dprintk("RPC: AF_UNSPEC connect return code %d\n", |
1776 | result); | 1726 | result); |
1777 | } | 1727 | } |
1778 | 1728 | ||
1779 | static void xs_tcp_reuse_connection(struct rpc_xprt *xprt, struct sock_xprt *transport) | 1729 | static void xs_tcp_reuse_connection(struct sock_xprt *transport) |
1780 | { | 1730 | { |
1781 | unsigned int state = transport->inet->sk_state; | 1731 | unsigned int state = transport->inet->sk_state; |
1782 | 1732 | ||
@@ -1799,7 +1749,7 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt, struct sock_xprt *tra | |||
1799 | "sk_shutdown set to %d\n", | 1749 | "sk_shutdown set to %d\n", |
1800 | __func__, transport->inet->sk_shutdown); | 1750 | __func__, transport->inet->sk_shutdown); |
1801 | } | 1751 | } |
1802 | xs_abort_connection(xprt, transport); | 1752 | xs_abort_connection(transport); |
1803 | } | 1753 | } |
1804 | 1754 | ||
1805 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 1755 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
@@ -1852,12 +1802,12 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
1852 | * | 1802 | * |
1853 | * Invoked by a work queue tasklet. | 1803 | * Invoked by a work queue tasklet. |
1854 | */ | 1804 | */ |
1855 | static void xs_tcp_setup_socket(struct rpc_xprt *xprt, | 1805 | static void xs_tcp_setup_socket(struct work_struct *work) |
1856 | struct sock_xprt *transport, | ||
1857 | struct socket *(*create_sock)(struct rpc_xprt *, | ||
1858 | struct sock_xprt *)) | ||
1859 | { | 1806 | { |
1807 | struct sock_xprt *transport = | ||
1808 | container_of(work, struct sock_xprt, connect_worker.work); | ||
1860 | struct socket *sock = transport->sock; | 1809 | struct socket *sock = transport->sock; |
1810 | struct rpc_xprt *xprt = &transport->xprt; | ||
1861 | int status = -EIO; | 1811 | int status = -EIO; |
1862 | 1812 | ||
1863 | if (xprt->shutdown) | 1813 | if (xprt->shutdown) |
@@ -1865,7 +1815,8 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt, | |||
1865 | 1815 | ||
1866 | if (!sock) { | 1816 | if (!sock) { |
1867 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); | 1817 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); |
1868 | sock = create_sock(xprt, transport); | 1818 | sock = xs_create_sock(xprt, transport, |
1819 | xs_addr(xprt)->sa_family, SOCK_STREAM, IPPROTO_TCP); | ||
1869 | if (IS_ERR(sock)) { | 1820 | if (IS_ERR(sock)) { |
1870 | status = PTR_ERR(sock); | 1821 | status = PTR_ERR(sock); |
1871 | goto out; | 1822 | goto out; |
@@ -1876,7 +1827,7 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt, | |||
1876 | abort_and_exit = test_and_clear_bit(XPRT_CONNECTION_ABORT, | 1827 | abort_and_exit = test_and_clear_bit(XPRT_CONNECTION_ABORT, |
1877 | &xprt->state); | 1828 | &xprt->state); |
1878 | /* "close" the socket, preserving the local port */ | 1829 | /* "close" the socket, preserving the local port */ |
1879 | xs_tcp_reuse_connection(xprt, transport); | 1830 | xs_tcp_reuse_connection(transport); |
1880 | 1831 | ||
1881 | if (abort_and_exit) | 1832 | if (abort_and_exit) |
1882 | goto out_eagain; | 1833 | goto out_eagain; |
@@ -1925,84 +1876,6 @@ out: | |||
1925 | xprt_wake_pending_tasks(xprt, status); | 1876 | xprt_wake_pending_tasks(xprt, status); |
1926 | } | 1877 | } |
1927 | 1878 | ||
1928 | static struct socket *xs_create_tcp_sock4(struct rpc_xprt *xprt, | ||
1929 | struct sock_xprt *transport) | ||
1930 | { | ||
1931 | struct socket *sock; | ||
1932 | int err; | ||
1933 | |||
1934 | /* start from scratch */ | ||
1935 | err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); | ||
1936 | if (err < 0) { | ||
1937 | dprintk("RPC: can't create TCP transport socket (%d).\n", | ||
1938 | -err); | ||
1939 | goto out_err; | ||
1940 | } | ||
1941 | xs_reclassify_socket4(sock); | ||
1942 | |||
1943 | if (xs_bind4(transport, sock) < 0) { | ||
1944 | sock_release(sock); | ||
1945 | goto out_err; | ||
1946 | } | ||
1947 | return sock; | ||
1948 | out_err: | ||
1949 | return ERR_PTR(-EIO); | ||
1950 | } | ||
1951 | |||
1952 | /** | ||
1953 | * xs_tcp_connect_worker4 - connect a TCP socket to a remote endpoint | ||
1954 | * @work: RPC transport to connect | ||
1955 | * | ||
1956 | * Invoked by a work queue tasklet. | ||
1957 | */ | ||
1958 | static void xs_tcp_connect_worker4(struct work_struct *work) | ||
1959 | { | ||
1960 | struct sock_xprt *transport = | ||
1961 | container_of(work, struct sock_xprt, connect_worker.work); | ||
1962 | struct rpc_xprt *xprt = &transport->xprt; | ||
1963 | |||
1964 | xs_tcp_setup_socket(xprt, transport, xs_create_tcp_sock4); | ||
1965 | } | ||
1966 | |||
1967 | static struct socket *xs_create_tcp_sock6(struct rpc_xprt *xprt, | ||
1968 | struct sock_xprt *transport) | ||
1969 | { | ||
1970 | struct socket *sock; | ||
1971 | int err; | ||
1972 | |||
1973 | /* start from scratch */ | ||
1974 | err = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, &sock); | ||
1975 | if (err < 0) { | ||
1976 | dprintk("RPC: can't create TCP transport socket (%d).\n", | ||
1977 | -err); | ||
1978 | goto out_err; | ||
1979 | } | ||
1980 | xs_reclassify_socket6(sock); | ||
1981 | |||
1982 | if (xs_bind6(transport, sock) < 0) { | ||
1983 | sock_release(sock); | ||
1984 | goto out_err; | ||
1985 | } | ||
1986 | return sock; | ||
1987 | out_err: | ||
1988 | return ERR_PTR(-EIO); | ||
1989 | } | ||
1990 | |||
1991 | /** | ||
1992 | * xs_tcp_connect_worker6 - connect a TCP socket to a remote endpoint | ||
1993 | * @work: RPC transport to connect | ||
1994 | * | ||
1995 | * Invoked by a work queue tasklet. | ||
1996 | */ | ||
1997 | static void xs_tcp_connect_worker6(struct work_struct *work) | ||
1998 | { | ||
1999 | struct sock_xprt *transport = | ||
2000 | container_of(work, struct sock_xprt, connect_worker.work); | ||
2001 | struct rpc_xprt *xprt = &transport->xprt; | ||
2002 | |||
2003 | xs_tcp_setup_socket(xprt, transport, xs_create_tcp_sock6); | ||
2004 | } | ||
2005 | |||
2006 | /** | 1879 | /** |
2007 | * xs_connect - connect a socket to a remote endpoint | 1880 | * xs_connect - connect a socket to a remote endpoint |
2008 | * @task: address of RPC task that manages state of connect request | 1881 | * @task: address of RPC task that manages state of connect request |
@@ -2262,6 +2135,31 @@ static struct rpc_xprt_ops bc_tcp_ops = { | |||
2262 | .print_stats = xs_tcp_print_stats, | 2135 | .print_stats = xs_tcp_print_stats, |
2263 | }; | 2136 | }; |
2264 | 2137 | ||
2138 | static int xs_init_anyaddr(const int family, struct sockaddr *sap) | ||
2139 | { | ||
2140 | static const struct sockaddr_in sin = { | ||
2141 | .sin_family = AF_INET, | ||
2142 | .sin_addr.s_addr = htonl(INADDR_ANY), | ||
2143 | }; | ||
2144 | static const struct sockaddr_in6 sin6 = { | ||
2145 | .sin6_family = AF_INET6, | ||
2146 | .sin6_addr = IN6ADDR_ANY_INIT, | ||
2147 | }; | ||
2148 | |||
2149 | switch (family) { | ||
2150 | case AF_INET: | ||
2151 | memcpy(sap, &sin, sizeof(sin)); | ||
2152 | break; | ||
2153 | case AF_INET6: | ||
2154 | memcpy(sap, &sin6, sizeof(sin6)); | ||
2155 | break; | ||
2156 | default: | ||
2157 | dprintk("RPC: %s: Bad address family\n", __func__); | ||
2158 | return -EAFNOSUPPORT; | ||
2159 | } | ||
2160 | return 0; | ||
2161 | } | ||
2162 | |||
2265 | static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | 2163 | static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, |
2266 | unsigned int slot_table_size) | 2164 | unsigned int slot_table_size) |
2267 | { | 2165 | { |
@@ -2273,27 +2171,25 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | |||
2273 | return ERR_PTR(-EBADF); | 2171 | return ERR_PTR(-EBADF); |
2274 | } | 2172 | } |
2275 | 2173 | ||
2276 | new = kzalloc(sizeof(*new), GFP_KERNEL); | 2174 | xprt = xprt_alloc(args->net, sizeof(*new), slot_table_size); |
2277 | if (new == NULL) { | 2175 | if (xprt == NULL) { |
2278 | dprintk("RPC: xs_setup_xprt: couldn't allocate " | 2176 | dprintk("RPC: xs_setup_xprt: couldn't allocate " |
2279 | "rpc_xprt\n"); | 2177 | "rpc_xprt\n"); |
2280 | return ERR_PTR(-ENOMEM); | 2178 | return ERR_PTR(-ENOMEM); |
2281 | } | 2179 | } |
2282 | xprt = &new->xprt; | ||
2283 | |||
2284 | xprt->max_reqs = slot_table_size; | ||
2285 | xprt->slot = kcalloc(xprt->max_reqs, sizeof(struct rpc_rqst), GFP_KERNEL); | ||
2286 | if (xprt->slot == NULL) { | ||
2287 | kfree(xprt); | ||
2288 | dprintk("RPC: xs_setup_xprt: couldn't allocate slot " | ||
2289 | "table\n"); | ||
2290 | return ERR_PTR(-ENOMEM); | ||
2291 | } | ||
2292 | 2180 | ||
2181 | new = container_of(xprt, struct sock_xprt, xprt); | ||
2293 | memcpy(&xprt->addr, args->dstaddr, args->addrlen); | 2182 | memcpy(&xprt->addr, args->dstaddr, args->addrlen); |
2294 | xprt->addrlen = args->addrlen; | 2183 | xprt->addrlen = args->addrlen; |
2295 | if (args->srcaddr) | 2184 | if (args->srcaddr) |
2296 | memcpy(&new->srcaddr, args->srcaddr, args->addrlen); | 2185 | memcpy(&new->srcaddr, args->srcaddr, args->addrlen); |
2186 | else { | ||
2187 | int err; | ||
2188 | err = xs_init_anyaddr(args->dstaddr->sa_family, | ||
2189 | (struct sockaddr *)&new->srcaddr); | ||
2190 | if (err != 0) | ||
2191 | return ERR_PTR(err); | ||
2192 | } | ||
2297 | 2193 | ||
2298 | return xprt; | 2194 | return xprt; |
2299 | } | 2195 | } |
@@ -2341,7 +2237,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
2341 | xprt_set_bound(xprt); | 2237 | xprt_set_bound(xprt); |
2342 | 2238 | ||
2343 | INIT_DELAYED_WORK(&transport->connect_worker, | 2239 | INIT_DELAYED_WORK(&transport->connect_worker, |
2344 | xs_udp_connect_worker4); | 2240 | xs_udp_setup_socket); |
2345 | xs_format_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP); | 2241 | xs_format_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP); |
2346 | break; | 2242 | break; |
2347 | case AF_INET6: | 2243 | case AF_INET6: |
@@ -2349,7 +2245,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
2349 | xprt_set_bound(xprt); | 2245 | xprt_set_bound(xprt); |
2350 | 2246 | ||
2351 | INIT_DELAYED_WORK(&transport->connect_worker, | 2247 | INIT_DELAYED_WORK(&transport->connect_worker, |
2352 | xs_udp_connect_worker6); | 2248 | xs_udp_setup_socket); |
2353 | xs_format_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP6); | 2249 | xs_format_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP6); |
2354 | break; | 2250 | break; |
2355 | default: | 2251 | default: |
@@ -2371,8 +2267,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
2371 | return xprt; | 2267 | return xprt; |
2372 | ret = ERR_PTR(-EINVAL); | 2268 | ret = ERR_PTR(-EINVAL); |
2373 | out_err: | 2269 | out_err: |
2374 | kfree(xprt->slot); | 2270 | xprt_free(xprt); |
2375 | kfree(xprt); | ||
2376 | return ret; | 2271 | return ret; |
2377 | } | 2272 | } |
2378 | 2273 | ||
@@ -2416,7 +2311,7 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
2416 | xprt_set_bound(xprt); | 2311 | xprt_set_bound(xprt); |
2417 | 2312 | ||
2418 | INIT_DELAYED_WORK(&transport->connect_worker, | 2313 | INIT_DELAYED_WORK(&transport->connect_worker, |
2419 | xs_tcp_connect_worker4); | 2314 | xs_tcp_setup_socket); |
2420 | xs_format_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP); | 2315 | xs_format_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP); |
2421 | break; | 2316 | break; |
2422 | case AF_INET6: | 2317 | case AF_INET6: |
@@ -2424,7 +2319,7 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
2424 | xprt_set_bound(xprt); | 2319 | xprt_set_bound(xprt); |
2425 | 2320 | ||
2426 | INIT_DELAYED_WORK(&transport->connect_worker, | 2321 | INIT_DELAYED_WORK(&transport->connect_worker, |
2427 | xs_tcp_connect_worker6); | 2322 | xs_tcp_setup_socket); |
2428 | xs_format_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP6); | 2323 | xs_format_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP6); |
2429 | break; | 2324 | break; |
2430 | default: | 2325 | default: |
@@ -2447,8 +2342,7 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
2447 | return xprt; | 2342 | return xprt; |
2448 | ret = ERR_PTR(-EINVAL); | 2343 | ret = ERR_PTR(-EINVAL); |
2449 | out_err: | 2344 | out_err: |
2450 | kfree(xprt->slot); | 2345 | xprt_free(xprt); |
2451 | kfree(xprt); | ||
2452 | return ret; | 2346 | return ret; |
2453 | } | 2347 | } |
2454 | 2348 | ||
@@ -2507,15 +2401,10 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
2507 | goto out_err; | 2401 | goto out_err; |
2508 | } | 2402 | } |
2509 | 2403 | ||
2510 | if (xprt_bound(xprt)) | 2404 | dprintk("RPC: set up xprt to %s (port %s) via %s\n", |
2511 | dprintk("RPC: set up xprt to %s (port %s) via %s\n", | 2405 | xprt->address_strings[RPC_DISPLAY_ADDR], |
2512 | xprt->address_strings[RPC_DISPLAY_ADDR], | 2406 | xprt->address_strings[RPC_DISPLAY_PORT], |
2513 | xprt->address_strings[RPC_DISPLAY_PORT], | 2407 | xprt->address_strings[RPC_DISPLAY_PROTO]); |
2514 | xprt->address_strings[RPC_DISPLAY_PROTO]); | ||
2515 | else | ||
2516 | dprintk("RPC: set up xprt to %s (autobind) via %s\n", | ||
2517 | xprt->address_strings[RPC_DISPLAY_ADDR], | ||
2518 | xprt->address_strings[RPC_DISPLAY_PROTO]); | ||
2519 | 2408 | ||
2520 | /* | 2409 | /* |
2521 | * Since we don't want connections for the backchannel, we set | 2410 | * Since we don't want connections for the backchannel, we set |
@@ -2528,8 +2417,7 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
2528 | return xprt; | 2417 | return xprt; |
2529 | ret = ERR_PTR(-EINVAL); | 2418 | ret = ERR_PTR(-EINVAL); |
2530 | out_err: | 2419 | out_err: |
2531 | kfree(xprt->slot); | 2420 | xprt_free(xprt); |
2532 | kfree(xprt); | ||
2533 | return ret; | 2421 | return ret; |
2534 | } | 2422 | } |
2535 | 2423 | ||