diff options
Diffstat (limited to 'net/ceph/messenger.c')
-rw-r--r-- | net/ceph/messenger.c | 64 |
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) */ |
33 | static char tag_msg = CEPH_MSGR_TAG_MSG; | 41 | static char tag_msg = CEPH_MSGR_TAG_MSG; |
34 | static char tag_ack = CEPH_MSGR_TAG_ACK; | 42 | static char tag_ack = CEPH_MSGR_TAG_ACK; |
@@ -147,6 +155,55 @@ void ceph_msgr_flush(void) | |||
147 | } | 155 | } |
148 | EXPORT_SYMBOL(ceph_msgr_flush); | 156 | EXPORT_SYMBOL(ceph_msgr_flush); |
149 | 157 | ||
158 | /* Connection socket state transition functions */ | ||
159 | |||
160 | static 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 | |||
169 | static 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 | |||
178 | static 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 | |||
187 | static 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 | |||
198 | static 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); |