]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osdc/Objecter: only post_rx_buffer if no op timeout
authorSage Weil <sage@redhat.com>
Thu, 25 Sep 2014 20:16:52 +0000 (13:16 -0700)
committerSage Weil <sage@redhat.com>
Thu, 2 Oct 2014 21:54:05 +0000 (14:54 -0700)
If we post an rx buffer and there is a timeout, the revocation can happen
while the reader has consumed the buffers but before it has decoded and
constructed the message.  In particular, we calculate a crc32c over the
data portion of the message after we've taken the buffers and dropped the
lock.

Instead of fixing this race (for example, by reverifying rx_buffers under
the lock while calculating the crc.. bleh), just skip the rx buffer
optimization entirely when a timeout is present.

Note that this doesn't cover the op_cancel() paths, but none of those users
provide static buffers to read into.

Fixes: #9582
Backport: firefly, dumpling
Signed-off-by: Sage Weil <sage@redhat.com>
backport of 126d0b30e990519b8f845f99ba893fdcd56de447

src/osdc/Objecter.cc

index d82b3e12902ec0cc11dd161e803af5a241ecbc21..695979d5c0427154be5c01a40aa28ec3f3e22584 100644 (file)
@@ -1640,7 +1640,9 @@ void Objecter::send_op(Op *op)
     ldout(cct, 20) << " revoking rx buffer for " << op->tid << " on " << op->con << dendl;
     op->con->revoke_rx_buffer(op->tid);
   }
-  if (op->outbl && op->outbl->length()) {
+  if (op->outbl &&
+      op->ontimeout == NULL &&  // only post rx_buffer if no timeout; see #9582
+      op->outbl->length()) {
     ldout(cct, 20) << " posting rx buffer for " << op->tid << " on " << op->session->con << dendl;
     op->con = op->session->con;
     op->con->post_rx_buffer(op->tid, *op->outbl);