]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: store blob logical length rather than recalculate it on pextent vector
authorIgor Fedotov <ifedotov@mirantis.com>
Tue, 17 Jan 2017 17:07:43 +0000 (17:07 +0000)
committerIgor Fedotov <ifedotov@mirantis.com>
Mon, 27 Mar 2017 11:54:52 +0000 (11:54 +0000)
Signed-off-by: Igor Fedotov <ifedotov@mirantis.com>
src/os/bluestore/BlueStore.cc
src/os/bluestore/bluestore_types.cc
src/os/bluestore/bluestore_types.h
src/test/objectstore/test_bluestore_types.cc

index cee896ca6d28b92222bd9725cc82ffc1175cd074..fdf936fe861409d8085ac540dad509d6f8c06968 100644 (file)
@@ -1668,7 +1668,7 @@ void BlueStore::Blob::discard_unallocated(Collection *coll)
     assert(discard == all_invalid); // in case of compressed blob all
                                    // or none pextents are invalid.
     if (discard) {
-      shared_blob->bc.discard(shared_blob->get_cache(), 0, blob.get_compressed_payload_original_length());
+      shared_blob->bc.discard(shared_blob->get_cache(), 0, blob.get_logical_length());
     }
   } else {
     size_t pos = 0;
@@ -1777,6 +1777,7 @@ bool BlueStore::Blob::put_ref(
       }
       pos += e.length;
     }
+    assert(b.is_compressed() || b.get_logical_length() == pos);
     b.extents.resize(1);
     b.extents[0].offset = bluestore_pextent_t::INVALID_OFFSET;
     b.extents[0].length = pos;
@@ -1861,9 +1862,12 @@ void BlueStore::Blob::split(Collection *coll, uint32_t blob_offset, Blob *r)
     blob_offset,
     &(r->used_in_blob));
 
+  uint32_t llen_lb = 0;
+  uint32_t llen_rb = 0;
   for (auto p = lb.extents.begin(); p != lb.extents.end(); ++p, ++i) {
     if (p->length <= left) {
       left -= p->length;
+      llen_lb += p->length;
       continue;
     }
     if (left) {
@@ -1875,14 +1879,19 @@ void BlueStore::Blob::split(Collection *coll, uint32_t blob_offset, Blob *r)
                                  bluestore_pextent_t::INVALID_OFFSET,
                                  p->length - left));
       }
+      llen_rb += p->length - left;
+      llen_lb += left;
       p->length = left;
       ++i;
       ++p;
     }
     while (p != lb.extents.end()) {
+      llen_rb += p->length;
       rb.extents.push_back(*p++);
     }
     lb.extents.resize(i);
+    lb.logical_length = llen_lb;
+    rb.logical_length = llen_rb;
     break;
   }
   rb.flags = lb.flags;
@@ -9000,6 +9009,7 @@ int BlueStore::_do_alloc_write(
     }
     if (!compressed) {
       dblob.set_flag(bluestore_blob_t::FLAG_MUTABLE);
+      dblob.logical_length = final_length;
       if (l->length() != wi.blob_length) {
        // hrm, maybe we could do better here, but let's not bother.
        dout(20) << __func__ << " forcing csum_order to block_size_order "
index 7bd6021d692f7519d541d1ddf47fc78873e8f77b..610df4e4d89238704d01cf084ebe4fc4c1c46cc6 100644 (file)
@@ -608,7 +608,7 @@ void bluestore_blob_t::dump(Formatter *f) const
     f->dump_object("extent", p);
   }
   f->close_section();
-  f->dump_unsigned("compressed_length_original", compressed_length_orig);
+  f->dump_unsigned("logical_length", logical_length);
   f->dump_unsigned("compressed_length", compressed_length);
   f->dump_unsigned("flags", flags);
   f->dump_unsigned("csum_type", csum_type);
@@ -627,15 +627,19 @@ void bluestore_blob_t::generate_test_instances(list<bluestore_blob_t*>& ls)
   ls.push_back(new bluestore_blob_t(0));
   ls.push_back(new bluestore_blob_t);
   ls.back()->extents.push_back(bluestore_pextent_t(111, 222));
+  ls.back()->logical_length += 222;
   ls.push_back(new bluestore_blob_t);
   ls.back()->init_csum(Checksummer::CSUM_XXHASH32, 16, 65536);
   ls.back()->csum_data = buffer::claim_malloc(4, strdup("abcd"));
   ls.back()->extents.emplace_back(bluestore_pextent_t(0x40100000, 0x10000));
+  ls.back()->logical_length += 0x10000;
   ls.back()->extents.emplace_back(
     bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET, 0x1000));
