]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osdc/Objecter: invalidate crcs on preallocated rx buffers 29247/head
authorIlya Dryomov <idryomov@gmail.com>
Wed, 20 Feb 2019 21:30:29 +0000 (22:30 +0100)
committerNathan Cutler <ncutler@suse.com>
Wed, 28 Aug 2019 07:38:01 +0000 (09:38 +0200)
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>
(cherry picked from commit 3eeab975b604d9fc4290747f85a78d59a2452c2e)

Conflicts:
src/test/librados/io_cxx.cc
- In master, 3730d10623650ce8569be96b28cbba599a9a0db6 renamed this file from
  src/test/librados/io.cc but that commit is not being backported to mimic.
  Manually cherry-picked the test mods into src/test/librados/io.cc.

src/osdc/Objecter.cc
src/test/librados/io.cc

index b4a96a78ee5a6f066d03d02c7dca1b3a6607c8b0..9e2c610ee49d7cf8250848dad0206da50e4814cf 100644 (file)
@@ -3286,6 +3286,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 0f879fa45e180d8a1d486f1867be400d3754a9c8..2f8a3251470bfec7dd8a9890c5c47f929477aa7e 100644 (file)
@@ -235,6 +235,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) {
@@ -799,6 +814,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) {