summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-05-24 11:55:03 -0500
committerSage Weil <sage@inktank.com>2012-07-05 21:14:30 -0700
commit7593af920baac37752190a0db703d2732bed4a3b (patch)
treef660bc222db9b74305b8a2b8cc25d508bd0596a5 /net
parentab166d5aa3bc036fba7efaca6e4e43a7e9510acf (diff)
downloadlinux-7593af920baac37752190a0db703d2732bed4a3b.tar.gz
linux-7593af920baac37752190a0db703d2732bed4a3b.tar.bz2
linux-7593af920baac37752190a0db703d2732bed4a3b.zip
libceph: distinguish two phases of connect sequence
Currently a ceph connection enters a "CONNECTING" state when it begins the process of (re-)connecting with its peer. Once the two ends have successfully exchanged their banner and addresses, an additional NEGOTIATING bit is set in the ceph connection's state to indicate the connection information exhange has begun. The CONNECTING bit/state continues to be set during this phase. Rather than have the CONNECTING state continue while the NEGOTIATING bit is set, interpret these two phases as distinct states. In other words, when NEGOTIATING is set, clear CONNECTING. That way only one of them will be active at a time. 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.c52
1 files changed, 28 insertions, 24 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 5e67be3fa296..32a3a2a72580 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -1559,7 +1559,6 @@ static int process_connect(struct ceph_connection *con)
return -1;
}
clear_bit(NEGOTIATING, &con->state);
- clear_bit(CONNECTING, &con->state);
set_bit(CONNECTED, &con->state);
con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq);
con->connect_seq++;
@@ -2000,7 +1999,8 @@ more_kvec:
}
do_next:
- if (!test_bit(CONNECTING, &con->state)) {
+ if (!test_bit(CONNECTING, &con->state) &&
+ !test_bit(NEGOTIATING, &con->state)) {
/* is anything else pending? */
if (!list_empty(&con->out_queue)) {
prepare_write_message(con);
@@ -2057,25 +2057,29 @@ more:
}
if (test_bit(CONNECTING, &con->state)) {
- if (!test_bit(NEGOTIATING, &con->state)) {
- dout("try_read connecting\n");
- ret = read_partial_banner(con);
- if (ret <= 0)
- goto out;
- ret = process_banner(con);
- if (ret < 0)
- goto out;
-
- /* Banner is good, exchange connection info */
- ret = prepare_write_connect(con);
- if (ret < 0)
- goto out;
- prepare_read_connect(con);
- set_bit(NEGOTIATING, &con->state);
-
- /* Send connection info before awaiting response */
+ dout("try_read connecting\n");
+ ret = read_partial_banner(con);
+ if (ret <= 0)
goto out;
- }
+ ret = process_banner(con);
+ if (ret < 0)
+ goto out;
+
+ clear_bit(CONNECTING, &con->state);
+ set_bit(NEGOTIATING, &con->state);
+
+ /* Banner is good, exchange connection info */
+ ret = prepare_write_connect(con);
+ if (ret < 0)
+ goto out;
+ prepare_read_connect(con);
+
+ /* Send connection info before awaiting response */
+ goto out;
+ }
+
+ if (test_bit(NEGOTIATING, &con->state)) {
+ dout("try_read negotiating\n");
ret = read_partial_connect(con);
if (ret <= 0)
goto out;
@@ -2197,12 +2201,12 @@ restart:
if (test_and_clear_bit(SOCK_CLOSED, &con->flags)) {
if (test_and_clear_bit(CONNECTED, &con->state))
con->error_msg = "socket closed";
- else if (test_and_clear_bit(CONNECTING, &con->state)) {
- clear_bit(NEGOTIATING, &con->state);
+ else if (test_and_clear_bit(NEGOTIATING, &con->state))
+ con->error_msg = "negotiation failed";
+ else if (test_and_clear_bit(CONNECTING, &con->state))
con->error_msg = "connection failed";
- } else {
+ else
con->error_msg = "unrecognized con state";
- }
goto fault;
}