From f1e9aee716d182635e730bce777c3a43d8e1c000 Mon Sep 17 00:00:00 2001 From: Ramesh Chander Date: Sun, 18 Dec 2016 10:23:42 -0800 Subject: [PATCH] zone block offset bug fix and related unit test case Signed-off-by: Ramesh Chander zone block offset related test case Signed-off-by: Ramesh Chander --- src/os/bluestore/BitAllocator.cc | 29 +++++++++++----- src/test/objectstore/BitAllocator_test.cc | 40 ++++++++++++++++++++++- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/os/bluestore/BitAllocator.cc b/src/os/bluestore/BitAllocator.cc index 2dfe190275a..d2ed8102747 100644 --- a/src/os/bluestore/BitAllocator.cc +++ b/src/os/bluestore/BitAllocator.cc @@ -195,6 +195,7 @@ void BmapEntry::clear_bits(int offset, int num_bits) if (num_bits == 0) { return; } + bmap_t bmask = BmapEntry::align_mask(num_bits) >> offset; m_bits &= ~(bmask); } @@ -504,17 +505,25 @@ void BitMapZone::free_blocks_int(int64_t start_block, int64_t num_blocks) BmapEntry *bmap = NULL; int bit = 0; int64_t falling_in_bmap = 0; + int64_t count = num_blocks; + int64_t first_blk = start_block; + + if (num_blocks == 0) { + return; + } + alloc_dbg_assert(is_allocated(start_block, num_blocks)); - while (num_blocks) { - bit = start_block % BmapEntry::size(); - bmap = &(*m_bmap_list)[start_block / BmapEntry::size()]; - falling_in_bmap = MIN(num_blocks, BmapEntry::size() - bit); + while (count) { + bit = first_blk % BmapEntry::size(); + bmap = &(*m_bmap_list)[first_blk / BmapEntry::size()]; + falling_in_bmap = MIN(count, BmapEntry::size() - bit); bmap->clear_bits(bit, falling_in_bmap); - start_block += falling_in_bmap; - num_blocks -= falling_in_bmap; + first_blk += falling_in_bmap; + count -= falling_in_bmap; } + alloc_dbg_assert(!is_allocated(start_block, num_blocks)); } void BitMapZone::lock_excl() @@ -581,7 +590,9 @@ int64_t BitMapZone::alloc_blocks_dis(int64_t num_blocks, last_cont += alloc_cont; if (!alloc_cont) { - this->free_blocks_int(last_running_ext, last_cont); + if (last_cont) { + this->free_blocks_int(last_running_ext - zone_blk_off, last_cont); + } allocated -= last_cont; last_cont = 0; } else if (last_cont / min_alloc) { @@ -624,7 +635,9 @@ int64_t BitMapZone::alloc_blocks_dis(int64_t num_blocks, search_idx = 0; bmap_idx = iter.index(); if ((bmap = iter.next()) == NULL) { - this->free_blocks_int(last_running_ext, last_cont); + if (last_cont) { + this->free_blocks_int(last_running_ext - zone_blk_off, last_cont); + } allocated -= last_cont; break; } diff --git a/src/test/objectstore/BitAllocator_test.cc b/src/test/objectstore/BitAllocator_test.cc index d5ca99d6e8d..09460a153b6 100644 --- a/src/test/objectstore/BitAllocator_test.cc +++ b/src/test/objectstore/BitAllocator_test.cc @@ -335,14 +335,52 @@ TEST(BitAllocator, test_zone_alloc) delete zone; } } + + //allocation in loop + { + ExtentList *block_list = new ExtentList(&extents, blk_size); + zone = new BitMapZone(total_blocks, 0); + lock = zone->lock_excl_try(); + + for (int iter = 1; iter < 5; iter++) { + for (int i = 1; i <= total_blocks; i = i << 1) { + for (int j = 0; j < total_blocks; j +=i) { + bmap_test_assert(lock); + block_list->reset(); + int64_t need_blks = i; + allocated = zone->alloc_blocks_dis(need_blks, i, 0, 0, block_list); + bmap_test_assert(allocated == need_blks); + bmap_test_assert(extents[0].offset == (uint64_t) j); + block_list->reset(); + } + { + allocated = zone->alloc_blocks_dis(1, 1, 0, 0, block_list); + bmap_test_assert(allocated == 0); + block_list->reset(); + } + + for (int j = 0; j < total_blocks; j +=i) { + zone->free_blocks(j, i); + } + } + } + delete block_list; + delete zone; + } + { + ExtentList *block_list = new ExtentList(&extents, blk_size); zone = new BitMapZone(total_blocks, 0); lock = zone->lock_excl_try(); bmap_test_assert(lock); block_list->reset(); - allocated = zone->alloc_blocks_dis(total_blocks + 1, total_blocks + 1, 0, 0, block_list); + allocated = zone->alloc_blocks_dis(total_blocks + 1, total_blocks + 1, 0, 1024, block_list); + bmap_test_assert(allocated == 0); + + block_list->reset(); + allocated = zone->alloc_blocks_dis(total_blocks, total_blocks, 1, 1024, block_list); bmap_test_assert(allocated == 0); block_list->reset(); -- 2.39.5