+  ls.back()->logical_length += 0x1000;
   ls.back()->extents.emplace_back(bluestore_pextent_t(0x40120000, 0x10000));
   ls.back()->add_unused(0, 3);
   ls.back()->add_unused(8, 8);
+  ls.back()->logical_length += 0x10000;
 }
 
 ostream& operator<<(ostream& out, const bluestore_blob_t& o)
@@ -643,7 +647,7 @@ ostream& operator<<(ostream& out, const bluestore_blob_t& o)
   out << "blob(" << o.extents;
   if (o.is_compressed()) {
     out << " clen 0x" << std::hex
-       << o.compressed_length_orig
+       << o.logical_length
        << " -> 0x"
        << o.compressed_length
        << std::dec;
index 7e1550935a64f86d3a3ff003c075c90f3e5c57a3..48c53c349658f6c453a55d2e446e82ddb33ea993 100644 (file)
@@ -447,9 +447,8 @@ struct bluestore_blob_t {
   };
   static string get_flags_string(unsigned flags);
 
-
   PExtentVector extents;              ///< raw data position on device
-  uint32_t compressed_length_orig = 0;///< original length of compressed blob if any
+  uint32_t logical_length = 0;        ///< < original length of data stored in the blob
   uint32_t compressed_length = 0;     ///< compressed length if any
   uint32_t flags = 0;                 ///< FLAG_*
 
@@ -467,7 +466,7 @@ struct bluestore_blob_t {
     assert(struct_v == 1 || struct_v == 2);
     denc(extents, p);
     denc_varint(flags, p);
-    denc_varint_lowz(compressed_length_orig, p);
+    denc_varint_lowz(logical_length, p);
     denc_varint_lowz(compressed_length, p);
     denc(csum_type, p);
     denc(csum_chunk_order, p);
@@ -481,7 +480,7 @@ struct bluestore_blob_t {
     denc(extents, p);
     denc_varint(flags, p);
     if (is_compressed()) {
-      denc_varint_lowz(compressed_length_orig, p);
+      denc_varint_lowz(logical_length, p);
       denc_varint_lowz(compressed_length, p);
     }
     if (has_csum()) {
@@ -501,8 +500,10 @@ struct bluestore_blob_t {
     denc(extents, p);
     denc_varint(flags, p);
     if (is_compressed()) {
-      denc_varint_lowz(compressed_length_orig, p);
+      denc_varint_lowz(logical_length, p);
       denc_varint_lowz(compressed_length, p);
+    } else {
+      logical_length = get_ondisk_length();
     }
     if (has_csum()) {
       denc(csum_type, p);
@@ -544,7 +545,7 @@ struct bluestore_blob_t {
 
   void set_compressed(uint64_t clen_orig, uint64_t clen) {
     set_flag(FLAG_COMPRESSED);
-    compressed_length_orig = clen_orig;
+    logical_length = clen_orig;
     compressed_length = clen;
   }
   bool is_mutable() const {
@@ -574,9 +575,6 @@ struct bluestore_blob_t {
   uint32_t get_compressed_payload_length() const {
     return is_compressed() ? compressed_length : 0;
   }
-  uint32_t get_compressed_payload_original_length() const {
-    return is_compressed() ? compressed_length_orig : 0;
-  }
   uint64_t calc_offset(uint64_t x_off, uint64_t *plen) const {
     auto p = extents.begin();
     assert(p != extents.end());
@@ -720,11 +718,7 @@ struct bluestore_blob_t {
   }
 
   uint32_t get_logical_length() const {
-    if (is_compressed()) {
-      return compressed_length_orig;
-    } else {
-      return get_ondisk_length();
-    }
+    return logical_length;
   }
   size_t get_csum_value_size() const;
 
@@ -785,6 +779,8 @@ struct bluestore_blob_t {
       !has_unused();
   }
   void prune_tail() {
+    const auto &p = extents.back();
+    logical_length -= p.length;
     extents.pop_back();
     if (has_csum()) {
       bufferptr t;
index a4901c689d3180cbcfa45cc658cce856c914406d..5a6533e736d55f30ddf4abe0c8b5e7017f99c156 100644 (file)
@@ -332,6 +332,7 @@ TEST(Blob, put_ref)
     b.dirty_blob().extents.push_back(
       bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET, 0x8000));
     b.dirty_blob().extents.push_back(bluestore_pextent_t(0x4071f000, 0x5000));
+    b.dirty_blob().logical_length = b.get_blob().get_ondisk_length();
     b.get_ref(&coll, 0, 0x1200);
     b.get_ref(&coll, 0xae00, 0x4200);
     ASSERT_EQ(0x5400u, b.get_referenced_bytes());
@@ -363,6 +364,7 @@ TEST(Blob, put_ref)
     bluestore_blob_t& b = B.dirty_blob();
     PExtentVector r;
     b.extents.push_back(bluestore_pextent_t(0, mas*2));
+    b.logical_length = b.get_ondisk_length();
     B.get_ref(coll.get(), 0, mas*2);
     ASSERT_EQ(mas * 2, B.get_referenced_bytes());
     ASSERT_TRUE(b.is_allocated(0, mas*2));
@@ -385,6 +387,7 @@ TEST(Blob, put_ref)
     bluestore_blob_t& b = B.dirty_blob();
     PExtentVector r;
     b.extents.push_back(bluestore_pextent_t(123, mas*2));
+    b.logical_length = b.get_ondisk_length();
     B.get_ref(coll.get(), 0, mas*2);
     ASSERT_EQ(mas * 2, B.get_referenced_bytes());
     B.put_ref(coll.get(), 0, mas, &r);
@@ -413,6 +416,7 @@ TEST(Blob, put_ref)
     b.extents.push_back(bluestore_pextent_t(2, mas));
     b.extents.push_back(bluestore_pextent_t(3, mas));
     b.extents.push_back(bluestore_pextent_t(4, mas));
+    b.logical_length = b.get_ondisk_length();
     B.get_ref(coll.get(), 0, mas*4);
     ASSERT_EQ(mas * 4, B.get_referenced_bytes());
     B.put_ref(coll.get(), mas, mas, &r);
@@ -454,6 +458,7 @@ TEST(Blob, put_ref)
     b.extents.push_back(bluestore_pextent_t(4, mas));
     b.extents.push_back(bluestore_pextent_t(5, mas));
     b.extents.push_back(bluestore_pextent_t(6, mas));
+    b.logical_length = b.get_ondisk_length();
     B.get_ref(coll.get(), 0, mas*6);
     ASSERT_EQ(mas * 6, B.get_referenced_bytes());
     B.put_ref(coll.get(), mas, mas, &r);
@@ -491,6 +496,7 @@ TEST(Blob, put_ref)
     bluestore_blob_t& b = B.dirty_blob();
     PExtentVector r;
     b.extents.push_back(bluestore_pextent_t(1, mas * 6));
+    b.logical_length = b.get_ondisk_length();
     B.get_ref(coll.get(), 0, mas*6);
     ASSERT_EQ(mas * 6, B.get_referenced_bytes());
     B.put_ref(coll.get(), mas, mas, &r);
@@ -526,6 +532,7 @@ TEST(Blob, put_ref)
     b.extents.push_back(bluestore_pextent_t(1, mas * 4));
     b.extents.push_back(bluestore_pextent_t(2, mas * 4));
     b.extents.push_back(bluestore_pextent_t(3, mas * 4));
+    b.logical_length = b.get_ondisk_length();
     B.get_ref(coll.get(), 0, mas*12);
     ASSERT_EQ(mas * 12, B.get_referenced_bytes());
     B.put_ref(coll.get(), mas, mas, &r);
@@ -565,6 +572,7 @@ TEST(Blob, put_ref)
     b.extents.push_back(bluestore_pextent_t(1, mas * 4));
     b.extents.push_back(bluestore_pextent_t(2, mas * 4));
     b.extents.push_back(bluestore_pextent_t(3, mas * 4));
+    b.logical_length = b.get_ondisk_length();
     B.get_ref(coll.get(), 0, mas*12);
     ASSERT_EQ(mas * 12, B.get_referenced_bytes());
     B.put_ref(coll.get(), mas, mas, &r);
@@ -621,6 +629,7 @@ TEST(Blob, put_ref)
     b.extents.push_back(bluestore_pextent_t(1, mas * 4));
     b.extents.push_back(bluestore_pextent_t(2, mas * 4));
     b.extents.push_back(bluestore_pextent_t(3, mas * 4));
+    b.logical_length = b.get_ondisk_length();
     B.get_ref(coll.get(), 0, mas*12);
     ASSERT_EQ(mas * 12, B.get_referenced_bytes());
     B.put_ref(coll.get(), mas, mas, &r);
@@ -675,6 +684,7 @@ TEST(Blob, put_ref)
     bluestore_blob_t& b = B.dirty_blob();
     PExtentVector r;
     b.extents.push_back(bluestore_pextent_t(1, mas * 8));
+    b.logical_length = b.get_ondisk_length();
     B.get_ref(coll.get(), 0, mas*8);
     ASSERT_EQ(mas * 8, B.get_referenced_bytes());
     B.put_ref(coll.get(), 0, mas, &r);
@@ -719,6 +729,7 @@ TEST(Blob, put_ref)
     bluestore_blob_t& b = B.dirty_blob();
     PExtentVector r;
     b.extents.push_back(bluestore_pextent_t(0, mas*4));
+    b.logical_length = b.get_ondisk_length();
     b.init_csum(Checksummer::CSUM_CRC32C, 14, mas * 4);
     B.get_ref(coll.get(), 0, mas*4);
     ASSERT_EQ(mas * 4, B.get_referenced_bytes());
@@ -740,7 +751,8 @@ TEST(Blob, put_ref)
     b.extents.push_back(bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET,
                                            0x13000));
     b.extents.push_back(bluestore_pextent_t(0x40118000, 0x7000));
-    B.get_ref(coll.get(), 0x0, 0x3800);
+    b.logical_length = b.get_ondisk_length();
+    B.get_ref(coll.get(0, 0x0, 0x3800);
     B.get_ref(coll.get(), 0x17c00, 0x6400);
     ASSERT_EQ(0x3800u + 0x6400u, B.get_referenced_bytes());
     b.set_flag(bluestore_blob_t::FLAG_SHARED);
@@ -760,7 +772,8 @@ TEST(Blob, put_ref)
     bluestore_blob_t& b = B.dirty_blob();
     b.extents.push_back(bluestore_pextent_t(1, 0x5000));
     b.extents.push_back(bluestore_pextent_t(2, 0x5000));
-    B.get_ref(coll.get(), 0x0, 0xa000);
+    b.logical_length = b.get_ondisk_length();
+    B.get_ref(coll.get(0, 0x0, 0xa000);
     ASSERT_EQ(0xa000u, B.get_referenced_bytes());
     cout << "before: " << B << std::endl;
     PExtentVector r;
@@ -779,6 +792,7 @@ TEST(Blob, put_ref)
     bluestore_blob_t& b = B.dirty_blob();
     b.extents.push_back(bluestore_pextent_t(1, 0x7000));
     b.extents.push_back(bluestore_pextent_t(2, 0x7000));
+    b.logical_length = b.get_ondisk_length();
     B.get_ref(coll.get(), 0x0, 0xe000);
     ASSERT_EQ(0xe000u, B.get_referenced_bytes());
     cout << "before: " << B << std::endl;
@@ -806,6 +820,7 @@ TEST(Blob, put_ref)
     bluestore_blob_t& b = B.dirty_blob();
     b.extents.push_back(bluestore_pextent_t(1, 0x5000));
     b.extents.push_back(bluestore_pextent_t(2, 0x7000));
+    b.logical_length = b.get_ondisk_length();
     B.get_ref(coll.get(), 0x0, 0xc000);
     ASSERT_EQ(0xc000u, B.get_referenced_bytes());
     cout << "before: " << B << std::endl;
@@ -861,6 +876,7 @@ TEST(bluestore_blob_t, prune_tail)
   ASSERT_FALSE(a.can_prune_tail());
   a.extents.emplace_back(
     bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET, 0x2000));
+  a.logical_length = 0x2000 * 3;
   ASSERT_TRUE(a.can_prune_tail());
   a.prune_tail();
   ASSERT_FALSE(a.can_prune_tail());
@@ -869,6 +885,7 @@ TEST(bluestore_blob_t, prune_tail)
 
   a.extents.emplace_back(
     bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET, 0x2000));
+  a.logical_length += 0x2000;
   a.init_csum(Checksummer::CSUM_CRC32C_8, 12, 0x6000);
   ASSERT_EQ(6u, a.csum_data.length());
   ASSERT_TRUE(a.can_prune_tail());
@@ -881,6 +898,7 @@ TEST(bluestore_blob_t, prune_tail)
   bluestore_blob_t b;
   b.extents.emplace_back(
     bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET, 0x2000));
+  a.logical_length += 0x2000;
   ASSERT_FALSE(a.can_prune_tail());
 }
 
@@ -897,6 +915,7 @@ TEST(Blob, split)
     R.shared_blob = new BlueStore::SharedBlob(coll.get());
     R.shared_blob->get();  // hack to avoid dtor from running
     L.dirty_blob().extents.emplace_back(bluestore_pextent_t(0x2000, 0x2000));
+    L.dirty_blob().logical_length = L.get_blob().get_ondisk_length();
     L.dirty_blob().init_csum(Checksummer::CSUM_CRC32C, 12, 0x2000);
     L.get_ref(coll.get(), 0, 0x2000);
     L.split(coll.get(), 0x1000, &R);
@@ -921,6 +940,7 @@ TEST(Blob, split)
     R.shared_blob->get();  // hack to avoid dtor from running
     L.dirty_blob().extents.emplace_back(bluestore_pextent_t(0x2000, 0x1000));
     L.dirty_blob().extents.emplace_back(bluestore_pextent_t(0x12000, 0x1000));
+    L.dirty_blob().logical_length = L.get_blob().get_ondisk_length();
     L.dirty_blob().init_csum(Checksummer::CSUM_CRC32C, 12, 0x2000);
     L.get_ref(coll.get(), 0, 0x1000);
     L.get_ref(coll.get(), 0x1000, 0x1000);
@@ -952,6 +972,7 @@ TEST(Blob, legacy_decode)
     B.shared_blob = new BlueStore::SharedBlob(coll.get());
     B.dirty_blob().extents.emplace_back(bluestore_pextent_t(0x1, 0x2000));
     B.dirty_blob().init_csum(Checksummer::CSUM_CRC32C, 12, 0x2000);
+    B.dirty_blob().logical_length = B.get_blob().get_ondisk_length();
     B.get_ref(coll.get(), 0, 0xff0);
     B.get_ref(coll.get(), 0x1fff, 1);
 
@@ -1258,12 +1279,15 @@ TEST(GarbageCollector, BasicTest)
     b3->shared_blob = new BlueStore::SharedBlob(coll.get());
     b4->shared_blob = new BlueStore::SharedBlob(coll.get());
     b1->dirty_blob().set_flag(bluestore_blob_t::FLAG_COMPRESSED);
-    b1->dirty_blob().compressed_length_orig = 0x2000;
+    b1->dirty_blob().logical_length = 0x2000;
     b1->dirty_blob().compressed_length = 0x1000;
     b1->dirty_blob().extents.emplace_back(0, 0x1000);
     b2->dirty_blob().extents.emplace_back(1, 0x1000);
+    b2->dirty_blob().logical_length = b2->get_blob().get_ondisk_length();
     b3->dirty_blob().extents.emplace_back(2, 0x1000);
+    b3->dirty_blob().logical_length = b3->get_blob().get_ondisk_length();
     b4->dirty_blob().extents.emplace_back(3, 0x1000);
+    b4->dirty_blob().logical_length = b4->get_blob().get_ondisk_length();
     em.extent_map.insert(*new BlueStore::Extent(100, 100, 10, b1));
     b1->get_ref(coll.get(), 100, 10);
     em.extent_map.insert(*new BlueStore::Extent(200, 200, 10, b2));
@@ -1324,10 +1348,13 @@ TEST(GarbageCollector, BasicTest)
     b1->dirty_blob().set_flag(bluestore_blob_t::FLAG_COMPRESSED);
     b1->dirty_blob().extents.emplace_back(0, 0x20000);
     b1->dirty_blob().compressed_length = 0x20000;
-    b1->dirty_blob().compressed_length_orig = 0x40000;
+    b1->dirty_blob().logical_length = 0x40000;
     b2->dirty_blob().extents.emplace_back(1, 0x10000);
+    b2->dirty_blob().logical_length = b2->get_blob().get_ondisk_length();
     b3->dirty_blob().extents.emplace_back(2, 0x20000);
+    b3->dirty_blob().logical_length = b3->get_blob().get_ondisk_length();
     b4->dirty_blob().extents.emplace_back(3, 0x10000);
+    b4->dirty_blob().logical_length = b4->get_blob().get_ondisk_length();
 
     em.extent_map.insert(*new BlueStore::Extent(0, 0, 0x8000, b1));
     b1->get_ref(coll.get(), 0, 0x8000);
@@ -1386,11 +1413,11 @@ TEST(GarbageCollector, BasicTest)
     b2->shared_blob = new BlueStore::SharedBlob(coll.get());
     b1->dirty_blob().set_flag(bluestore_blob_t::FLAG_COMPRESSED);
     b1->dirty_blob().extents.emplace_back(0, 0x2000);
-    b1->dirty_blob().compressed_length_orig = 0x4000;
+    b1->dirty_blob().logical_length = 0x4000;
     b1->dirty_blob().compressed_length = 0x2000;
     b2->dirty_blob().set_flag(bluestore_blob_t::FLAG_COMPRESSED);
     b2->dirty_blob().extents.emplace_back(0, 0x2000);
-    b2->dirty_blob().compressed_length_orig = 0x4000;
+    b2->dirty_blob().logical_length = 0x4000;
     b2->dirty_blob().compressed_length = 0x2000;
 
     em.extent_map.insert(*new BlueStore::Extent(0, 0, 0x3000, b1));
@@ -1451,15 +1478,18 @@ TEST(GarbageCollector, BasicTest)
     b4->shared_blob = new BlueStore::SharedBlob(coll.get());
     b0->dirty_blob().set_flag(bluestore_blob_t::FLAG_COMPRESSED);
     b0->dirty_blob().extents.emplace_back(0, 0x10000);
-    b0->dirty_blob().compressed_length_orig = 0x20000;
+    b0->dirty_blob().logical_length = 0x20000;
     b0->dirty_blob().compressed_length = 0x10000;
     b1->dirty_blob().set_flag(bluestore_blob_t::FLAG_COMPRESSED);
     b1->dirty_blob().extents.emplace_back(0, 0x10000);
-    b1->dirty_blob().compressed_length_orig = 0x20000;
+    b1->dirty_blob().logical_length = 0x20000;
     b1->dirty_blob().compressed_length = 0x10000;
     b2->dirty_blob().extents.emplace_back(1, 0x10000);
+    b2->dirty_blob().logical_length = b2->get_blob().get_ondisk_length();
     b3->dirty_blob().extents.emplace_back(2, 0x20000);
+    b3->dirty_blob().logical_length = b3->get_blob().get_ondisk_length();
     b4->dirty_blob().extents.emplace_back(3, 0x1000);
+    b4->dirty_blob().logical_length = b4->get_blob().get_ondisk_length();
 
     em.extent_map.insert(*new BlueStore::Extent(0, 0, 0x8000, b0));
     b0->get_ref(coll.get(), 0, 0x8000);