libceph: fix handling of immediate socket connect failure
If the connect() call immediately fails such that sock == NULL, we still need con_close_socket() to reset our socket state to CLOSED. Signed-off-by: Sage Weil <sage@inktank.com> Reviewed-by: Alex Elder <elder@inktank.com>
This commit is contained in:
@@ -224,6 +224,8 @@ static void con_sock_state_init(struct ceph_connection *con)
|
|||||||
old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSED);
|
old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSED);
|
||||||
if (WARN_ON(old_state != CON_SOCK_STATE_NEW))
|
if (WARN_ON(old_state != CON_SOCK_STATE_NEW))
|
||||||
printk("%s: unexpected old state %d\n", __func__, old_state);
|
printk("%s: unexpected old state %d\n", __func__, old_state);
|
||||||
|
dout("%s con %p sock %d -> %d\n", __func__, con, old_state,
|
||||||
|
CON_SOCK_STATE_CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void con_sock_state_connecting(struct ceph_connection *con)
|
static void con_sock_state_connecting(struct ceph_connection *con)
|
||||||
@@ -233,6 +235,8 @@ static void con_sock_state_connecting(struct ceph_connection *con)
|
|||||||
old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CONNECTING);
|
old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CONNECTING);
|
||||||
if (WARN_ON(old_state != CON_SOCK_STATE_CLOSED))
|
if (WARN_ON(old_state != CON_SOCK_STATE_CLOSED))
|
||||||
printk("%s: unexpected old state %d\n", __func__, old_state);
|
printk("%s: unexpected old state %d\n", __func__, old_state);
|
||||||
|
dout("%s con %p sock %d -> %d\n", __func__, con, old_state,
|
||||||
|
CON_SOCK_STATE_CONNECTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void con_sock_state_connected(struct ceph_connection *con)
|
static void con_sock_state_connected(struct ceph_connection *con)
|
||||||
@@ -242,6 +246,8 @@ static void con_sock_state_connected(struct ceph_connection *con)
|
|||||||
old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CONNECTED);
|
old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CONNECTED);
|
||||||
if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTING))
|
if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTING))
|
||||||
printk("%s: unexpected old state %d\n", __func__, old_state);
|
printk("%s: unexpected old state %d\n", __func__, old_state);
|
||||||
|
dout("%s con %p sock %d -> %d\n", __func__, con, old_state,
|
||||||
|
CON_SOCK_STATE_CONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void con_sock_state_closing(struct ceph_connection *con)
|
static void con_sock_state_closing(struct ceph_connection *con)
|
||||||
@@ -253,6 +259,8 @@ static void con_sock_state_closing(struct ceph_connection *con)
|
|||||||
old_state != CON_SOCK_STATE_CONNECTED &&
|
old_state != CON_SOCK_STATE_CONNECTED &&
|
||||||
old_state != CON_SOCK_STATE_CLOSING))
|
old_state != CON_SOCK_STATE_CLOSING))
|
||||||
printk("%s: unexpected old state %d\n", __func__, old_state);
|
printk("%s: unexpected old state %d\n", __func__, old_state);
|
||||||
|
dout("%s con %p sock %d -> %d\n", __func__, con, old_state,
|
||||||
|
CON_SOCK_STATE_CLOSING);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void con_sock_state_closed(struct ceph_connection *con)
|
static void con_sock_state_closed(struct ceph_connection *con)
|
||||||
@@ -262,8 +270,11 @@ static void con_sock_state_closed(struct ceph_connection *con)
|
|||||||
old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSED);
|
old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSED);
|
||||||
if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTED &&
|
if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTED &&
|
||||||
old_state != CON_SOCK_STATE_CLOSING &&
|
old_state != CON_SOCK_STATE_CLOSING &&
|
||||||
old_state != CON_SOCK_STATE_CONNECTING))
|
old_state != CON_SOCK_STATE_CONNECTING &&
|
||||||
|
old_state != CON_SOCK_STATE_CLOSED))
|
||||||
printk("%s: unexpected old state %d\n", __func__, old_state);
|
printk("%s: unexpected old state %d\n", __func__, old_state);
|
||||||
|
dout("%s con %p sock %d -> %d\n", __func__, con, old_state,
|
||||||
|
CON_SOCK_STATE_CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -448,14 +459,14 @@ static int ceph_tcp_sendpage(struct socket *sock, struct page *page,
|
|||||||
*/
|
*/
|
||||||
static int con_close_socket(struct ceph_connection *con)
|
static int con_close_socket(struct ceph_connection *con)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc = 0;
|
||||||
|
|
||||||
dout("con_close_socket on %p sock %p\n", con, con->sock);
|
dout("con_close_socket on %p sock %p\n", con, con->sock);
|
||||||
if (!con->sock)
|
if (con->sock) {
|
||||||
return 0;
|
rc = con->sock->ops->shutdown(con->sock, SHUT_RDWR);
|
||||||
rc = con->sock->ops->shutdown(con->sock, SHUT_RDWR);
|
sock_release(con->sock);
|
||||||
sock_release(con->sock);
|
con->sock = NULL;
|
||||||
con->sock = NULL;
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Forcibly clear the SOCK_CLOSED flag. It gets set
|
* Forcibly clear the SOCK_CLOSED flag. It gets set
|
||||||
@@ -464,6 +475,7 @@ static int con_close_socket(struct ceph_connection *con)
|
|||||||
* shut the socket down.
|
* shut the socket down.
|
||||||
*/
|
*/
|
||||||
clear_bit(CON_FLAG_SOCK_CLOSED, &con->flags);
|
clear_bit(CON_FLAG_SOCK_CLOSED, &con->flags);
|
||||||
|
|
||||||
con_sock_state_closed(con);
|
con_sock_state_closed(con);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user