<< " 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)
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;
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);
} 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);
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;
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) {
{
__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--) {
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);
}
}
}
}
+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);