aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-06-20 22:53:53 -0400
committerSage Weil <sage@inktank.com>2012-07-06 00:14:23 -0400
commit456ea46865787283088b23a8a7f69244513b95f0 (patch)
tree39bac208be184e2cc5f2e6921fc8c3d983fd6d05 /net
parentd65c9e0b9eb43d14ece9dd843506ccba06162ee7 (diff)
libceph: don't touch con state in con_close_socket()
In con_close_socket(), a connection's SOCK_CLOSED flag gets set and then cleared while its shutdown method is called and its reference gets dropped. Previously, that flag got set only if it had not already been set, so setting it in con_close_socket() might have prevented additional processing being done on a socket being shut down. We no longer set SOCK_CLOSED in the socket event routine conditionally, so setting that bit here no longer provides whatever benefit it might have provided before. A race condition could still leave the SOCK_CLOSED bit set even after we've issued the call to con_close_socket(), so we still clear that bit after shutting the socket down. Add a comment explaining the reason for this. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'net')
-rw-r--r--net/ceph/messenger.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index cebef8560586..cfcca1f5be67 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -392,10 +392,16 @@ static int con_close_socket(struct ceph_connection *con)
392 dout("con_close_socket on %p sock %p\n", con, con->sock); 392 dout("con_close_socket on %p sock %p\n", con, con->sock);
393 if (!con->sock) 393 if (!con->sock)
394 return 0; 394 return 0;
395 set_bit(SOCK_CLOSED, &con->flags);
396 rc = con->sock->ops->shutdown(con->sock, SHUT_RDWR); 395 rc = con->sock->ops->shutdown(con->sock, SHUT_RDWR);
397 sock_release(con->sock); 396 sock_release(con->sock);
398 con->sock = NULL; 397 con->sock = NULL;
398
399 /*
400 * Forcibly clear the SOCK_CLOSE flag. It gets set
401 * independent of the connection mutex, and we could have
402 * received a socket close event before we had the chance to
403 * shut the socket down.
404 */
399 clear_bit(SOCK_CLOSED, &con->flags); 405 clear_bit(SOCK_CLOSED, &con->flags);
400 con_sock_state_closed(con); 406 con_sock_state_closed(con);
401 return rc; 407 return rc;