]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
osdc/Objecter: invalidate crcs on preallocated rx buffers
authorIlya Dryomov <idryomov@gmail.com>
Wed, 20 Feb 2019 21:30:29 +0000 (22:30 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 20 Feb 2019 23:38:04 +0000 (00:38 +0100)
Both simple and async messengers use c_str() when copying the data from
the socket into the receive buffer, going behind bufferlist's back.  If
the receive buffer is preallocated, we need to invalidate its crc cache
by hand to avoid possible data crc mismatches on the client side.

Fixes: https://tracker.ceph.com/issues/38416
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
src/osdc/Objecter.cc
src/test/librados/io_cxx.cc

index 841cfabf99d188903659bff9ec191bf778666282..1f839cabc7a1d66bc8d197e37a4c6b96080fa70d 100644 (file)
@@ -3255,6 +3255,7 @@ void Objecter::_send_op(Op *op)
   if (op->outbl &&
       op->ontimeout == 0 &&  // only post rx_buffer if no timeout; see #9582
       op->outbl->length()) {
+    op->outbl->invalidate_crc();  // messenger writes through c_str()
     ldout(cct, 20) << " posting rx buffer for " << op->tid << " on " << con
                   << dendl;
     op->con = con;
index 5930849100b87ce15af5b1665243b87437af7bb3..c5a01215fc16d5331cf6bab31a1f6b588bf88271 100644 (file)
@@ -167,6 +167,21 @@ TEST_F(LibRadosIoPP, ReadOpPP) {
       ASSERT_EQ(0, memcmp(read_bl1.c_str(), buf, sizeof(buf)));
       ASSERT_EQ(0, memcmp(read_bl2.c_str(), buf, sizeof(buf)));
   }
+
+  // read into a preallocated buffer with a cached crc
+  {
+      bufferlist op_bl;
+      op_bl.append(std::string(sizeof(buf), 'x'));
+      ASSERT_NE(op_bl.crc32c(0), bl.crc32c(0));  // cache 'x' crc
+
+      ObjectReadOperation op;
+      op.read(0, sizeof(buf), NULL, NULL);
+      ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl));
+
+      ASSERT_EQ(sizeof(buf), op_bl.length());
+      ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf)));
+      ASSERT_EQ(op_bl.crc32c(0), bl.crc32c(0));
+  }
 }
 
 TEST_F(LibRadosIoPP, SparseReadOpPP) {
@@ -551,6 +566,21 @@ TEST_F(LibRadosIoECPP, ReadOpPP) {
       ASSERT_EQ(0, memcmp(read_bl1.c_str(), buf, sizeof(buf)));
       ASSERT_EQ(0, memcmp(read_bl2.c_str(), buf, sizeof(buf)));
   }
+
+  // read into a preallocated buffer with a cached crc
+  {
+      bufferlist op_bl;
+      op_bl.append(std::string(sizeof(buf), 'x'));
+      ASSERT_NE(op_bl.crc32c(0), bl.crc32c(0));  // cache 'x' crc
+
+      ObjectReadOperation op;
+      op.read(0, sizeof(buf), NULL, NULL);
+      ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl));
+
+      ASSERT_EQ(sizeof(buf), op_bl.length());
+      ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf)));
+      ASSERT_EQ(op_bl.crc32c(0), bl.crc32c(0));
+  }
 }
 
 TEST_F(LibRadosIoECPP, SparseReadOpPP) {