aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2011-01-25 11:17:48 -0500
committerSage Weil <sage@newdream.net>2011-01-25 11:17:48 -0500
commit98bdb0aa007ff7e8e0061936d8d0e210faf2e655 (patch)
tree78c32ad3f4aee581e1f17bc477791fbc102b672c
parentd66bbd441c08fe00ed2add1cf70cb243ebc2b27e (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.c39
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
1906done:
1907 ret = 0;
1908out: 1907out:
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
1912bad_tag: 1911bad_tag: