]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: raise ExtentMap/Blob encoding version to handle migration from ref_map...
authorIgor Fedotov <ifedotov@mirantis.com>
Wed, 11 Jan 2017 17:47:11 +0000 (20:47 +0300)
committerIgor Fedotov <ifedotov@mirantis.com>
Thu, 26 Jan 2017 23:37:44 +0000 (23:37 +0000)
Signed-off-by: Igor Fedotov <ifedotov@mirantis.com>
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h
src/os/bluestore/bluestore_types.h
src/test/objectstore/test_bluestore_types.cc

index bd7ece3b881af9b37d5945381f3e5ba79d5a704a..8b7ea2d6dc633bb16f655d6e6123f36d86a1f1ae 100644 (file)
@@ -1683,6 +1683,36 @@ void BlueStore::Blob::split(Collection *coll, uint32_t blob_offset, Blob *r)
           << "    and " << *r << dendl;
 }
 
+#ifndef CACHE_BLOB_BL
+void BlueStore::Blob::decode(
+  Collection *coll,
+  bufferptr::iterator& p,
+  uint64_t struct_v,
+  uint64_t* sbid,
+  bool include_ref_map)
+{
+  denc(blob, p, struct_v);
+  if (blob.is_shared()) {
+    denc(*sbid, p);
+  }
+  if (include_ref_map) {
+    if (struct_v > 1) {
+      used_in_blob.decode(p);
+    } else {
+      used_in_blob.clear();
+      bluestore_extent_ref_map_t legacy_ref_map;
+      legacy_ref_map.decode(p);
+      for (auto r : legacy_ref_map.ref_map) {
+        get_ref(
+          coll,
+          r.first,
+          r.second.refs * r.second.length);
+      }
+    }
+  }
+}
+#endif
+
 // Extent
 
 ostream& operator<<(ostream& out, const BlueStore::Extent& e)
