]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
msg/Pipe: avoid creating empty out_q entry
authorSage Weil <sage@inktank.com>
Tue, 16 Jul 2013 17:09:02 +0000 (10:09 -0700)
committerSage Weil <sage@inktank.com>
Wed, 17 Jul 2013 21:34:40 +0000 (14:34 -0700)
We need to maintain the invariant that all sub queues in out_q are never
empty.  Fix discard_requeued_up_to() to avoid creating an entry unless we
know it is already present.

This bug leads to an incorrect reconnect attempt when

 - we accept a pipe (lossless peer)
 - they send some stuff, maybe
 - fault
 - we initiate reconnect, even tho we have nothing queued

In particular, we shouldn't reconnect because we aren't checking for
resets, and the fact that our out_seq is 0 while the peer's might be
something else entirely will trigger asserts later.

This fixes at least one source of #5626, and possibly #5517.

Backport: cuttlefish
Signed-off-by: Sage Weil <sage@inktank.com>
src/msg/Pipe.cc

index d45666c21c608eb4f379f9c484c0abb3fcc15310..571c3fa3233df985b37511217b2c6ec0eb7390dd 100644 (file)
@@ -1124,6 +1124,8 @@ void Pipe::requeue_sent()
 void Pipe::discard_requeued_up_to(uint64_t seq)
 {
   ldout(msgr->cct, 10) << "discard_requeued_up_to " << seq << dendl;
+  if (out_q.count(CEPH_MSG_PRIO_HIGHEST) == 0)
+    return;
   list<Message*>& rq = out_q[CEPH_MSG_PRIO_HIGHEST];
   while (!rq.empty()) {
     Message *m = rq.front();
@@ -1135,6 +1137,8 @@ void Pipe::discard_requeued_up_to(uint64_t seq)
     rq.pop_front();
     out_seq++;
   }
+  if (rq.empty())
+    out_q.erase(CEPH_MSG_PRIO_HIGHEST);
 }
 
 /*