void BlueStore::Onode::get() {
if (++nref >= 2 && !pinned) {
OnodeCacheShard* ocs = c->get_onode_cache();
- std::lock_guard l(ocs->lock);
+ ocs->lock.lock();
+ // It is possible that during waiting split_cache moved us to different OnodeCacheShard.
+ while (ocs != c->get_onode_cache()) {
+ ocs->lock.unlock();
+ ocs = c->get_onode_cache();
+ ocs->lock.lock();
+ }
bool was_pinned = pinned;
pinned = nref >= 2;
// additional increment for newly pinned instance
if (cached && r) {
ocs->_pin(this);
}
+ ocs->lock.unlock();
}
}
void BlueStore::Onode::put() {
int n = --nref;
if (n == 2) {
OnodeCacheShard* ocs = c->get_onode_cache();
- std::lock_guard l(ocs->lock);
+ ocs->lock.lock();
+ // It is possible that during waiting split_cache moved us to different OnodeCacheShard.
+ while (ocs != c->get_onode_cache()) {
+ ocs->lock.unlock();
+ ocs = c->get_onode_cache();
+ ocs->lock.lock();
+ }
bool need_unpin = pinned;
pinned = pinned && nref > 2; // intentionally use > not >= as we have
// +1 due to pinned state
if (need_unpin) {
n = --nref;
}
+ ocs->lock.unlock();
}
if (n == 0) {
delete this;