diff options
Diffstat (limited to 'fs/ceph/messenger.c')
-rw-r--r-- | fs/ceph/messenger.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index cdaaa131add3..509f57d9ccb3 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c | |||
@@ -1334,6 +1334,7 @@ static int read_partial_message(struct ceph_connection *con) | |||
1334 | unsigned front_len, middle_len, data_len, data_off; | 1334 | unsigned front_len, middle_len, data_len, data_off; |
1335 | int datacrc = con->msgr->nocrc; | 1335 | int datacrc = con->msgr->nocrc; |
1336 | int skip; | 1336 | int skip; |
1337 | u64 seq; | ||
1337 | 1338 | ||
1338 | dout("read_partial_message con %p msg %p\n", con, m); | 1339 | dout("read_partial_message con %p msg %p\n", con, m); |
1339 | 1340 | ||
@@ -1368,6 +1369,25 @@ static int read_partial_message(struct ceph_connection *con) | |||
1368 | return -EIO; | 1369 | return -EIO; |
1369 | data_off = le16_to_cpu(con->in_hdr.data_off); | 1370 | data_off = le16_to_cpu(con->in_hdr.data_off); |
1370 | 1371 | ||
1372 | /* verify seq# */ | ||
1373 | seq = le64_to_cpu(con->in_hdr.seq); | ||
1374 | if ((s64)seq - (s64)con->in_seq < 1) { | ||
1375 | pr_info("skipping %s%lld %s seq %lld, expected %lld\n", | ||
1376 | ENTITY_NAME(con->peer_name), | ||
1377 | pr_addr(&con->peer_addr.in_addr), | ||
1378 | seq, con->in_seq + 1); | ||
1379 | con->in_base_pos = -front_len - middle_len - data_len - | ||
1380 | sizeof(m->footer); | ||
1381 | con->in_tag = CEPH_MSGR_TAG_READY; | ||
1382 | con->in_seq++; | ||
1383 | return 0; | ||
1384 | } else if ((s64)seq - (s64)con->in_seq > 1) { | ||
1385 | pr_err("read_partial_message bad seq %lld expected %lld\n", | ||
1386 | seq, con->in_seq + 1); | ||
1387 | con->error_msg = "bad message sequence # for incoming message"; | ||
1388 | return -EBADMSG; | ||
1389 | } | ||
1390 | |||
1371 | /* allocate message? */ | 1391 | /* allocate message? */ |
1372 | if (!con->in_msg) { | 1392 | if (!con->in_msg) { |
1373 | dout("got hdr type %d front %d data %d\n", con->in_hdr.type, | 1393 | dout("got hdr type %d front %d data %d\n", con->in_hdr.type, |
@@ -1379,6 +1399,7 @@ static int read_partial_message(struct ceph_connection *con) | |||
1379 | con->in_base_pos = -front_len - middle_len - data_len - | 1399 | con->in_base_pos = -front_len - middle_len - data_len - |
1380 | sizeof(m->footer); | 1400 | sizeof(m->footer); |
1381 | con->in_tag = CEPH_MSGR_TAG_READY; | 1401 | con->in_tag = CEPH_MSGR_TAG_READY; |
1402 | con->in_seq++; | ||
1382 | return 0; | 1403 | return 0; |
1383 | } | 1404 | } |
1384 | if (IS_ERR(con->in_msg)) { | 1405 | if (IS_ERR(con->in_msg)) { |
@@ -2030,6 +2051,7 @@ void ceph_con_revoke_message(struct ceph_connection *con, struct ceph_msg *msg) | |||
2030 | ceph_msg_put(con->in_msg); | 2051 | ceph_msg_put(con->in_msg); |
2031 | con->in_msg = NULL; | 2052 | con->in_msg = NULL; |
2032 | con->in_tag = CEPH_MSGR_TAG_READY; | 2053 | con->in_tag = CEPH_MSGR_TAG_READY; |
2054 | con->in_seq++; | ||
2033 | } else { | 2055 | } else { |
2034 | dout("con_revoke_pages %p msg %p pages %p no-op\n", | 2056 | dout("con_revoke_pages %p msg %p pages %p no-op\n", |
2035 | con, con->in_msg, msg); | 2057 | con, con->in_msg, msg); |