aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/messenger.c
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-05-22 23:15:49 -0400
committerAlex Elder <elder@dreamhost.com>2012-06-01 09:37:56 -0400
commitce2c8903e76e690846a00a0284e4bd9ee954d680 (patch)
tree883ce31b9da920f7e4d68302569fd0143d14b264 /net/ceph/messenger.c
parent928443cd9644e7cfd46f687dbeffda2d1a357ff9 (diff)
libceph: start tracking connection socket state
Start explicitly keeping track of the state of a ceph connection's socket, separate from the state of the connection itself. Create placeholder functions to encapsulate the state transitions. -------- | NEW* | transient initial state -------- | con_sock_state_init() v ---------- | CLOSED | initialized, but no socket (and no ---------- TCP connection) ^ \ | \ con_sock_state_connecting() | ---------------------- | \ + con_sock_state_closed() \ |\ \ | \ \ | ----------- \ | | CLOSING | socket event; \ | ----------- await close \ | ^ | | | | | + con_sock_state_closing() | | / \ | | / --------------- | | / \ v | / -------------- | / -----------------| CONNECTING | socket created, TCP | | / -------------- connect initiated | | | con_sock_state_connected() | | v ------------- | CONNECTED | TCP connection established ------------- Make the socket state an atomic variable, reinforcing that it's a distinct transtion with no possible "intermediate/both" states. This is almost certainly overkill at this point, though the transitions into CONNECTED and CLOSING state do get called via socket callback (the rest of the transitions occur with the connection mutex held). We can back out the atomicity later. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Sage Weil<sage@inktank.com>
Diffstat (limited to 'net/ceph/messenger.c')
-rw-r--r--net/ceph/messenger.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index e84e4fd86bb7..a4ac3deec161 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -29,6 +29,14 @@
29 * the sender. 29 * the sender.
30 */ 30 */
31 31
32/* State values for ceph_connection->sock_state; NEW is assumed to be 0 */
33
34#define CON_SOCK_STATE_NEW 0 /* -> CLOSED */
35#define CON_SOCK_STATE_CLOSED 1 /* -> CONNECTING */
36#define CON_SOCK_STATE_CONNECTING 2 /* -> CONNECTED or -> CLOSING */
37#define CON_SOCK_STATE_CONNECTED 3 /* -> CLOSING or -> CLOSED */
38#define CON_SOCK_STATE_CLOSING 4 /* -> CLOSED */
39
32/* static tag bytes (protocol control messages) */ 40/* static tag bytes (protocol control messages) */
33static char tag_msg = CEPH_MSGR_TAG_MSG; 41static char tag_msg = CEPH_MSGR_TAG_MSG;
34static char tag_ack = CEPH_MSGR_TAG_ACK; 42static char tag_ack = CEPH_MSGR_TAG_ACK;
@@ -147,6 +155,55 @@ void ceph_msgr_flush(void)
147} 155}
148EXPORT_SYMBOL(ceph_msgr_flush); 156EXPORT_SYMBOL(ceph_msgr_flush);
149 157
158/* Connection socket state transition functions */
159
160static void con_sock_state_init(struct ceph_connection *con)
161{
162 int old_state;
163
164 old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSED);
165 if (WARN_ON(old_state != CON_SOCK_STATE_NEW))
166 printk("%s: unexpected old state %d\n", __func__, old_state);
167}
168
169static void con_sock_state_connecting(struct ceph_connection *con)
170{
171 int old_state;
172
173 old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CONNECTING);
174 if (WARN_ON(old_state != CON_SOCK_STATE_CLOSED))
175 printk("%s: unexpected old state %d\n", __func__, old_state);
176}
177
178static void con_sock_state_connected(struct ceph_connection *con)
179{
180 int old_state;
181
182 old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CONNECTED);
183 if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTING))
184 printk("%s: unexpected old state %d\n", __func__, old_state);
185}
186
187static void con_sock_state_closing(struct ceph_connection *con)
188{
189 int old_state;
190
191 old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSING);
192 if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTING &&
193 old_state != CON_SOCK_STATE_CONNECTED &&
194 old_state != CON_SOCK_STATE_CLOSING))
195 printk("%s: unexpected old state %d\n", __func__, old_state);
196}
197
198static void con_sock_state_closed(struct ceph_connection *con)
199{
200 int old_state;
201
202 old_state = atomic_xchg(&con->sock_state, CON_SOCK_STATE_CLOSED);
203 if (WARN_ON(old_state != CON_SOCK_STATE_CONNECTED &&
204 old_state != CON_SOCK_STATE_CLOSING))
205 printk("%s: unexpected old state %d\n", __func__, old_state);
206}
150 207
151/* 208/*
152 * socket callback functions 209 * socket callback functions
@@ -203,6 +260,7 @@ static void ceph_sock_state_change(struct sock *sk)
203 dout("%s TCP_CLOSE\n", __func__); 260 dout("%s TCP_CLOSE\n", __func__);
204 case TCP_CLOSE_WAIT: 261 case TCP_CLOSE_WAIT:
205 dout("%s TCP_CLOSE_WAIT\n", __func__); 262 dout("%s TCP_CLOSE_WAIT\n", __func__);
263 con_sock_state_closing(con);
206 if (test_and_set_bit(SOCK_CLOSED, &con->flags) == 0) { 264 if (test_and_set_bit(SOCK_CLOSED, &con->flags) == 0) {
207 if (test_bit(CONNECTING, &con->state)) 265 if (test_bit(CONNECTING, &con->state))
208 con->error_msg = "connection failed"; 266 con->error_msg = "connection failed";
@@ -213,6 +271,7 @@ static void ceph_sock_state_change(struct sock *sk)
213 break; 271 break;
214 case TCP_ESTABLISHED: 272 case TCP_ESTABLISHED:
215 dout("%s TCP_ESTABLISHED\n", __func__); 273 dout("%s TCP_ESTABLISHED\n", __func__);
274 con_sock_state_connected(con);
216 queue_con(con); 275 queue_con(con);
217 break; 276 break;
218 default: /* Everything else is uninteresting */ 277 default: /* Everything else is uninteresting */
@@ -277,6 +336,7 @@ static int ceph_tcp_connect(struct ceph_connection *con)
277 return ret; 336 return ret;
278 } 337 }
279 con->sock = sock; 338 con->sock = sock;
339 con_sock_state_connecting(con);
280 340
281 return 0; 341 return 0;
282} 342}
@@ -343,6 +403,7 @@ static int con_close_socket(struct ceph_connection *con)
343 sock_release(con->sock); 403 sock_release(con->sock);
344 con->sock = NULL; 404 con->sock = NULL;
345 clear_bit(SOCK_CLOSED, &con->state); 405 clear_bit(SOCK_CLOSED, &con->state);
406 con_sock_state_closed(con);
346 return rc; 407 return rc;
347} 408}
348 409
@@ -462,6 +523,9 @@ void ceph_con_init(struct ceph_messenger *msgr, struct ceph_connection *con)
462 memset(con, 0, sizeof(*con)); 523 memset(con, 0, sizeof(*con));
463 atomic_set(&con->nref, 1); 524 atomic_set(&con->nref, 1);
464 con->msgr = msgr; 525 con->msgr = msgr;
526
527 con_sock_state_init(con);
528
465 mutex_init(&con->mutex); 529 mutex_init(&con->mutex);
466 INIT_LIST_HEAD(&con->out_queue); 530 INIT_LIST_HEAD(&con->out_queue);
467 INIT_LIST_HEAD(&con->out_sent); 531 INIT_LIST_HEAD(&con->out_sent);