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>
This commit is contained in:
Sage Weil 2010-04-22 07:47:01 -07:00
parent 684be25c52
commit ae18756b9f
1 changed files with 20 additions and 0 deletions

View File

@ -1334,6 +1334,7 @@ static int read_partial_message(struct ceph_connection *con)
unsigned front_len, middle_len, data_len, data_off; unsigned front_len, middle_len, data_len, data_off;
int datacrc = con->msgr->nocrc; int datacrc = con->msgr->nocrc;
int skip; int skip;
u64 seq;
dout("read_partial_message con %p msg %p\n", con, m); dout("read_partial_message con %p msg %p\n", con, m);
@ -1368,6 +1369,25 @@ static int read_partial_message(struct ceph_connection *con)
return -EIO; return -EIO;
data_off = le16_to_cpu(con->in_hdr.data_off); data_off = le16_to_cpu(con->in_hdr.data_off);
/* verify seq# */
seq = le64_to_cpu(con->in_hdr.seq);
if ((s64)seq - (s64)con->in_seq < 1) {
pr_info("skipping %s%lld %s seq %lld, expected %lld\n",
ENTITY_NAME(con->peer_name),
pr_addr(&con->peer_addr.in_addr),
seq, con->in_seq + 1);
con->in_base_pos = -front_len - middle_len - data_len -
sizeof(m->footer);
con->in_tag = CEPH_MSGR_TAG_READY;
con->in_seq++;
return 0;
} else if ((s64)seq - (s64)con->in_seq > 1) {
pr_err("read_partial_message bad seq %lld expected %lld\n",
seq, con->in_seq + 1);
con->error_msg = "bad message sequence # for incoming message";
return -EBADMSG;
}
/* allocate message? */ /* allocate message? */
if (!con->in_msg) { if (!con->in_msg) {
dout("got hdr type %d front %d data %d\n", con->in_hdr.type, dout("got hdr type %d front %d data %d\n", con->in_hdr.type,