From: Piotr Dałek Date: Fri, 15 May 2015 13:44:18 +0000 (+0200) Subject: bufferlist: implement bufferlist::invalidate_crc() X-Git-Tag: v9.0.3~188^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=55a6f9efbee041d041742810ca4fa8874b6191a7;p=ceph.git bufferlist: implement bufferlist::invalidate_crc() This function iterates over all bufferlist internal buffers and calls their invalidate_crc() method. Required for rados bench to work correctly, because it modifies buffers outside buffer api, invalidating internal CRC cache in the process - this method clears that cache, so another call for buffer::get_crc() to return correct checksum. Signed-off-by: Piotr Dałek --- diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 258880b011d4..0d54142faeb9 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -1866,6 +1866,15 @@ __u32 buffer::list::crc32c(__u32 crc) const return crc; } +void buffer::list::invalidate_crc() +{ + for (std::list::const_iterator p = _buffers.begin(); p != _buffers.end(); ++p) { + raw *r = p->get_raw(); + if (r) { + r->invalidate_crc(); + } + } +} /** * Binary write all contents to a C++ stream diff --git a/src/include/buffer.h b/src/include/buffer.h index 9af95ae9a06b..911581ac64a9 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -490,6 +490,7 @@ public: int write_fd(int fd) const; int write_fd_zero_copy(int fd) const; uint32_t crc32c(uint32_t crc) const; + void invalidate_crc(); }; /* diff --git a/src/test/bufferlist.cc b/src/test/bufferlist.cc index 86141f0c4619..0170d4fb50ce 100644 --- a/src/test/bufferlist.cc +++ b/src/test/bufferlist.cc @@ -2374,6 +2374,46 @@ TEST(BufferList, TestCopyAll) { ASSERT_EQ(memcmp(big.get(), big2.get(), BIG_SZ), 0); } +TEST(BufferList, InvalidateCrc) { + const static size_t buffer_size = 262144; + ceph::shared_ptr big( + (unsigned char*)malloc(buffer_size), free); + unsigned char c = 0; + char* ptr = (char*) big.get(); + char* inptr; + for (size_t i = 0; i < buffer_size; ++i) { + ptr[i] = c++; + } + bufferlist bl; + + // test for crashes (shouldn't crash) + bl.invalidate_crc(); + + // put data into bufferlist + bl.append((const char*)big.get(), buffer_size); + + // get its crc + __u32 crc = bl.crc32c(0); + + // modify data in bl without its knowledge + inptr = (char*) bl.c_str(); + c = 0; + for (size_t i = 0; i < buffer_size; ++i) { + inptr[i] = c--; + } + + // make sure data in bl are now different than in big + EXPECT_NE(memcmp((void*) ptr, (void*) inptr, buffer_size), 0); + + // crc should remain the same + __u32 new_crc = bl.crc32c(0); + EXPECT_EQ(crc, new_crc); + + // force crc invalidate, check if it is updated + bl.invalidate_crc(); + EXPECT_NE(crc, bl.crc32c(0)); +} + TEST(BufferHash, all) { { bufferlist bl;