diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ceph/messenger.c | 107 |
1 files changed, 78 insertions, 29 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 8a62a559a2aa..771d4c904469 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -98,6 +98,57 @@ | |||
98 | #define CON_FLAG_SOCK_CLOSED 3 /* socket state changed to closed */ | 98 | #define CON_FLAG_SOCK_CLOSED 3 /* socket state changed to closed */ |
99 | #define CON_FLAG_BACKOFF 4 /* need to retry queuing delayed work */ | 99 | #define CON_FLAG_BACKOFF 4 /* need to retry queuing delayed work */ |
100 | 100 | ||
101 | static bool con_flag_valid(unsigned long con_flag) | ||
102 | { | ||
103 | switch (con_flag) { | ||
104 | case CON_FLAG_LOSSYTX: | ||
105 | case CON_FLAG_KEEPALIVE_PENDING: | ||
106 | case CON_FLAG_WRITE_PENDING: | ||
107 | case CON_FLAG_SOCK_CLOSED: | ||
108 | case CON_FLAG_BACKOFF: | ||
109 | return true; | ||
110 | default: | ||
111 | return false; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | static void con_flag_clear(struct ceph_connection *con, unsigned long con_flag) | ||
116 | { | ||
117 | BUG_ON(!con_flag_valid(con_flag)); | ||
118 | |||
119 | clear_bit(con_flag, &con->flags); | ||
120 | } | ||
121 | |||
122 | static void con_flag_set(struct ceph_connection *con, unsigned long con_flag) | ||
123 | { | ||
124 | BUG_ON(!con_flag_valid(con_flag)); | ||
125 | |||
126 | set_bit(con_flag, &con->flags); | ||
127 | } | ||
128 | |||
129 | static bool con_flag_test(struct ceph_connection *con, unsigned long con_flag) | ||
130 | { | ||
131 | BUG_ON(!con_flag_valid(con_flag)); | ||
132 | |||
133 | return test_bit(con_flag, &con->flags); | ||
134 | } | ||
135 | |||
136 | static bool con_flag_test_and_clear(struct ceph_connection *con, | ||
137 | unsigned long con_flag) | ||
138 | { | ||
139 | BUG_ON(!con_flag_valid(con_flag)); | ||
140 | |||
141 | return test_and_clear_bit(con_flag, &con->flags); | ||
142 | } | ||
143 | |||
144 | static bool con_flag_test_and_set(struct ceph_connection *con, | ||
145 | unsigned long con_flag) | ||
146 | { | ||
147 | BUG_ON(!con_flag_valid(con_flag)); | ||
148 | |||
149 | return test_and_set_bit(con_flag, &con->flags); | ||
150 | } | ||
151 | |||
101 | /* static tag bytes (protocol control messages) */ | 152 | /* static tag bytes (protocol control messages) */ |
102 | static char tag_msg = CEPH_MSGR_TAG_MSG; | 153 | static char tag_msg = CEPH_MSGR_TAG_MSG; |
103 | static char tag_ack = CEPH_MSGR_TAG_ACK; | 154 | static char tag_ack = CEPH_MSGR_TAG_ACK; |
@@ -309,7 +360,7 @@ static void ceph_sock_write_space(struct sock *sk) | |||
309 | * buffer. See net/ipv4/tcp_input.c:tcp_check_space() | 360 | * buffer. See net/ipv4/tcp_input.c:tcp_check_space() |
310 | * and net/core/stream.c:sk_stream_write_space(). | 361 | * and net/core/stream.c:sk_stream_write_space(). |
311 | */ | 362 | */ |
312 | if (test_bit(CON_FLAG_WRITE_PENDING, &con->flags)) { | 363 | if (con_flag_test(con, CON_FLAG_WRITE_PENDING)) { |
313 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) { | 364 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) { |
314 | dout("%s %p queueing write work\n", __func__, con); | 365 | dout("%s %p queueing write work\n", __func__, con); |
315 | clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags); | 366 | clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags); |
@@ -334,7 +385,7 @@ static void ceph_sock_state_change(struct sock *sk) | |||
334 | case TCP_CLOSE_WAIT: | 385 | case TCP_CLOSE_WAIT: |
335 | dout("%s TCP_CLOSE_WAIT\n", __func__); | 386 | dout("%s TCP_CLOSE_WAIT\n", __func__); |
336 | con_sock_state_closing(con); | 387 | con_sock_state_closing(con); |
337 | set_bit(CON_FLAG_SOCK_CLOSED, &con->flags); | 388 | con_flag_set(con, CON_FLAG_SOCK_CLOSED); |
338 | queue_con(con); | 389 | queue_con(con); |
339 | break; | 390 | break; |
340 | case TCP_ESTABLISHED: | 391 | case TCP_ESTABLISHED: |
@@ -475,7 +526,7 @@ static int con_close_socket(struct ceph_connection *con) | |||
475 | * received a socket close event before we had the chance to | 526 | * received a socket close event before we had the chance to |
476 | * shut the socket down. | 527 | * shut the socket down. |
477 | */ | 528 | */ |
478 | clear_bit(CON_FLAG_SOCK_CLOSED, &con->flags); | 529 | con_flag_clear(con, CON_FLAG_SOCK_CLOSED); |
479 | 530 | ||
480 | con_sock_state_closed(con); | 531 | con_sock_state_closed(con); |
481 | return rc; | 532 | return rc; |
@@ -539,11 +590,10 @@ void ceph_con_close(struct ceph_connection *con) | |||
539 | ceph_pr_addr(&con->peer_addr.in_addr)); | 590 | ceph_pr_addr(&con->peer_addr.in_addr)); |
540 | con->state = CON_STATE_CLOSED; | 591 | con->state = CON_STATE_CLOSED; |
541 | 592 | ||
542 | clear_bit(CON_FLAG_LOSSYTX, &con->flags); /* so we retry next connect */ | 593 | con_flag_clear(con, CON_FLAG_LOSSYTX); /* so we retry next connect */ |
543 | clear_bit(CON_FLAG_KEEPALIVE_PENDING, &con->flags); | 594 | con_flag_clear(con, CON_FLAG_KEEPALIVE_PENDING); |
544 | clear_bit(CON_FLAG_WRITE_PENDING, &con->flags); | 595 | con_flag_clear(con, CON_FLAG_WRITE_PENDING); |
545 | clear_bit(CON_FLAG_KEEPALIVE_PENDING, &con->flags); | 596 | con_flag_clear(con, CON_FLAG_BACKOFF); |
546 | clear_bit(CON_FLAG_BACKOFF, &con->flags); | ||
547 | 597 | ||
548 | reset_connection(con); | 598 | reset_connection(con); |
549 | con->peer_global_seq = 0; | 599 | con->peer_global_seq = 0; |
@@ -799,7 +849,7 @@ static void prepare_write_message(struct ceph_connection *con) | |||
799 | /* no, queue up footer too and be done */ | 849 | /* no, queue up footer too and be done */ |
800 | prepare_write_message_footer(con); | 850 | prepare_write_message_footer(con); |
801 | 851 | ||
802 | set_bit(CON_FLAG_WRITE_PENDING, &con->flags); | 852 | con_flag_set(con, CON_FLAG_WRITE_PENDING); |
803 | } | 853 | } |
804 | 854 | ||
805 | /* | 855 | /* |
@@ -820,7 +870,7 @@ static void prepare_write_ack(struct ceph_connection *con) | |||
820 | &con->out_temp_ack); | 870 | &con->out_temp_ack); |
821 | 871 | ||
822 | con->out_more = 1; /* more will follow.. eventually.. */ | 872 | con->out_more = 1; /* more will follow.. eventually.. */ |
823 | set_bit(CON_FLAG_WRITE_PENDING, &con->flags); | 873 | con_flag_set(con, CON_FLAG_WRITE_PENDING); |
824 | } | 874 | } |
825 | 875 | ||
826 | /* | 876 | /* |
@@ -831,7 +881,7 @@ static void prepare_write_keepalive(struct ceph_connection *con) | |||
831 | dout("prepare_write_keepalive %p\n", con); | 881 | dout("prepare_write_keepalive %p\n", con); |
832 | con_out_kvec_reset(con); | 882 | con_out_kvec_reset(con); |
833 | con_out_kvec_add(con, sizeof (tag_keepalive), &tag_keepalive); | 883 | con_out_kvec_add(con, sizeof (tag_keepalive), &tag_keepalive); |
834 | set_bit(CON_FLAG_WRITE_PENDING, &con->flags); | 884 | con_flag_set(con, CON_FLAG_WRITE_PENDING); |
835 | } | 885 | } |
836 | 886 | ||
837 | /* | 887 | /* |
@@ -874,7 +924,7 @@ static void prepare_write_banner(struct ceph_connection *con) | |||
874 | &con->msgr->my_enc_addr); | 924 | &con->msgr->my_enc_addr); |
875 | 925 | ||
876 | con->out_more = 0; | 926 | con->out_more = 0; |
877 | set_bit(CON_FLAG_WRITE_PENDING, &con->flags); | 927 | con_flag_set(con, CON_FLAG_WRITE_PENDING); |
878 | } | 928 | } |
879 | 929 | ||
880 | static int prepare_write_connect(struct ceph_connection *con) | 930 | static int prepare_write_connect(struct ceph_connection *con) |
@@ -924,7 +974,7 @@ static int prepare_write_connect(struct ceph_connection *con) | |||
924 | auth->authorizer_buf); | 974 | auth->authorizer_buf); |
925 | 975 | ||
926 | con->out_more = 0; | 976 | con->out_more = 0; |
927 | set_bit(CON_FLAG_WRITE_PENDING, &con->flags); | 977 | con_flag_set(con, CON_FLAG_WRITE_PENDING); |
928 | 978 | ||
929 | return 0; | 979 | return 0; |
930 | } | 980 | } |
@@ -1644,7 +1694,7 @@ static int process_connect(struct ceph_connection *con) | |||
1644 | le32_to_cpu(con->in_reply.connect_seq)); | 1694 | le32_to_cpu(con->in_reply.connect_seq)); |
1645 | 1695 | ||
1646 | if (con->in_reply.flags & CEPH_MSG_CONNECT_LOSSY) | 1696 | if (con->in_reply.flags & CEPH_MSG_CONNECT_LOSSY) |
1647 | set_bit(CON_FLAG_LOSSYTX, &con->flags); | 1697 | con_flag_set(con, CON_FLAG_LOSSYTX); |
1648 | 1698 | ||
1649 | con->delay = 0; /* reset backoff memory */ | 1699 | con->delay = 0; /* reset backoff memory */ |
1650 | 1700 | ||
@@ -2081,15 +2131,14 @@ do_next: | |||
2081 | prepare_write_ack(con); | 2131 | prepare_write_ack(con); |
2082 | goto more; | 2132 | goto more; |
2083 | } | 2133 | } |
2084 | if (test_and_clear_bit(CON_FLAG_KEEPALIVE_PENDING, | 2134 | if (con_flag_test_and_clear(con, CON_FLAG_KEEPALIVE_PENDING)) { |
2085 | &con->flags)) { | ||
2086 | prepare_write_keepalive(con); | 2135 | prepare_write_keepalive(con); |
2087 | goto more; | 2136 | goto more; |
2088 | } | 2137 | } |
2089 | } | 2138 | } |
2090 | 2139 | ||
2091 | /* Nothing to do! */ | 2140 | /* Nothing to do! */ |
2092 | clear_bit(CON_FLAG_WRITE_PENDING, &con->flags); | 2141 | con_flag_clear(con, CON_FLAG_WRITE_PENDING); |
2093 | dout("try_write nothing else to write.\n"); | 2142 | dout("try_write nothing else to write.\n"); |
2094 | ret = 0; | 2143 | ret = 0; |
2095 | out: | 2144 | out: |
@@ -2269,7 +2318,7 @@ static void queue_con(struct ceph_connection *con) | |||
2269 | 2318 | ||
2270 | static bool con_sock_closed(struct ceph_connection *con) | 2319 | static bool con_sock_closed(struct ceph_connection *con) |
2271 | { | 2320 | { |
2272 | if (!test_and_clear_bit(CON_FLAG_SOCK_CLOSED, &con->flags)) | 2321 | if (!con_flag_test_and_clear(con, CON_FLAG_SOCK_CLOSED)) |
2273 | return false; | 2322 | return false; |
2274 | 2323 | ||
2275 | #define CASE(x) \ | 2324 | #define CASE(x) \ |
@@ -2310,14 +2359,14 @@ restart: | |||
2310 | if (con_sock_closed(con)) | 2359 | if (con_sock_closed(con)) |
2311 | goto fault; | 2360 | goto fault; |
2312 | 2361 | ||
2313 | if (test_and_clear_bit(CON_FLAG_BACKOFF, &con->flags)) { | 2362 | if (con_flag_test_and_clear(con, CON_FLAG_BACKOFF)) { |
2314 | dout("con_work %p backing off\n", con); | 2363 | dout("con_work %p backing off\n", con); |
2315 | ret = queue_con_delay(con, round_jiffies_relative(con->delay)); | 2364 | ret = queue_con_delay(con, round_jiffies_relative(con->delay)); |
2316 | if (ret) { | 2365 | if (ret) { |
2317 | dout("con_work %p FAILED to back off %lu\n", con, | 2366 | dout("con_work %p FAILED to back off %lu\n", con, |
2318 | con->delay); | 2367 | con->delay); |
2319 | BUG_ON(ret == -ENOENT); | 2368 | BUG_ON(ret == -ENOENT); |
2320 | set_bit(CON_FLAG_BACKOFF, &con->flags); | 2369 | con_flag_set(con, CON_FLAG_BACKOFF); |
2321 | } | 2370 | } |
2322 | goto done; | 2371 | goto done; |
2323 | } | 2372 | } |
@@ -2382,7 +2431,7 @@ static void ceph_fault(struct ceph_connection *con) | |||
2382 | 2431 | ||
2383 | con_close_socket(con); | 2432 | con_close_socket(con); |
2384 | 2433 | ||
2385 | if (test_bit(CON_FLAG_LOSSYTX, &con->flags)) { | 2434 | if (con_flag_test(con, CON_FLAG_LOSSYTX)) { |
2386 | dout("fault on LOSSYTX channel, marking CLOSED\n"); | 2435 | dout("fault on LOSSYTX channel, marking CLOSED\n"); |
2387 | con->state = CON_STATE_CLOSED; | 2436 | con->state = CON_STATE_CLOSED; |
2388 | goto out_unlock; | 2437 | goto out_unlock; |
@@ -2402,9 +2451,9 @@ static void ceph_fault(struct ceph_connection *con) | |||
2402 | /* If there are no messages queued or keepalive pending, place | 2451 | /* If there are no messages queued or keepalive pending, place |
2403 | * the connection in a STANDBY state */ | 2452 | * the connection in a STANDBY state */ |
2404 | if (list_empty(&con->out_queue) && | 2453 | if (list_empty(&con->out_queue) && |
2405 | !test_bit(CON_FLAG_KEEPALIVE_PENDING, &con->flags)) { | 2454 | !con_flag_test(con, CON_FLAG_KEEPALIVE_PENDING)) { |
2406 | dout("fault %p setting STANDBY clearing WRITE_PENDING\n", con); | 2455 | dout("fault %p setting STANDBY clearing WRITE_PENDING\n", con); |
2407 | clear_bit(CON_FLAG_WRITE_PENDING, &con->flags); | 2456 | con_flag_clear(con, CON_FLAG_WRITE_PENDING); |
2408 | con->state = CON_STATE_STANDBY; | 2457 | con->state = CON_STATE_STANDBY; |
2409 | } else { | 2458 | } else { |
2410 | /* retry after a delay. */ | 2459 | /* retry after a delay. */ |
@@ -2413,7 +2462,7 @@ static void ceph_fault(struct ceph_connection *con) | |||
2413 | con->delay = BASE_DELAY_INTERVAL; | 2462 | con->delay = BASE_DELAY_INTERVAL; |
2414 | else if (con->delay < MAX_DELAY_INTERVAL) | 2463 | else if (con->delay < MAX_DELAY_INTERVAL) |
2415 | con->delay *= 2; | 2464 | con->delay *= 2; |
2416 | set_bit(CON_FLAG_BACKOFF, &con->flags); | 2465 | con_flag_set(con, CON_FLAG_BACKOFF); |
2417 | queue_con(con); | 2466 | queue_con(con); |
2418 | } | 2467 | } |
2419 | 2468 | ||
@@ -2470,8 +2519,8 @@ static void clear_standby(struct ceph_connection *con) | |||
2470 | dout("clear_standby %p and ++connect_seq\n", con); | 2519 | dout("clear_standby %p and ++connect_seq\n", con); |
2471 | con->state = CON_STATE_PREOPEN; | 2520 | con->state = CON_STATE_PREOPEN; |
2472 | con->connect_seq++; | 2521 | con->connect_seq++; |
2473 | WARN_ON(test_bit(CON_FLAG_WRITE_PENDING, &con->flags)); | 2522 | WARN_ON(con_flag_test(con, CON_FLAG_WRITE_PENDING)); |
2474 | WARN_ON(test_bit(CON_FLAG_KEEPALIVE_PENDING, &con->flags)); | 2523 | WARN_ON(con_flag_test(con, CON_FLAG_KEEPALIVE_PENDING)); |
2475 | } | 2524 | } |
2476 | } | 2525 | } |
2477 | 2526 | ||
@@ -2512,7 +2561,7 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) | |||
2512 | 2561 | ||
2513 | /* if there wasn't anything waiting to send before, queue | 2562 | /* if there wasn't anything waiting to send before, queue |
2514 | * new work */ | 2563 | * new work */ |
2515 | if (test_and_set_bit(CON_FLAG_WRITE_PENDING, &con->flags) == 0) | 2564 | if (con_flag_test_and_set(con, CON_FLAG_WRITE_PENDING) == 0) |
2516 | queue_con(con); | 2565 | queue_con(con); |
2517 | } | 2566 | } |
2518 | EXPORT_SYMBOL(ceph_con_send); | 2567 | EXPORT_SYMBOL(ceph_con_send); |
@@ -2601,8 +2650,8 @@ void ceph_con_keepalive(struct ceph_connection *con) | |||
2601 | mutex_lock(&con->mutex); | 2650 | mutex_lock(&con->mutex); |
2602 | clear_standby(con); | 2651 | clear_standby(con); |
2603 | mutex_unlock(&con->mutex); | 2652 | mutex_unlock(&con->mutex); |
2604 | if (test_and_set_bit(CON_FLAG_KEEPALIVE_PENDING, &con->flags) == 0 && | 2653 | if (con_flag_test_and_set(con, CON_FLAG_KEEPALIVE_PENDING) == 0 && |
2605 | test_and_set_bit(CON_FLAG_WRITE_PENDING, &con->flags) == 0) | 2654 | con_flag_test_and_set(con, CON_FLAG_WRITE_PENDING) == 0) |
2606 | queue_con(con); | 2655 | queue_con(con); |
2607 | } | 2656 | } |
2608 | EXPORT_SYMBOL(ceph_con_keepalive); | 2657 | EXPORT_SYMBOL(ceph_con_keepalive); |