Commit 98bdb0aa authored by Sage Weil's avatar Sage Weil

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: default avatarSage Weil <sage@newdream.net>
parent d66bbd44
...@@ -252,8 +252,12 @@ static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len) ...@@ -252,8 +252,12 @@ static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len)
{ {
struct kvec iov = {buf, len}; struct kvec iov = {buf, len};
struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL }; struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL };
int r;
return kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags); r = kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags);
if (r == -EAGAIN)
r = 0;
return r;
} }
/* /*
...@@ -1821,19 +1825,17 @@ static int try_read(struct ceph_connection *con) ...@@ -1821,19 +1825,17 @@ static int try_read(struct ceph_connection *con)
dout("try_read connecting\n"); dout("try_read connecting\n");
ret = read_partial_banner(con); ret = read_partial_banner(con);
if (ret <= 0) if (ret <= 0)
goto done;
if (process_banner(con) < 0) {
ret = -1;
goto out; goto out;
} ret = process_banner(con);
if (ret < 0)
goto out;
} }
ret = read_partial_connect(con); ret = read_partial_connect(con);
if (ret <= 0) if (ret <= 0)
goto done;
if (process_connect(con) < 0) {
ret = -1;
goto out; goto out;
} ret = process_connect(con);
if (ret < 0)
goto out;
goto more; goto more;
} }
...@@ -1848,7 +1850,7 @@ static int try_read(struct ceph_connection *con) ...@@ -1848,7 +1850,7 @@ static int try_read(struct ceph_connection *con)
dout("skipping %d / %d bytes\n", skip, -con->in_base_pos); dout("skipping %d / %d bytes\n", skip, -con->in_base_pos);
ret = ceph_tcp_recvmsg(con->sock, buf, skip); ret = ceph_tcp_recvmsg(con->sock, buf, skip);
if (ret <= 0) if (ret <= 0)
goto done; goto out;
con->in_base_pos += ret; con->in_base_pos += ret;
if (con->in_base_pos) if (con->in_base_pos)
goto more; goto more;
...@@ -1859,7 +1861,7 @@ static int try_read(struct ceph_connection *con) ...@@ -1859,7 +1861,7 @@ static int try_read(struct ceph_connection *con)
*/ */
ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1); ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1);
if (ret <= 0) if (ret <= 0)
goto done; goto out;
dout("try_read got tag %d\n", (int)con->in_tag); dout("try_read got tag %d\n", (int)con->in_tag);
switch (con->in_tag) { switch (con->in_tag) {
case CEPH_MSGR_TAG_MSG: case CEPH_MSGR_TAG_MSG:
...@@ -1870,7 +1872,7 @@ static int try_read(struct ceph_connection *con) ...@@ -1870,7 +1872,7 @@ static int try_read(struct ceph_connection *con)
break; break;
case CEPH_MSGR_TAG_CLOSE: case CEPH_MSGR_TAG_CLOSE:
set_bit(CLOSED, &con->state); /* fixme */ set_bit(CLOSED, &con->state); /* fixme */
goto done; goto out;
default: default:
goto bad_tag; goto bad_tag;
} }
...@@ -1882,13 +1884,12 @@ static int try_read(struct ceph_connection *con) ...@@ -1882,13 +1884,12 @@ static int try_read(struct ceph_connection *con)
case -EBADMSG: case -EBADMSG:
con->error_msg = "bad crc"; con->error_msg = "bad crc";
ret = -EIO; ret = -EIO;
goto out; break;
case -EIO: case -EIO:
con->error_msg = "io error"; con->error_msg = "io error";
goto out; break;
default:
goto done;
} }
goto out;
} }
if (con->in_tag == CEPH_MSGR_TAG_READY) if (con->in_tag == CEPH_MSGR_TAG_READY)
goto more; goto more;
...@@ -1898,15 +1899,13 @@ static int try_read(struct ceph_connection *con) ...@@ -1898,15 +1899,13 @@ static int try_read(struct ceph_connection *con)
if (con->in_tag == CEPH_MSGR_TAG_ACK) { if (con->in_tag == CEPH_MSGR_TAG_ACK) {
ret = read_partial_ack(con); ret = read_partial_ack(con);
if (ret <= 0) if (ret <= 0)
goto done; goto out;
process_ack(con); process_ack(con);
goto more; goto more;
} }
done:
ret = 0;
out: out:
dout("try_read done on %p\n", con); dout("try_read done on %p ret %d\n", con, ret);
return ret; return ret;
bad_tag: bad_tag:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment