Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os/bluestore/BitAllocator: fix bug of checking required blocks #13470

Merged
merged 2 commits into from Feb 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 26 additions & 5 deletions src/os/bluestore/BitAllocator.cc
Expand Up @@ -782,7 +782,7 @@ void BitMapAreaIN::shutdown()
unlock();
}

bool BitMapAreaIN::child_check_n_lock(BitMapArea *child)
bool BitMapAreaIN::child_check_n_lock(BitMapArea *child, int64_t required)
{
child->lock_shared();

Expand All @@ -791,6 +791,13 @@ bool BitMapAreaIN::child_check_n_lock(BitMapArea *child)
return false;
}

int64_t child_used_blocks = child->get_used_blocks();
int64_t child_total_blocks = child->size();
if ((child_total_blocks - child_used_blocks) < required) {
child->unlock();
return false;
}

return true;
}

Expand Down Expand Up @@ -900,7 +907,7 @@ int64_t BitMapAreaIN::alloc_blocks_dis_int_work(bool wrap, int64_t num_blocks, i
m_child_list, hint / m_child_size_blocks, wrap);

while ((child = (BitMapArea *) iter.next())) {
if (!child_check_n_lock(child)) {
if (!child_check_n_lock(child, 1)) {
hint = 0;
continue;
}
Expand Down Expand Up @@ -1089,7 +1096,7 @@ BitMapAreaLeaf::~BitMapAreaLeaf()
unlock();
}

bool BitMapAreaLeaf::child_check_n_lock(BitMapArea *child, bool lock)
bool BitMapAreaLeaf::child_check_n_lock(BitMapArea *child, int64_t required, bool lock)
{
if (lock) {
child->lock_excl();
Expand All @@ -1101,6 +1108,14 @@ bool BitMapAreaLeaf::child_check_n_lock(BitMapArea *child, bool lock)
child->unlock();
return false;
}

int64_t child_used_blocks = child->get_used_blocks();
int64_t child_total_blocks = child->size();
if ((child_total_blocks - child_used_blocks) < required) {
child->unlock();
return false;
}

return true;
}

Expand All @@ -1120,7 +1135,7 @@ int64_t BitMapAreaLeaf::alloc_blocks_dis_int(int64_t num_blocks, int64_t min_all
m_child_list, hint / m_child_size_blocks, false);

while ((child = (BitMapArea *) iter.next())) {
if (!child_check_n_lock(child, false)) {
if (!child_check_n_lock(child, 1, false)) {
hint = 0;
continue;
}
Expand Down Expand Up @@ -1329,7 +1344,7 @@ bool BitAllocator::try_serial_lock()
return get_lock;
}

bool BitAllocator::child_check_n_lock(BitMapArea *child)
bool BitAllocator::child_check_n_lock(BitMapArea *child, int64_t required)
{
child->lock_shared();

Expand All @@ -1338,6 +1353,12 @@ bool BitAllocator::child_check_n_lock(BitMapArea *child)
return false;
}

int64_t child_used_blocks = child->get_used_blocks();
int64_t child_total_blocks = child->size();
if ((child_total_blocks - child_used_blocks) < required) {
child->unlock();
return false;
}

return true;
}
Expand Down
14 changes: 7 additions & 7 deletions src/os/bluestore/BitAllocator.h
Expand Up @@ -209,11 +209,11 @@ class BitMapArea {
static int64_t get_level_factor(CephContext* cct, int level);
virtual bool is_allocated(int64_t start_block, int64_t num_blocks) = 0;
virtual bool is_exhausted() = 0;
virtual bool child_check_n_lock(BitMapArea *child) {
virtual bool child_check_n_lock(BitMapArea *child, int64_t required) {
ceph_abort();
return true;
}
virtual bool child_check_n_lock(BitMapArea *child, bool lock) {
virtual bool child_check_n_lock(BitMapArea *child, int64_t required, bool lock) {
ceph_abort();
return true;
}
Expand Down Expand Up @@ -375,12 +375,12 @@ class BitMapAreaIN: public BitMapArea{
virtual bool is_allocated(int64_t start_block, int64_t num_blocks);
virtual bool is_exhausted();

bool child_check_n_lock(BitMapArea *child, bool lock) {
bool child_check_n_lock(BitMapArea *child, int64_t required, bool lock) {
ceph_abort();
return false;
}

virtual bool child_check_n_lock(BitMapArea *child);
virtual bool child_check_n_lock(BitMapArea *child, int64_t required);
virtual void child_unlock(BitMapArea *child);

virtual void lock_excl() {
Expand Down Expand Up @@ -449,12 +449,12 @@ class BitMapAreaLeaf: public BitMapAreaIN{
BitMapAreaLeaf(CephContext* cct, int64_t zone_num, int64_t total_blocks,
bool def);

bool child_check_n_lock(BitMapArea *child) {
bool child_check_n_lock(BitMapArea *child, int64_t required) {
ceph_abort();
return false;
}

bool child_check_n_lock(BitMapArea *child, bool lock);
bool child_check_n_lock(BitMapArea *child, int64_t required, bool lock);
void child_unlock(BitMapArea *child);

int64_t alloc_blocks_int(int64_t num_blocks, int64_t hint, int64_t *start_block);
Expand Down Expand Up @@ -485,7 +485,7 @@ class BitAllocator:public BitMapAreaIN{
}

using BitMapArea::child_check_n_lock;
bool child_check_n_lock(BitMapArea *child);
bool child_check_n_lock(BitMapArea *child, int64_t required);
virtual void child_unlock(BitMapArea *child);

void serial_lock();
Expand Down