diff options
Diffstat (limited to 'fs/ceph/messenger.c')
-rw-r--r-- | fs/ceph/messenger.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index cdaaa131add3..cd4fadb6491a 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c | |||
@@ -492,7 +492,14 @@ static void prepare_write_message(struct ceph_connection *con) | |||
492 | list_move_tail(&m->list_head, &con->out_sent); | 492 | list_move_tail(&m->list_head, &con->out_sent); |
493 | } | 493 | } |
494 | 494 | ||
495 | m->hdr.seq = cpu_to_le64(++con->out_seq); | 495 | /* |
496 | * only assign outgoing seq # if we haven't sent this message | ||
497 | * yet. if it is requeued, resend with it's original seq. | ||
498 | */ | ||
499 | if (m->needs_out_seq) { | ||
500 | m->hdr.seq = cpu_to_le64(++con->out_seq); | ||
501 | m->needs_out_seq = false; | ||
502 | } | ||
496 | 503 | ||
497 | dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n", | 504 | dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n", |
498 | m, con->out_seq, le16_to_cpu(m->hdr.type), | 505 | m, con->out_seq, le16_to_cpu(m->hdr.type), |
@@ -1334,6 +1341,7 @@ static int read_partial_message(struct ceph_connection *con) | |||
1334 | unsigned front_len, middle_len, data_len, data_off; | 1341 | unsigned front_len, middle_len, data_len, data_off; |
1335 | int datacrc = con->msgr->nocrc; | 1342 | int datacrc = con->msgr->nocrc; |
1336 | int skip; | 1343 | int skip; |
1344 | u64 seq; | ||
1337 | 1345 | ||
1338 | dout("read_partial_message con %p msg %p\n", con, m); | 1346 | dout("read_partial_message con %p msg %p\n", con, m); |
1339 | 1347 | ||
@@ -1368,6 +1376,25 @@ static int read_partial_message(struct ceph_connection *con) | |||
1368 | return -EIO; | 1376 | return -EIO; |
1369 | data_off = le16_to_cpu(con->in_hdr.data_off); | 1377 | data_off = le16_to_cpu(con->in_hdr.data_off); |
1370 | 1378 | ||
1379 | /* verify seq# */ | ||
1380 | seq = le64_to_cpu(con->in_hdr.seq); | ||
1381 | if ((s64)seq - (s64)con->in_seq < 1) { | ||
1382 | pr_info("skipping %s%lld %s seq %lld, expected %lld\n", | ||
1383 | ENTITY_NAME(con->peer_name), | ||
1384 | pr_addr(&con->peer_addr.in_addr), | ||
1385 | seq, con->in_seq + 1); | ||
1386 | con->in_base_pos = -front_len - middle_len - data_len - | ||
1387 | sizeof(m->footer); | ||
1388 | con->in_tag = CEPH_MSGR_TAG_READY; | ||
1389 | con->in_seq++; | ||
1390 | return 0; | ||
1391 | } else if ((s64)seq - (s64)con->in_seq > 1) { | ||
1392 | pr_err("read_partial_message bad seq %lld expected %lld\n", | ||
1393 | seq, con->in_seq + 1); | ||
1394 | con->error_msg = "bad message sequence # for incoming message"; | ||
1395 | return -EBADMSG; | ||
1396 | } | ||
1397 | |||
1371 | /* allocate message? */ | 1398 | /* allocate message? */ |
1372 | if (!con->in_msg) { | 1399 | if (!con->in_msg) { |
1373 | dout("got hdr type %d front %d data %d\n", con->in_hdr.type, | 1400 | dout("got hdr type %d front %d data %d\n", con->in_hdr.type, |
@@ -1379,6 +1406,7 @@ static int read_partial_message(struct ceph_connection *con) | |||
1379 | con->in_base_pos = -front_len - middle_len - data_len - | 1406 | con->in_base_pos = -front_len - middle_len - data_len - |
1380 | sizeof(m->footer); | 1407 | sizeof(m->footer); |
1381 | con->in_tag = CEPH_MSGR_TAG_READY; | 1408 | con->in_tag = CEPH_MSGR_TAG_READY; |
1409 | con->in_seq++; | ||
1382 | return 0; | 1410 | return 0; |
1383 | } | 1411 | } |
1384 | if (IS_ERR(con->in_msg)) { | 1412 | if (IS_ERR(con->in_msg)) { |
@@ -1965,6 +1993,8 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) | |||
1965 | 1993 | ||
1966 | BUG_ON(msg->front.iov_len != le32_to_cpu(msg->hdr.front_len)); | 1994 | BUG_ON(msg->front.iov_len != le32_to_cpu(msg->hdr.front_len)); |
1967 | 1995 | ||
1996 | msg->needs_out_seq = true; | ||
1997 | |||
1968 | /* queue */ | 1998 | /* queue */ |
1969 | mutex_lock(&con->mutex); | 1999 | mutex_lock(&con->mutex); |
1970 | BUG_ON(!list_empty(&msg->list_head)); | 2000 | BUG_ON(!list_empty(&msg->list_head)); |
@@ -2030,6 +2060,7 @@ void ceph_con_revoke_message(struct ceph_connection *con, struct ceph_msg *msg) | |||
2030 | ceph_msg_put(con->in_msg); | 2060 | ceph_msg_put(con->in_msg); |
2031 | con->in_msg = NULL; | 2061 | con->in_msg = NULL; |
2032 | con->in_tag = CEPH_MSGR_TAG_READY; | 2062 | con->in_tag = CEPH_MSGR_TAG_READY; |
2063 | con->in_seq++; | ||
2033 | } else { | 2064 | } else { |
2034 | dout("con_revoke_pages %p msg %p pages %p no-op\n", | 2065 | dout("con_revoke_pages %p msg %p pages %p no-op\n", |
2035 | con, con->in_msg, msg); | 2066 | con, con->in_msg, msg); |
@@ -2063,15 +2094,19 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, | |||
2063 | kref_init(&m->kref); | 2094 | kref_init(&m->kref); |
2064 | INIT_LIST_HEAD(&m->list_head); | 2095 | INIT_LIST_HEAD(&m->list_head); |
2065 | 2096 | ||
2097 | m->hdr.tid = 0; | ||
2066 | m->hdr.type = cpu_to_le16(type); | 2098 | m->hdr.type = cpu_to_le16(type); |
2099 | m->hdr.priority = cpu_to_le16(CEPH_MSG_PRIO_DEFAULT); | ||
2100 | m->hdr.version = 0; | ||
2067 | m->hdr.front_len = cpu_to_le32(front_len); | 2101 | m->hdr.front_len = cpu_to_le32(front_len); |
2068 | m->hdr.middle_len = 0; | 2102 | m->hdr.middle_len = 0; |
2069 | m->hdr.data_len = cpu_to_le32(page_len); | 2103 | m->hdr.data_len = cpu_to_le32(page_len); |
2070 | m->hdr.data_off = cpu_to_le16(page_off); | 2104 | m->hdr.data_off = cpu_to_le16(page_off); |
2071 | m->hdr.priority = cpu_to_le16(CEPH_MSG_PRIO_DEFAULT); | 2105 | m->hdr.reserved = 0; |
2072 | m->footer.front_crc = 0; | 2106 | m->footer.front_crc = 0; |
2073 | m->footer.middle_crc = 0; | 2107 | m->footer.middle_crc = 0; |
2074 | m->footer.data_crc = 0; | 2108 | m->footer.data_crc = 0; |
2109 | m->footer.flags = 0; | ||
2075 | m->front_max = front_len; | 2110 | m->front_max = front_len; |
2076 | m->front_is_vmalloc = false; | 2111 | m->front_is_vmalloc = false; |
2077 | m->more_to_follow = false; | 2112 | m->more_to_follow = false; |