aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/messenger.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2009-12-23 12:30:21 -0500
committerSage Weil <sage@newdream.net>2009-12-23 12:30:21 -0500
commit04a419f908b5291ff7e8ffd7aa351fa0ac0c08af (patch)
tree2e634bdca766c27b88280ab5c1ce067f47ffe536 /fs/ceph/messenger.c
parent6df058c025ce343052c5516b1d8a9a7e73cddd64 (diff)
ceph: add feature bits to connection handshake (protocol change)
Define supported and required feature set. Fail connection if the server requires features we do not support (TAG_FEATURES), or if the server does not support features we require. Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/messenger.c')
-rw-r--r--fs/ceph/messenger.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c
index 506b638a023b..68052f664280 100644
--- a/fs/ceph/messenger.c
+++ b/fs/ceph/messenger.c
@@ -631,6 +631,7 @@ static void prepare_write_connect(struct ceph_messenger *msgr,
631 dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con, 631 dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con,
632 con->connect_seq, global_seq, proto); 632 con->connect_seq, global_seq, proto);
633 633
634 con->out_connect.features = CEPH_FEATURE_SUPPORTED;
634 con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT); 635 con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT);
635 con->out_connect.connect_seq = cpu_to_le32(con->connect_seq); 636 con->out_connect.connect_seq = cpu_to_le32(con->connect_seq);
636 con->out_connect.global_seq = cpu_to_le32(global_seq); 637 con->out_connect.global_seq = cpu_to_le32(global_seq);
@@ -1080,15 +1081,37 @@ static int process_banner(struct ceph_connection *con)
1080 return 0; 1081 return 0;
1081} 1082}
1082 1083
1084static void fail_protocol(struct ceph_connection *con)
1085{
1086 reset_connection(con);
1087 set_bit(CLOSED, &con->state); /* in case there's queued work */
1088
1089 mutex_unlock(&con->mutex);
1090 if (con->ops->bad_proto)
1091 con->ops->bad_proto(con);
1092 mutex_lock(&con->mutex);
1093}
1094
1083static int process_connect(struct ceph_connection *con) 1095static int process_connect(struct ceph_connection *con)
1084{ 1096{
1097 u64 sup_feat = CEPH_FEATURE_SUPPORTED;
1098 u64 req_feat = CEPH_FEATURE_REQUIRED;
1099 u64 server_feat = le64_to_cpu(con->in_reply.features);
1100
1085 dout("process_connect on %p tag %d\n", con, (int)con->in_tag); 1101 dout("process_connect on %p tag %d\n", con, (int)con->in_tag);
1086 1102
1087 switch (con->in_reply.tag) { 1103 switch (con->in_reply.tag) {
1104 case CEPH_MSGR_TAG_FEATURES:
1105 pr_err("%s%lld %s feature set mismatch,"
1106 " my %llx < server's %llx, missing %llx\n",
1107 ENTITY_NAME(con->peer_name),
1108 pr_addr(&con->peer_addr.in_addr),
1109 sup_feat, server_feat, server_feat & ~sup_feat);
1110 con->error_msg = "missing required protocol features";
1111 fail_protocol(con);
1112 return -1;
1113
1088 case CEPH_MSGR_TAG_BADPROTOVER: 1114 case CEPH_MSGR_TAG_BADPROTOVER:
1089 dout("process_connect got BADPROTOVER my %d != their %d\n",
1090 le32_to_cpu(con->out_connect.protocol_version),
1091 le32_to_cpu(con->in_reply.protocol_version));
1092 pr_err("%s%lld %s protocol version mismatch," 1115 pr_err("%s%lld %s protocol version mismatch,"
1093 " my %d != server's %d\n", 1116 " my %d != server's %d\n",
1094 ENTITY_NAME(con->peer_name), 1117 ENTITY_NAME(con->peer_name),
@@ -1096,13 +1119,7 @@ static int process_connect(struct ceph_connection *con)
1096 le32_to_cpu(con->out_connect.protocol_version), 1119 le32_to_cpu(con->out_connect.protocol_version),
1097 le32_to_cpu(con->in_reply.protocol_version)); 1120 le32_to_cpu(con->in_reply.protocol_version));
1098 con->error_msg = "protocol version mismatch"; 1121 con->error_msg = "protocol version mismatch";
1099 reset_connection(con); 1122 fail_protocol(con);
1100 set_bit(CLOSED, &con->state); /* in case there's queued work */
1101
1102 mutex_unlock(&con->mutex);
1103 if (con->ops->bad_proto)
1104 con->ops->bad_proto(con);
1105 mutex_lock(&con->mutex);
1106 return -1; 1123 return -1;
1107 1124
1108 case CEPH_MSGR_TAG_BADAUTHORIZER: 1125 case CEPH_MSGR_TAG_BADAUTHORIZER:
@@ -1173,6 +1190,16 @@ static int process_connect(struct ceph_connection *con)
1173 break; 1190 break;
1174 1191
1175 case CEPH_MSGR_TAG_READY: 1192 case CEPH_MSGR_TAG_READY:
1193 if (req_feat & ~server_feat) {
1194 pr_err("%s%lld %s protocol feature mismatch,"
1195 " my required %llx > server's %llx, need %llx\n",
1196 ENTITY_NAME(con->peer_name),
1197 pr_addr(&con->peer_addr.in_addr),
1198 req_feat, server_feat, req_feat & ~server_feat);
1199 con->error_msg = "missing required protocol features";
1200 fail_protocol(con);
1201 return -1;
1202 }
1176 clear_bit(CONNECTING, &con->state); 1203 clear_bit(CONNECTING, &con->state);
1177 con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq); 1204 con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq);
1178 con->connect_seq++; 1205 con->connect_seq++;