diff options
author | Sage Weil <sage@newdream.net> | 2011-01-25 11:17:48 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2011-01-25 11:17:48 -0500 |
commit | 98bdb0aa007ff7e8e0061936d8d0e210faf2e655 (patch) | |
tree | 78c32ad3f4aee581e1f17bc477791fbc102b672c | |
parent | d66bbd441c08fe00ed2add1cf70cb243ebc2b27e (diff) |
libceph: fix socket read error handling
If we get EAGAIN when trying to read from the socket, it is not an error.
Return 0 from the helper in this case to simplify the error handling cases
in the caller (indirectly, try_read).
Fix try_read to pass any error to it's caller (con_work) instead of almost
always returning 0. This let's us respond to things like socket
disconnects.
Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r-- | net/ceph/messenger.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index dff633d62e5b..d95576d40c98 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -252,8 +252,12 @@ static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len) | |||
252 | { | 252 | { |
253 | struct kvec iov = {buf, len}; | 253 | struct kvec iov = {buf, len}; |
254 | struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL }; | 254 | struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL }; |
255 | int r; | ||
255 | 256 | ||
256 | return kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags); | 257 | r = kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags); |
258 | if (r == -EAGAIN) | ||
259 | r = 0; | ||
260 | return r; | ||
257 | } | 261 | } |
258 | 262 | ||
259 | /* | 263 | /* |
@@ -1821,19 +1825,17 @@ more: | |||
1821 | dout("try_read connecting\n"); | 1825 | dout("try_read connecting\n"); |
1822 | ret = read_partial_banner(con); | 1826 | ret = read_partial_banner(con); |
1823 | if (ret <= 0) | 1827 | if (ret <= 0) |
1824 | goto done; | ||
1825 | if (process_banner(con) < 0) { | ||
1826 | ret = -1; | ||
1827 | goto out; | 1828 | goto out; |
1828 | } | 1829 | ret = process_banner(con); |
1830 | if (ret < 0) | ||
1831 | goto out; | ||
1829 | } | 1832 | } |
1830 | ret = read_partial_connect(con); | 1833 | ret = read_partial_connect(con); |
1831 | if (ret <= 0) | 1834 | if (ret <= 0) |
1832 | goto done; | ||
1833 | if (process_connect(con) < 0) { | ||
1834 | ret = -1; | ||
1835 | goto out; | 1835 | goto out; |
1836 | } | 1836 | ret = process_connect(con); |
1837 | if (ret < 0) | ||
1838 | goto out; | ||
1837 | goto more; | 1839 | goto more; |
1838 | } | 1840 | } |
1839 | 1841 | ||
@@ -1848,7 +1850,7 @@ more: | |||
1848 | dout("skipping %d / %d bytes\n", skip, -con->in_base_pos); | 1850 | dout("skipping %d / %d bytes\n", skip, -con->in_base_pos); |
1849 | ret = ceph_tcp_recvmsg(con->sock, buf, skip); | 1851 | ret = ceph_tcp_recvmsg(con->sock, buf, skip); |
1850 | if (ret <= 0) | 1852 | if (ret <= 0) |
1851 | goto done; | 1853 | goto out; |
1852 | con->in_base_pos += ret; | 1854 | con->in_base_pos += ret; |
1853 | if (con->in_base_pos) | 1855 | if (con->in_base_pos) |
1854 | goto more; | 1856 | goto more; |
@@ -1859,7 +1861,7 @@ more: | |||
1859 | */ | 1861 | */ |
1860 | ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1); | 1862 | ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1); |
1861 | if (ret <= 0) | 1863 | if (ret <= 0) |
1862 | goto done; | 1864 | goto out; |
1863 | dout("try_read got tag %d\n", (int)con->in_tag); | 1865 | dout("try_read got tag %d\n", (int)con->in_tag); |
1864 | switch (con->in_tag) { | 1866 | switch (con->in_tag) { |
1865 | case CEPH_MSGR_TAG_MSG: | 1867 | case CEPH_MSGR_TAG_MSG: |
@@ -1870,7 +1872,7 @@ more: | |||
1870 | break; | 1872 | break; |
1871 | case CEPH_MSGR_TAG_CLOSE: | 1873 | case CEPH_MSGR_TAG_CLOSE: |
1872 | set_bit(CLOSED, &con->state); /* fixme */ | 1874 | set_bit(CLOSED, &con->state); /* fixme */ |
1873 | goto done; | 1875 | goto out; |
1874 | default: | 1876 | default: |
1875 | goto bad_tag; | 1877 | goto bad_tag; |
1876 | } | 1878 | } |
@@ -1882,13 +1884,12 @@ more: | |||
1882 | case -EBADMSG: | 1884 | case -EBADMSG: |
1883 | con->error_msg = "bad crc"; | 1885 | con->error_msg = "bad crc"; |
1884 | ret = -EIO; | 1886 | ret = -EIO; |
1885 | goto out; | 1887 | break; |
1886 | case -EIO: | 1888 | case -EIO: |
1887 | con->error_msg = "io error"; | 1889 | con->error_msg = "io error"; |
1888 | goto out; | 1890 | break; |
1889 | default: | ||
1890 | goto done; | ||
1891 | } | 1891 | } |
1892 | goto out; | ||
1892 | } | 1893 | } |
1893 | if (con->in_tag == CEPH_MSGR_TAG_READY) | 1894 | if (con->in_tag == CEPH_MSGR_TAG_READY) |
1894 | goto more; | 1895 | goto more; |
@@ -1898,15 +1899,13 @@ more: | |||
1898 | if (con->in_tag == CEPH_MSGR_TAG_ACK) { | 1899 | if (con->in_tag == CEPH_MSGR_TAG_ACK) { |
1899 | ret = read_partial_ack(con); | 1900 | ret = read_partial_ack(con); |
1900 | if (ret <= 0) | 1901 | if (ret <= 0) |
1901 | goto done; | 1902 | goto out; |
1902 | process_ack(con); | 1903 | process_ack(con); |
1903 | goto more; | 1904 | goto more; |
1904 | } | 1905 | } |
1905 | 1906 | ||
1906 | done: | ||
1907 | ret = 0; | ||
1908 | out: | 1907 | out: |
1909 | dout("try_read done on %p\n", con); | 1908 | dout("try_read done on %p ret %d\n", con, ret); |
1910 | return ret; | 1909 | return ret; |
1911 | 1910 | ||
1912 | bad_tag: | 1911 | bad_tag: |