]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
bufferlist: implement bufferlist::invalidate_crc()
authorPiotr Dałek <piotr.dalek@ts.fujitsu.com>
Fri, 15 May 2015 13:44:18 +0000 (15:44 +0200)
committerPiotr Dałek <piotr.dalek@ts.fujitsu.com>
Tue, 19 May 2015 11:43:04 +0000 (13:43 +0200)
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 <piotr.dalek@ts.fujitsu.com>
src/common/buffer.cc
src/include/buffer.h
src/test/bufferlist.cc

index 258880b011d45e63fbd0174e080057b7029e90d0..0d54142faeb9552cc42bf7b56457dfc362eaeafd 100644 (file)
@@ -1866,6 +1866,15 @@ __u32 buffer::list::crc32c(__u32 crc) const
   return crc;
 }
 
+void buffer::list::invalidate_crc()
+{
+  for (std::list<ptr>::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
index 9af95ae9a06b6f99c9686b56a5acccc044317b4b..911581ac64a9e93e0a462ca22ede6f27a47b5c4a 100644 (file)
@@ -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();
   };
 
   /*
index 86141f0c4619767d84686e1a1a544b3f100baa24..0170d4fb50ce55d543e3af5904c1e76dacb5068f 100644 (file)
@@ -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 <unsigned char> 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;