diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-03-11 14:38:04 -0400 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-03-19 15:17:35 -0400 |
| commit | b61d59fffd3e5b6037c92b4c840605831de8a251 (patch) | |
| tree | 329bfecb1c8c66364e7b2797c51eab779ee2540d /net/sunrpc | |
| parent | 25fe6142a57c720452c5e9ddbc1f32309c1e5c19 (diff) | |
SUNRPC: xs_tcp_connect_worker{4,6}: merge common code
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
| -rw-r--r-- | net/sunrpc/xprtsock.c | 140 |
1 files changed, 72 insertions, 68 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 42222b4dd76d..f05a56e597ef 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -1738,33 +1738,29 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
| 1738 | } | 1738 | } |
| 1739 | 1739 | ||
| 1740 | /** | 1740 | /** |
| 1741 | * xs_tcp_connect_worker4 - connect a TCP socket to a remote endpoint | 1741 | * xs_tcp_setup_socket - create a TCP socket and connect to a remote endpoint |
| 1742 | * @work: RPC transport to connect | 1742 | * @xprt: RPC transport to connect |
| 1743 | * @transport: socket transport to connect | ||
| 1744 | * @create_sock: function to create a socket of the correct type | ||
| 1743 | * | 1745 | * |
| 1744 | * Invoked by a work queue tasklet. | 1746 | * Invoked by a work queue tasklet. |
| 1745 | */ | 1747 | */ |
| 1746 | static void xs_tcp_connect_worker4(struct work_struct *work) | 1748 | static void xs_tcp_setup_socket(struct rpc_xprt *xprt, |
| 1749 | struct sock_xprt *transport, | ||
| 1750 | struct socket *(*create_sock)(struct rpc_xprt *, | ||
| 1751 | struct sock_xprt *)) | ||
| 1747 | { | 1752 | { |
| 1748 | struct sock_xprt *transport = | ||
| 1749 | container_of(work, struct sock_xprt, connect_worker.work); | ||
| 1750 | struct rpc_xprt *xprt = &transport->xprt; | ||
| 1751 | struct socket *sock = transport->sock; | 1753 | struct socket *sock = transport->sock; |
| 1752 | int err, status = -EIO; | 1754 | int status = -EIO; |
| 1753 | 1755 | ||
| 1754 | if (xprt->shutdown) | 1756 | if (xprt->shutdown) |
| 1755 | goto out; | 1757 | goto out; |
| 1756 | 1758 | ||
| 1757 | if (!sock) { | 1759 | if (!sock) { |
| 1758 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); | 1760 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); |
| 1759 | /* start from scratch */ | 1761 | sock = create_sock(xprt, transport); |
| 1760 | if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { | 1762 | if (IS_ERR(sock)) { |
| 1761 | dprintk("RPC: can't create TCP transport socket (%d).\n", -err); | 1763 | status = PTR_ERR(sock); |
| 1762 | goto out; | ||
| 1763 | } | ||
| 1764 | xs_reclassify_socket4(sock); | ||
| 1765 | |||
| 1766 | if (xs_bind4(transport, sock) < 0) { | ||
| 1767 | sock_release(sock); | ||
| 1768 | goto out; | 1764 | goto out; |
| 1769 | } | 1765 | } |
| 1770 | } else { | 1766 | } else { |
| @@ -1808,74 +1804,82 @@ out: | |||
| 1808 | xprt_wake_pending_tasks(xprt, status); | 1804 | xprt_wake_pending_tasks(xprt, status); |
| 1809 | } | 1805 | } |
| 1810 | 1806 | ||
| 1807 | static struct socket *xs_create_tcp_sock4(struct rpc_xprt *xprt, | ||
| 1808 | struct sock_xprt *transport) | ||
| 1809 | { | ||
| 1810 | struct socket *sock; | ||
| 1811 | int err; | ||
| 1812 | |||
| 1813 | /* start from scratch */ | ||
| 1814 | err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); | ||
| 1815 | if (err < 0) { | ||
| 1816 | dprintk("RPC: can't create TCP transport socket (%d).\n", | ||
| 1817 | -err); | ||
| 1818 | goto out_err; | ||
| 1819 | } | ||
| 1820 | xs_reclassify_socket4(sock); | ||
| 1821 | |||
| 1822 | if (xs_bind4(transport, sock) < 0) { | ||
| 1823 | sock_release(sock); | ||
| 1824 | goto out_err; | ||
| 1825 | } | ||
| 1826 | return sock; | ||
| 1827 | out_err: | ||
| 1828 | return ERR_PTR(-EIO); | ||
| 1829 | } | ||
| 1830 | |||
| 1811 | /** | 1831 | /** |
| 1812 | * xs_tcp_connect_worker6 - connect a TCP socket to a remote endpoint | 1832 | * xs_tcp_connect_worker4 - connect a TCP socket to a remote endpoint |
| 1813 | * @work: RPC transport to connect | 1833 | * @work: RPC transport to connect |
| 1814 | * | 1834 | * |
| 1815 | * Invoked by a work queue tasklet. | 1835 | * Invoked by a work queue tasklet. |
| 1816 | */ | 1836 | */ |
| 1817 | static void xs_tcp_connect_worker6(struct work_struct *work) | 1837 | static void xs_tcp_connect_worker4(struct work_struct *work) |
| 1818 | { | 1838 | { |
| 1819 | struct sock_xprt *transport = | 1839 | struct sock_xprt *transport = |
| 1820 | container_of(work, struct sock_xprt, connect_worker.work); | 1840 | container_of(work, struct sock_xprt, connect_worker.work); |
| 1821 | struct rpc_xprt *xprt = &transport->xprt; | 1841 | struct rpc_xprt *xprt = &transport->xprt; |
| 1822 | struct socket *sock = transport->sock; | ||
| 1823 | int err, status = -EIO; | ||
| 1824 | 1842 | ||
| 1825 | if (xprt->shutdown) | 1843 | xs_tcp_setup_socket(xprt, transport, xs_create_tcp_sock4); |
| 1826 | goto out; | 1844 | } |
| 1827 | |||
| 1828 | if (!sock) { | ||
| 1829 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); | ||
| 1830 | /* start from scratch */ | ||
| 1831 | if ((err = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { | ||
| 1832 | dprintk("RPC: can't create TCP transport socket (%d).\n", -err); | ||
| 1833 | goto out; | ||
| 1834 | } | ||
| 1835 | xs_reclassify_socket6(sock); | ||
| 1836 | 1845 | ||
| 1837 | if (xs_bind6(transport, sock) < 0) { | 1846 | static struct socket *xs_create_tcp_sock6(struct rpc_xprt *xprt, |
| 1838 | sock_release(sock); | 1847 | struct sock_xprt *transport) |
| 1839 | goto out; | 1848 | { |
| 1840 | } | 1849 | struct socket *sock; |
| 1841 | } else { | 1850 | int err; |
| 1842 | int abort_and_exit; | ||
| 1843 | 1851 | ||
| 1844 | abort_and_exit = test_and_clear_bit(XPRT_CONNECTION_ABORT, | 1852 | /* start from scratch */ |
| 1845 | &xprt->state); | 1853 | err = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, &sock); |
| 1846 | /* "close" the socket, preserving the local port */ | 1854 | if (err < 0) { |
| 1847 | xs_tcp_reuse_connection(xprt, transport); | 1855 | dprintk("RPC: can't create TCP transport socket (%d).\n", |
| 1856 | -err); | ||
| 1857 | goto out_err; | ||
| 1858 | } | ||
| 1859 | xs_reclassify_socket6(sock); | ||
| 1848 | 1860 | ||
| 1849 | if (abort_and_exit) | 1861 | if (xs_bind6(transport, sock) < 0) { |
| 1850 | goto out_eagain; | 1862 | sock_release(sock); |
| 1863 | goto out_err; | ||
| 1851 | } | 1864 | } |
| 1865 | return sock; | ||
| 1866 | out_err: | ||
| 1867 | return ERR_PTR(-EIO); | ||
| 1868 | } | ||
| 1852 | 1869 | ||
| 1853 | dprintk("RPC: worker connecting xprt %p to address: %s\n", | 1870 | /** |
| 1854 | xprt, xprt->address_strings[RPC_DISPLAY_ALL]); | 1871 | * xs_tcp_connect_worker6 - connect a TCP socket to a remote endpoint |
| 1872 | * @work: RPC transport to connect | ||
| 1873 | * | ||
| 1874 | * Invoked by a work queue tasklet. | ||
| 1875 | */ | ||
| 1876 | static void xs_tcp_connect_worker6(struct work_struct *work) | ||
| 1877 | { | ||
| 1878 | struct sock_xprt *transport = | ||
| 1879 | container_of(work, struct sock_xprt, connect_worker.work); | ||
| 1880 | struct rpc_xprt *xprt = &transport->xprt; | ||
| 1855 | 1881 | ||
| 1856 | status = xs_tcp_finish_connecting(xprt, sock); | 1882 | xs_tcp_setup_socket(xprt, transport, xs_create_tcp_sock6); |
| 1857 | dprintk("RPC: %p connect status %d connected %d sock state %d\n", | ||
| 1858 | xprt, -status, xprt_connected(xprt), sock->sk->sk_state); | ||
| 1859 | switch (status) { | ||
| 1860 | case -ECONNREFUSED: | ||
| 1861 | case -ECONNRESET: | ||
| 1862 | case -ENETUNREACH: | ||
| 1863 | /* retry with existing socket, after a delay */ | ||
| 1864 | case 0: | ||
| 1865 | case -EINPROGRESS: | ||
| 1866 | case -EALREADY: | ||
| 1867 | xprt_clear_connecting(xprt); | ||
| 1868 | return; | ||
| 1869 | } | ||
| 1870 | /* get rid of existing socket, and retry */ | ||
| 1871 | xs_tcp_shutdown(xprt); | ||
| 1872 | printk("%s: connect returned unhandled error %d\n", | ||
| 1873 | __func__, status); | ||
| 1874 | out_eagain: | ||
| 1875 | status = -EAGAIN; | ||
| 1876 | out: | ||
| 1877 | xprt_clear_connecting(xprt); | ||
| 1878 | xprt_wake_pending_tasks(xprt, status); | ||
| 1879 | } | 1883 | } |
| 1880 | 1884 | ||
| 1881 | /** | 1885 | /** |
