]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
osdc/Objecter: preserve read-into-existing-buffer behavior
authorSage Weil <sage@redhat.com>
Fri, 1 Mar 2019 20:12:42 +0000 (14:12 -0600)
committerSage Weil <sage@redhat.com>
Sun, 3 Mar 2019 16:38:53 +0000 (10:38 -0600)
The libradosstriper::RadosStriperImpl::aio_read populates the target
outbl with a static buffer and relies on us reading into it.  This was
actually not reliable in the past (it could fail if the rx_buffers
optimization failed due to a retransmit or something else) but nevertheless
libradosstriper requires it to work *at all*.

Resolve this by modifying Objecter to copy the result into any provided
buffer at the lowest layer.  This should capture any other such user who
needed this behavior.

On the other hand, it will break any user who inadvertantly reads into a
non-empty bufferlist.  Given that any such user would already previously
have seen bad behavior due to the rx_buffers optimization, we expect
there to be 0 such instances.

Signed-off-by: Sage Weil <sage@redhat.com>
src/osdc/Objecter.cc

index c0a8b9e46a2932bf49a72bb9b39d7ead54c2f4bf..ee1ca23121a2213cd3c956f3cceeff5829448e66 100644 (file)
@@ -3458,6 +3458,26 @@ void Objecter::handle_osd_op_reply(MOSDOpReply *m)
     if (op->con)
       op->con->revoke_rx_buffer(op->tid);
 #endif
+    auto& bl = m->get_data();
+    if (op->outbl->length() == bl.length() &&
+       bl.get_num_buffers() <= 1) {
+      // this is here to keep previous users to *relied* on getting data
+      // read into existing buffers happy.  Notably,
+      // libradosstriper::RadosStriperImpl::aio_read().
+      ldout(cct,10) << __func__ << " copying resulting " << bl.length()
+                   << " into existing buffer of length " << op->outbl->length()
+                   << dendl;
+      bufferlist t;
+      t.claim(*op->outbl);
+      t.invalidate_crc();  // we're overwriting the raw buffers via c_str()
+      bl.copy(0, bl.length(), t.c_str());
+      op->outbl->substr_of(t, 0, bl.length());
+    } else {
+      m->claim_data(*op->outbl);
+    }
+    lderr(cct) << __func__ << " data:\n";
+    op->outbl->hexdump(*_dout);
+    *_dout << dendl;
     op->outbl = 0;
   }