Skip to content

Commit

Permalink
os/bluestore: migrate to refcounting for Blob class instances
Browse files Browse the repository at this point in the history
Signed-off-by: Igor Fedotov <ifedotov@mirantis.com>
  • Loading branch information
Igor Fedotov committed Jul 28, 2016
1 parent dffbab2 commit 6d6d940
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 42 deletions.
48 changes: 21 additions & 27 deletions src/os/bluestore/BlueStore.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,7 @@ void BlueStore::BlobMap::decode(bufferlist::iterator& p, Cache *c)
::decode(id, p);
Blob *b = new Blob(id, c);
::decode(b->blob, p);
b->get();
blob_map.insert(*b);
}
}
Expand Down Expand Up @@ -3515,8 +3516,13 @@ struct region_t {
<< r.blob_xoffset << "~" << r.length << std::dec;
}
};

bool less(const BlueStore::BlobRef& a, const BlueStore::BlobRef& b)
{
return *a < *b;
}
typedef list<region_t> regions2read_t;
typedef map<Blob*, regions2read_t> blobs2read_t;
typedef map<BlueStore::BlobRef, regions2read_t> blobs2read_t;

int BlueStore::_do_read(
Collection *c,
Expand Down Expand Up @@ -3576,7 +3582,7 @@ int BlueStore::_do_read(
pos += hole;
left -= hole;
}
Blob *bptr = c->get_blob(o, lp->second.blob);
BlobRef bptr = c->get_blob(o, lp->second.blob);
if (bptr == nullptr) {
dout(20) << __func__ << " missed blob " << lp->second.blob << dendl;
assert(bptr != nullptr);
Expand Down Expand Up @@ -3624,7 +3630,7 @@ int BlueStore::_do_read(
//enumerate and read/decompress desired blobs
blobs2read_t::iterator b2r_it = blobs2read.begin();
while (b2r_it != blobs2read.end()) {
Blob* bptr = b2r_it->first;
BlobRef bptr = b2r_it->first;
dout(20) << __func__ << " blob " << *bptr << std::hex
<< " need 0x" << b2r_it->second << std::dec << dendl;
if (bptr->blob.has_flag(bluestore_blob_t::FLAG_COMPRESSED)) {
Expand Down Expand Up @@ -5213,7 +5219,7 @@ int BlueStore::queue_transactions(

// delayed csum calculation?
for (auto& d : txc->deferred_csum) {
Blob *b = d.onode->get_blob(d.blob);
BlobRef b = d.onode->get_blob(d.blob);
dout(20) << __func__ << " deferred csum calc blob " << d.blob
<< " b_off 0x" << std::hex << d.b_off << std::dec
<< " on " << d.onode->oid << dendl;
Expand Down Expand Up @@ -5777,7 +5783,7 @@ void BlueStore::_do_write_small(
blp.copy(length, bl);

// look for an existing mutable blob we can use
Blob *b = 0;
BlobRef b = 0;
map<uint64_t,bluestore_lextent_t>::iterator ep = o->onode.seek_lextent(offset);
if (ep != o->onode.extent_map.begin()) {
--ep;
Expand Down Expand Up @@ -5977,7 +5983,7 @@ void BlueStore::_do_write_big(
<< " compress " << (int)wctx->compress
<< std::dec << dendl;
while (length > 0) {
Blob *b = o->blob_map.new_blob(c->cache);
BlobRef b = o->blob_map.new_blob(c->cache);
auto l = MIN(max_blob_len, length);
bufferlist t;
blp.copy(l, t);
Expand Down Expand Up @@ -6015,7 +6021,7 @@ int BlueStore::_do_alloc_write(

uint64_t hint = 0;
for (auto& wi : wctx->writes) {
Blob *b = wi.b;
BlobRef b = wi.b;
uint64_t b_off = wi.b_off;
bufferlist *l = &wi.bl;
uint64_t final_length = wi.blob_length;
Expand Down Expand Up @@ -6138,10 +6144,10 @@ void BlueStore::_wctx_finish(
WriteContext *wctx)
{
dout(10) << __func__ << " lex_old " << wctx->lex_old << dendl;
set<pair<bool, Blob*> > blobs2remove;
set<pair<bool, BlobRef> > blobs2remove;
for (auto &lo : wctx->lex_old) {
bluestore_lextent_t& l = lo.second;
Blob *b = c->get_blob(o, l.blob);
BlobRef b = c->get_blob(o, l.blob);
vector<bluestore_pextent_t> r;
bool compressed = b->blob.is_compressed();
if (o->onode.deref_lextent(lo.first, l, &b->blob, min_alloc_size, &r)) {
Expand All @@ -6166,29 +6172,17 @@ void BlueStore::_wctx_finish(
txc->statfs_delta.compressed_allocated() -= e.length;
}
}
if (b->blob.ref_map.empty()) {
dout(20) << __func__ << " rm blob " << *b << dendl;
txc->statfs_delta.compressed() -= b->blob.get_compressed_payload_length();
if (l.blob >= 0) {
o->blob_map.erase(b, true);
} else {
o->bnode->blob_map.erase(b, true);
}
} else {
dout(20) << __func__ << " keep blob " << *b << dendl;
}
if (l.blob < 0) {
txc->write_bnode(o->bnode);
}
}
for (auto br : blobs2remove) {
Blob* b = br.second;
dout(20) << __func__ << " rm blob " << *b << dendl;
txc->statfs_delta.compressed() -= b->blob.get_compressed_payload_length();
dout(20) << __func__ << " rm blob " << *br.second << dendl;
txc->statfs_delta.compressed() -= br.second->blob.get_compressed_payload_length();
if (br.first) {
o->blob_map.erase(b);
o->blob_map.erase(br.second);
} else {
o->bnode->blob_map.erase(b);
o->bnode->blob_map.erase(br.second);
}
}

Expand Down Expand Up @@ -6734,10 +6728,10 @@ int BlueStore::_clone(TransContext *txc,
map<int64_t,int64_t> moved_blobs;
for (auto& p : oldo->onode.extent_map) {
if (!p.second.is_shared()) {
Blob *b;
BlobRef b;
if (moved_blobs.count(p.second.blob) == 0) {
b = oldo->blob_map.get(p.second.blob);
oldo->blob_map.erase(b, false);
oldo->blob_map.erase(b);
newo->bnode->blob_map.claim(b);
moved_blobs[p.second.blob] = b->id;
dout(30) << __func__ << " moving old onode blob " << p.second.blob
Expand Down
42 changes: 27 additions & 15 deletions src/os/bluestore/BlueStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ class BlueStore : public ObjectStore,
void _set_compression();

class TransContext;
class Blob;

typedef map<uint64_t, bufferlist> ready_regions_t;

Expand Down Expand Up @@ -278,15 +277,19 @@ class BlueStore : public ObjectStore,

/// in-memory blob metadata and associated cached buffers (if any)
struct Blob : public boost::intrusive::set_base_hook<> {
std::atomic_int nref; ///< reference count
int64_t id = 0; ///< id
bluestore_blob_t blob; ///< blob metadata
BufferSpace bc; ///< buffer cache

Blob(int64_t i, Cache *c) : id(i), bc(c) {}
Blob(int64_t i, Cache *c) : nref(0), id(i), bc(c) {}
~Blob() {
assert(bc.empty());
}

friend void intrusive_ptr_add_ref(Blob *b) { b->get(); }
friend void intrusive_ptr_release(Blob *b) { b->put(); }

// comparators for intrusive_set
friend bool operator<(const Blob &a, const Blob &b) {
return a.id < b.id;
Expand All @@ -304,7 +307,16 @@ class BlueStore : public ObjectStore,

/// discard buffers for unallocated regions
void discard_unallocated();

void get() {
++nref;
}
void put() {
if (--nref == 0)
delete this;
}
};
typedef boost::intrusive_ptr<Blob> BlobRef;

/// a map of blobs, indexed by int64_t
struct BlobMap {
Expand All @@ -319,7 +331,7 @@ class BlueStore : public ObjectStore,
return blob_map.empty();
}

Blob *get(int64_t id) {
BlobRef get(int64_t id) {
Blob dummy(id, nullptr);
auto p = blob_map.find(dummy);
if (p != blob_map.end()) {
Expand All @@ -328,25 +340,25 @@ class BlueStore : public ObjectStore,
return nullptr;
}

Blob *new_blob(Cache *c) {
BlobRef new_blob(Cache *c) {
int64_t id = get_new_id();
Blob *b = new Blob(id, c);
b->get();
blob_map.insert(*b);
return b;
}

void claim(Blob *b) {
void claim(BlobRef b) {
assert(b->id == 0);
b->id = get_new_id();
b->get();
blob_map.insert(*b);
}

void erase(Blob *b, bool release) {
void erase(BlobRef b) {
blob_map.erase(*b);
b->id = 0;
if (release) {
delete b;
}
b->put();
}

int64_t get_new_id() {
Expand All @@ -358,7 +370,7 @@ class BlueStore : public ObjectStore,
while (!blob_map.empty()) {
Blob *b = &*blob_map.begin();
b->bc._clear();
erase(b, true);
erase(b);
}
}

Expand Down Expand Up @@ -476,7 +488,7 @@ class BlueStore : public ObjectStore,
exists(false) {
}

Blob *get_blob(int64_t id) {
BlobRef get_blob(int64_t id) {
if (id < 0) {
assert(bnode);
return bnode->blob_map.get(-id);
Expand Down Expand Up @@ -704,7 +716,7 @@ class BlueStore : public ObjectStore,
OnodeRef get_onode(const ghobject_t& oid, bool create);
BnodeRef get_bnode(uint32_t hash);

Blob *get_blob(OnodeRef& o, int64_t blob) {
BlobRef get_blob(OnodeRef& o, int64_t blob) {
if (blob < 0) {
if (!o->bnode) {
o->bnode = get_bnode(o->oid.hobj.get_hash());
Expand Down Expand Up @@ -1485,18 +1497,18 @@ class BlueStore : public ObjectStore,
vector<std::pair<uint64_t, bluestore_lextent_t> > lex_old; ///< must deref blobs

struct write_item {
Blob *b;
BlobRef b;
uint64_t blob_length;
uint64_t b_off;
bufferlist bl;
bool mark_unused;

write_item(Blob *b, uint64_t blob_len, uint64_t o, bufferlist& bl, bool _mark_unused)
write_item(BlobRef b, uint64_t blob_len, uint64_t o, bufferlist& bl, bool _mark_unused)
: b(b), blob_length(blob_len), b_off(o), bl(bl), mark_unused(_mark_unused) {}
};
vector<write_item> writes; ///< blobs we're writing

void write(Blob *b, uint64_t blob_len, uint64_t o, bufferlist& bl, bool _mark_unused) {
void write(BlobRef b, uint64_t blob_len, uint64_t o, bufferlist& bl, bool _mark_unused) {
writes.emplace_back(write_item(b, blob_len, o, bl, _mark_unused));
}
};
Expand Down

0 comments on commit 6d6d940

Please sign in to comment.