diff options
author | Sage Weil <sage@newdream.net> | 2010-04-22 10:47:01 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-05-03 13:49:24 -0400 |
commit | ae18756b9fa7bb93132cff06cd8575e3d46633f9 (patch) | |
tree | e09f5c89b4611e2c53bb50118d8fa8133b58c73b /fs | |
parent | 684be25c52a1e43638ced160be0b0b46596e7f2b (diff) |
ceph: discard incoming messages with bad seq #
We can get old message seq #'s after a tcp reconnect for stateful sessions
(i.e., the MDS). If we get a higher seq #, that is an error, and we
shouldn't see any bad seq #'s for stateless (mon, osd) connections.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/messenger.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index e7b91e093f54..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, |