denc_varint(0, bound); // logical_offset
denc_varint(0, bound); // len
denc_varint(0, bound); // blob_offset
- p->blob->bound_encode(bound, struct_v, false);
+ p->blob->bound_encode(bound, struct_v, p->blob->shared_blob->sbid, false);
}
{
}
pos = p->logical_end();
if (include_blob) {
- p->blob->encode(app, struct_v, false);
+ p->blob->encode(app, struct_v, p->blob->shared_blob->sbid, false);
}
}
}
assert(le->blob);
} else {
Blob *b = new Blob();
- b->decode(p, struct_v, false);
+ uint64_t sbid = 0;
+ b->decode(p, struct_v, &sbid, false);
blobs[n] = b;
- onode->c->open_shared_blob(b);
+ onode->c->open_shared_blob(sbid, b);
le->assign_blob(b);
}
// we build ref_map dynamically for non-spanning blobs
denc_varint((uint32_t)0, key_size);
p += spanning_blob_map.size() * key_size;
for (const auto& i : spanning_blob_map) {
- i.second->bound_encode(p, struct_v, true);
+ i.second->bound_encode(p, struct_v, i.second->shared_blob->sbid, true);
}
}
denc_varint(spanning_blob_map.size(), p);
for (auto& i : spanning_blob_map) {
denc_varint(i.second->id, p);
- i.second->encode(p, struct_v, true);
+ i.second->encode(p, struct_v, i.second->shared_blob->sbid, true);
}
}
BlobRef b(new Blob());
denc_varint(b->id, p);
spanning_blob_map[b->id] = b;
- b->decode(p, struct_v, true);
- c->open_shared_blob(b);
+ uint64_t sbid = 0;
+ b->decode(p, struct_v, &sbid, true);
+ c->open_shared_blob(sbid, b);
}
}
{
}
-void BlueStore::Collection::open_shared_blob(BlobRef b)
+void BlueStore::Collection::open_shared_blob(uint64_t sbid, BlobRef b)
{
assert(!b->shared_blob);
const bluestore_blob_t& blob = b->get_blob();
return;
}
- b->shared_blob = shared_blob_set.lookup(blob.sbid);
+ b->shared_blob = shared_blob_set.lookup(sbid);
if (b->shared_blob) {
- dout(10) << __func__ << " sbid 0x" << std::hex << blob.sbid << std::dec
+ dout(10) << __func__ << " sbid 0x" << std::hex << sbid << std::dec
<< " had " << *b->shared_blob << dendl;
} else {
- b->shared_blob = new SharedBlob(blob.sbid, cache);
+ b->shared_blob = new SharedBlob(sbid, cache);
shared_blob_set.add(b->shared_blob.get());
- dout(10) << __func__ << " sbid 0x" << std::hex << blob.sbid << std::dec
+ dout(10) << __func__ << " sbid 0x" << std::hex << sbid << std::dec
<< " opened " << *b->shared_blob << dendl;
}
}
sb->loaded = true;
}
-void BlueStore::Collection::make_blob_shared(BlobRef b)
+void BlueStore::Collection::make_blob_shared(uint64_t sbid, BlobRef b)
{
dout(10) << __func__ << " " << *b << dendl;
bluestore_blob_t& blob = b->dirty_blob();
// update shared blob
b->shared_blob->loaded = true; // we are new and therefore up to date
- b->shared_blob->sbid = blob.sbid;
+ b->shared_blob->sbid = sbid;
shared_blob_set.add(b->shared_blob.get());
for (auto p : blob.extents) {
if (p.is_valid()) {
}
}
if (blob.is_shared()) {
- if (blob.sbid > blobid_max) {
+ if (i.first->shared_blob->sbid > blobid_max) {
derr << __func__ << " " << oid << " blob " << blob
- << " sbid " << blob.sbid << " > blobid_max "
+ << " sbid " << i.first->shared_blob->sbid << " > blobid_max "
<< blobid_max << dendl;
++errors;
- } else if (blob.sbid == 0) {
+ } else if (i.first->shared_blob->sbid == 0) {
derr << __func__ << " " << oid << " blob " << blob
<< " marked as shared but has uninitialized sbid"
<< dendl;
++errors;
}
- sb_info_t& sbi = sb_info[blob.sbid];
+ sb_info_t& sbi = sb_info[i.first->shared_blob->sbid];
sbi.sb = i.first->shared_blob;
sbi.oids.push_back(oid);
sbi.compressed = blob.is_compressed();
const bluestore_blob_t& blob = e.blob->get_blob();
// make sure it is shared
if (!blob.is_shared()) {
- e.blob->dirty_blob().sbid = _assign_blobid(txc);
- c->make_blob_shared(e.blob);
+ c->make_blob_shared(_assign_blobid(txc), e.blob);
dirtied_oldo = true; // fixme: overkill
} else if (!e.blob->shared_blob->loaded) {
c->load_shared_blob(e.blob->shared_blob);
}
}
#else
- void bound_encode(size_t& p, uint64_t struct_v, bool include_ref_map) const {
+ void bound_encode(size_t& p, uint64_t struct_v, uint64_t sbid, bool include_ref_map) const {
denc(blob, p, struct_v);
+ if (blob.is_shared()) {
+ denc(sbid, p);
+ }
if (include_ref_map) {
ref_map.bound_encode(p);
}
}
- void encode(bufferlist::contiguous_appender& p, uint64_t struct_v,
+ void encode(bufferlist::contiguous_appender& p, uint64_t struct_v, uint64_t sbid,
bool include_ref_map) const {
denc(blob, p, struct_v);
+ if (blob.is_shared()) {
+ denc(sbid, p);
+ }
if (include_ref_map) {
ref_map.encode(p);
}
}
- void decode(bufferptr::iterator& p, uint64_t struct_v,
+ void decode(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) {
ref_map.decode(p);
}
// open = SharedBlob is instantiated
// shared = blob_t shared flag is set; SharedBlob is hashed.
// loaded = SharedBlob::shared_blob_t is loaded from kv store
- void open_shared_blob(BlobRef b);
+ void open_shared_blob(uint64_t sbid, BlobRef b);
void load_shared_blob(SharedBlobRef sb);
- void make_blob_shared(BlobRef b);
+ void make_blob_shared(uint64_t sbid, BlobRef b);
BlobRef new_blob() {
BlobRef b = new Blob;