@@ -1956,7 +1986,9 @@ bool BlueStore::ExtentMap::encode_some(
   auto start = extent_map.lower_bound(dummy);
   uint32_t end = offset + length;
 
-  __u8 struct_v = 1;
+  __u8 struct_v = 2; // Version 2 differs from v1 in blob's ref_map
+                     // serialization only. Hence there is no specific
+                     // handling at ExtentMap level.
 
   unsigned n = 0;
   size_t bound = 0;
@@ -2057,7 +2089,11 @@ void BlueStore::ExtentMap::decode_some(bufferlist& bl)
   auto p = bl.front().begin_deep();
   __u8 struct_v;
   denc(struct_v, p);
-  assert(struct_v == 1);
+  // Version 2 differs from v1 in blob's ref_map
+  // serialization only. Hence there is no specific
+  // handling at ExtentMap level below.
+  assert(struct_v == 1 || struct_v == 2);
+
   uint32_t num;
   denc_varint(num, p);
   vector<BlobRef> blobs(num);
@@ -2095,7 +2131,7 @@ void BlueStore::ExtentMap::decode_some(bufferlist& bl)
       } else {
        Blob *b = new Blob();
         uint64_t sbid = 0;
-       b->decode(p, struct_v, &sbid, false);
+        b->decode(onode->c, p, struct_v, &sbid, false);
        blobs[n] = b;
        onode->c->open_shared_blob(sbid, b);
        le->assign_blob(b);
@@ -2116,7 +2152,11 @@ void BlueStore::ExtentMap::decode_some(bufferlist& bl)
 
 void BlueStore::ExtentMap::bound_encode_spanning_blobs(size_t& p)
 {
-  __u8 struct_v = 1;
+  // Version 2 differs from v1 in blob's ref_map
+  // serialization only. Hence there is no specific
+  // handling at ExtentMap level.
+  __u8 struct_v = 2;
+
   denc(struct_v, p);
   denc_varint((uint32_t)0, p);
   size_t key_size = 0;
@@ -2130,7 +2170,11 @@ void BlueStore::ExtentMap::bound_encode_spanning_blobs(size_t& p)
 void BlueStore::ExtentMap::encode_spanning_blobs(
   bufferlist::contiguous_appender& p)
 {
-  __u8 struct_v = 1;
+  // Version 2 differs from v1 in blob's ref_map
+  // serialization only. Hence there is no specific
+  // handling at ExtentMap level.
+  __u8 struct_v = 2;
+
   denc(struct_v, p);
   denc_varint(spanning_blob_map.size(), p);
   for (auto& i : spanning_blob_map) {
@@ -2144,7 +2188,11 @@ void BlueStore::ExtentMap::decode_spanning_blobs(
 {
   __u8 struct_v;
   denc(struct_v, p);
-  assert(struct_v == 1);
+  // Version 2 differs from v1 in blob's ref_map
+  // serialization only. Hence there is no specific
+  // handling at ExtentMap level.
+  assert(struct_v == 1 || struct_v == 2);
+
   unsigned n;
   denc_varint(n, p);
   while (n--) {
@@ -2152,7 +2200,7 @@ void BlueStore::ExtentMap::decode_spanning_blobs(
     denc_varint(b->id, p);
     spanning_blob_map[b->id] = b;
     uint64_t sbid = 0;
-    b->decode(p, struct_v, &sbid, true);
+    b->decode(onode->c, p, struct_v, &sbid, true);
     onode->c->open_shared_blob(sbid, b);
   }
 }
index 47f551e62b77b21c73e77fe888f8ac6a8a794c33..d7161b6a8bc59a3728bef9e2b3a96c6e3dac7ac5 100644 (file)
@@ -525,6 +525,7 @@ public:
       }
     }
     void decode(
+      Collection */*coll*/,
       bufferptr::iterator& p,
       bool include_ref_map) {
       const char *start = p.get_pos();
@@ -564,18 +565,11 @@ public:
       }
     }
     void decode(
+      Collection *coll,
       bufferptr::iterator& p,
       uint64_t struct_v,
       uint64_t* sbid,
-      bool include_ref_map) {
-      denc(blob, p, struct_v);
-      if (blob.is_shared()) {
-        denc(*sbid, p);
-      }
-      if (include_ref_map) {
-       used_in_blob.decode(p);
-      }
-    }
+      bool include_ref_map);
 #endif
   };
   typedef boost::intrusive_ptr<Blob> BlobRef;
index 80990f1ebfdac45a841c6570115929eb632a7c7d..610f1fe29b2beb55d3b075c703c10e2c34ace729 100644 (file)
@@ -456,7 +456,7 @@ struct bluestore_blob_t {
 
   DENC_HELPERS;
   void bound_encode(size_t& p, uint64_t struct_v) const {
-    assert(struct_v == 1);
+    assert(struct_v == 1 || struct_v == 2);
     denc(extents, p);
     denc_varint(flags, p);
     denc_varint_lowz(compressed_length_orig, p);
@@ -469,7 +469,7 @@ struct bluestore_blob_t {
   }
 
   void encode(bufferlist::contiguous_appender& p, uint64_t struct_v) const {
-    assert(struct_v == 1);
+    assert(struct_v == 1 || struct_v == 2);
     denc(extents, p);
     denc_varint(flags, p);
     if (is_compressed()) {
@@ -489,7 +489,7 @@ struct bluestore_blob_t {
   }
 
   void decode(bufferptr::iterator& p, uint64_t struct_v) {
-    assert(struct_v == 1);
+    assert(struct_v == 1 || struct_v == 2);
     denc(extents, p);
     denc_varint(flags, p);
     if (is_compressed()) {
index 87d16cd67c02c8b4c200684ce3de20c97a7ebecf..4bb7e360a2617b6c55e0e632c5dcea97c1bb7dc8 100644 (file)
@@ -938,6 +938,82 @@ TEST(Blob, split)
   }
 }
 
+TEST(Blob, legacy_decode)
+{
+  BlueStore store(g_ceph_context, "", 4096);
+  BlueStore::Cache *cache = BlueStore::Cache::create(
+    g_ceph_context, "lru", NULL);
+  BlueStore::Collection coll(&store, cache, coll_t());
+  bufferlist bl, bl2;
+  {
+    BlueStore::Blob B;
+    B.shared_blob = new BlueStore::SharedBlob(&coll);
+    B.dirty_blob().extents.emplace_back(bluestore_pextent_t(0x1, 0x2000));
+    B.dirty_blob().init_csum(Checksummer::CSUM_CRC32C, 12, 0x2000);
+    B.get_ref(&coll, 0, 0xff0);
+    B.get_ref(&coll, 0x1fff, 1);
+
+    bluestore_extent_ref_map_t fake_ref_map;
+    fake_ref_map.get(0, 0xff0);
+    fake_ref_map.get(0x1fff, 1);
+
+    size_t bound = 0, bound2 = 0;
+
+    B.bound_encode(
+      bound,
+      1, /*struct_v*/
+      0, /*sbid*/
+      false);
+    fake_ref_map.bound_encode(bound);
+
+    B.bound_encode(
+      bound2,
+      2, /*struct_v*/
+      0, /*sbid*/
+      true);
+
+    {
+      auto app = bl.get_contiguous_appender(bound);
+      auto app2 = bl2.get_contiguous_appender(bound2);
+      B.encode(
+        app,
+        1, /*struct_v*/
+        0, /*sbid*/
+        false);
+      fake_ref_map.encode(app);
+
+      B.encode(
+        app2,
+        2, /*struct_v*/
+        0, /*sbid*/
+        true);
+    }
+
+    auto p = bl.front().begin_deep();
+    auto p2 = bl2.front().begin_deep();
+    BlueStore::Blob Bres, Bres2;
+    Bres.shared_blob = new BlueStore::SharedBlob(&coll);
+    Bres2.shared_blob = new BlueStore::SharedBlob(&coll);
+   
+    uint64_t sbid, sbid2;
+    Bres.decode(
+      &coll,
+      p,
+      1, /*struct_v*/
+      &sbid,
+      true);
+    Bres2.decode(
+      &coll,
+      p2,
+      2, /*struct_v*/
+      &sbid2,
+      true);
+
+    ASSERT_EQ(0xff0u + 1u, Bres.get_blob_use_tracker().get_referenced_bytes());
+    ASSERT_EQ(0xff0u + 1u, Bres2.get_blob_use_tracker().get_referenced_bytes());
+    ASSERT_TRUE(Bres.get_blob_use_tracker().equal(Bres2.get_blob_use_tracker()));
+  }
+}
 TEST(ExtentMap, find_lextent)
 {
   BlueStore store(g_ceph_context, "", 4096);