From: Igor Fedotov Date: Tue, 17 Jan 2017 17:07:43 +0000 (+0000) Subject: os/bluestore: store blob logical length rather than recalculate it on pextent vector X-Git-Tag: v12.0.2~265^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4457aaa286c408aab3560d2d9843442887c28d60;p=ceph.git os/bluestore: store blob logical length rather than recalculate it on pextent vector Signed-off-by: Igor Fedotov --- diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index cee896ca6d28..fdf936fe8614 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -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 " diff --git a/src/os/bluestore/bluestore_types.cc b/src/os/bluestore/bluestore_types.cc index 7bd6021d692f..610df4e4d892 100644 --- a/src/os/bluestore/bluestore_types.cc +++ b/src/os/bluestore/bluestore_types.cc @@ -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& 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; diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h index 7e1550935a64..48c53c349658 100644 --- a/src/os/bluestore/bluestore_types.h +++ b/src/os/bluestore/bluestore_types.h @@ -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; diff --git a/src/test/objectstore/test_bluestore_types.cc b/src/test/objectstore/test_bluestore_types.cc index a4901c689d31..5a6533e736d5 100644 --- a/src/test/objectstore/test_bluestore_types.cc +++ b/src/test/objectstore/test_bluestore_types.cc @@ -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);