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; |
