From 2942bc627a5bb8ce21b167eace5a0dab9dcbf304 Mon Sep 17 00:00:00 2001 From: Ramesh Chander Date: Thu, 15 Dec 2016 23:41:11 -0800 Subject: [PATCH] consolidate allocator calls to single alloc_extent api Signed-off-by: Ramesh Chander --- src/os/bluestore/Allocator.h | 10 +--- src/os/bluestore/BitMapAllocator.cc | 93 ++--------------------------- src/os/bluestore/BitMapAllocator.h | 9 +-- src/os/bluestore/BlueFS.cc | 28 ++++++--- src/os/bluestore/BlueStore.cc | 10 ++-- src/os/bluestore/StupidAllocator.cc | 9 ++- src/os/bluestore/StupidAllocator.h | 2 +- 7 files changed, 43 insertions(+), 118 deletions(-) diff --git a/src/os/bluestore/Allocator.h b/src/os/bluestore/Allocator.h index 13fe46b0eb1..d74822a0877 100644 --- a/src/os/bluestore/Allocator.h +++ b/src/os/bluestore/Allocator.h @@ -26,10 +26,6 @@ public: virtual int reserve(uint64_t need) = 0; virtual void unreserve(uint64_t unused) = 0; - virtual int allocate( - uint64_t need_size, uint64_t alloc_unit, int64_t hint, - uint64_t *offset, uint32_t *length) = 0; - /* * Allocate required number of blocks in n number of extents. * Min and Max number of extents are limited by: @@ -41,11 +37,11 @@ public: */ virtual int alloc_extents(uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size, int64_t hint, - AllocExtentVector *extents, int *count) = 0; + AllocExtentVector *extents, int *count, uint64_t *ret_len) = 0; int alloc_extents(uint64_t want_size, uint64_t alloc_unit, - int64_t hint, AllocExtentVector *extents, int *count) { - return alloc_extents(want_size, alloc_unit, want_size, hint, extents, count); + int64_t hint, AllocExtentVector *extents, int *count, uint64_t *ret_len) { + return alloc_extents(want_size, alloc_unit, want_size, hint, extents, count, ret_len); } virtual int release( diff --git a/src/os/bluestore/BitMapAllocator.cc b/src/os/bluestore/BitMapAllocator.cc index bb13475dfb1..169208b017c 100644 --- a/src/os/bluestore/BitMapAllocator.cc +++ b/src/os/bluestore/BitMapAllocator.cc @@ -105,48 +105,9 @@ void BitMapAllocator::unreserve(uint64_t unused) m_bit_alloc->unreserve_blocks(nblks); } -int BitMapAllocator::allocate( - uint64_t want_size, uint64_t alloc_unit, int64_t hint, - uint64_t *offset, uint32_t *length) -{ - if (want_size == 0) - return 0; - - assert(!(alloc_unit % m_block_size)); - int64_t nblks = (want_size + m_block_size - 1) / m_block_size; - - assert(alloc_unit); - - int64_t start_blk = 0; - int64_t count = 0; - - dout(10) << __func__ << " instance " << (uint64_t) this - << " want_size 0x" << std::hex << want_size - << " alloc_unit 0x" << alloc_unit - << " hint 0x" << hint << std::dec - << dendl; - - *offset = 0; - *length = 0; - - count = m_bit_alloc->alloc_blocks_res(nblks, hint / m_block_size, &start_blk); - if (count == 0) { - return -ENOSPC; - } - *offset = start_blk * m_block_size; - *length = count * m_block_size; - - dout(20) << __func__ <<" instance "<< (uint64_t) this - << " offset 0x" << std::hex << *offset - << " length 0x" << *length << std::dec - << dendl; - - return 0; -} - int BitMapAllocator::alloc_extents( uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size, - int64_t hint, mempool::bluestore_alloc::vector *extents, int *count) + int64_t hint, mempool::bluestore_alloc::vector *extents, int *count, uint64_t *ret_len) { assert(!(alloc_unit % m_block_size)); @@ -161,67 +122,25 @@ int BitMapAllocator::alloc_extents( << dendl; return alloc_extents_dis(want_size, alloc_unit / m_block_size, - max_alloc_size, hint / m_block_size, extents, count); -} - -/* - * Allocator extents with min alloc unit > bitmap block size. - */ -int BitMapAllocator::alloc_extents_cont( - uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size, int64_t hint, - mempool::bluestore_alloc::vector *extents, int *count) -{ - *count = 0; - assert(alloc_unit); - assert(!(alloc_unit % m_block_size)); - assert(!(want_size % alloc_unit)); - assert(!(max_alloc_size % m_block_size)); - - int64_t nblks = (want_size + m_block_size - 1) / m_block_size; - int64_t start_blk = 0; - int64_t need_blks = nblks; - int64_t cont_blks = alloc_unit / m_block_size; - - ExtentList block_list = ExtentList(extents, m_block_size, max_alloc_size); - - while (need_blks > 0) { - int64_t count = 0; - count = m_bit_alloc->alloc_blocks_res(cont_blks, hint, &start_blk); - if (count == 0) { - break; - } - assert(cont_blks == count); - dout(30) << __func__ <<" instance "<< (uint64_t) this - << " offset " << start_blk << " length " << count << dendl; - need_blks -= count; - block_list.add_extents(start_blk, count); - hint = start_blk + count; - } - - if (need_blks > 0) { - m_bit_alloc->free_blocks_dis(nblks - need_blks, &block_list); - return -ENOSPC; - } - *count = block_list.get_extent_count(); - - return 0; + max_alloc_size, hint / m_block_size, extents, count, ret_len); } int BitMapAllocator::alloc_extents_dis( uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size, - int64_t hint, mempool::bluestore_alloc::vector *extents, int *count) + int64_t hint, mempool::bluestore_alloc::vector *extents, int *count, uint64_t *ret_len) { ExtentList block_list = ExtentList(extents, m_block_size, max_alloc_size); int64_t nblks = (want_size + m_block_size - 1) / m_block_size; int64_t num = 0; *count = 0; + *ret_len = 0; num = m_bit_alloc->alloc_blocks_dis_res(nblks, alloc_unit, hint, &block_list); - if (num < nblks) { - m_bit_alloc->free_blocks_dis(num, &block_list); + if (num == 0) { return -ENOSPC; } *count = block_list.get_extent_count(); + *ret_len = num * m_block_size; return 0; } diff --git a/src/os/bluestore/BitMapAllocator.h b/src/os/bluestore/BitMapAllocator.h index f885b73ca0a..3214b2fa735 100644 --- a/src/os/bluestore/BitMapAllocator.h +++ b/src/os/bluestore/BitMapAllocator.h @@ -19,12 +19,11 @@ class BitMapAllocator : public Allocator { BitAllocator *m_bit_alloc; // Bit allocator instance void insert_free(uint64_t offset, uint64_t len); - int alloc_extents_cont(uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size, int64_t hint, mempool::bluestore_alloc::vector *extents, int *count); int alloc_extents_dis(uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size, - int64_t hint, mempool::bluestore_alloc::vector *extents, int *count); + int64_t hint, mempool::bluestore_alloc::vector *extents, int *count, uint64_t *ret_len); public: BitMapAllocator(); @@ -34,13 +33,9 @@ public: int reserve(uint64_t need); void unreserve(uint64_t unused); - int allocate( - uint64_t want_size, uint64_t alloc_unit, int64_t hint, - uint64_t *offset, uint32_t *length); - int alloc_extents( uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size, - int64_t hint, mempool::bluestore_alloc::vector *extents, int *count); + int64_t hint, mempool::bluestore_alloc::vector *extents, int *count, uint64_t *ret_len); int release( uint64_t offset, uint64_t length); diff --git a/src/os/bluestore/BlueFS.cc b/src/os/bluestore/BlueFS.cc index 10cad5d8f68..6a8120b498a 100644 --- a/src/os/bluestore/BlueFS.cc +++ b/src/os/bluestore/BlueFS.cc @@ -177,16 +177,24 @@ int BlueFS::reclaim_blocks(unsigned id, uint64_t want, assert(alloc[id]); int r = alloc[id]->reserve(want); assert(r == 0); // caller shouldn't ask for more than they can get + int count = 0; + uint64_t alloc_len = 0;; + AllocExtentVector extents = AllocExtentVector(want / g_conf->bluefs_alloc_size); + + r = alloc[id]->alloc_extents(want, g_conf->bluefs_alloc_size, 0, + &extents, &count, &alloc_len); - r = alloc[id]->allocate(want, g_conf->bluefs_alloc_size, 0, - offset, length); + *length = alloc_len; assert(r >= 0); - if (*length < want) + if (*length < want) alloc[id]->unreserve(want - *length); - block_all[id].erase(*offset, *length); - block_total[id] -= *length; - log_t.op_alloc_rm(id, *offset, *length); + for (int i = 0; i < count; i++) { + block_all[id].erase(extents[i].offset, extents[i].length); + block_total[id] -= extents[i].length; + log_t.op_alloc_rm(id, extents[i].offset, extents[i].length); + } + r = _flush_and_sync_log(l); assert(r == 0); @@ -1761,17 +1769,19 @@ int BlueFS::_allocate(uint8_t id, uint64_t len, } int count = 0; + uint64_t alloc_len = 0; AllocExtentVector extents = AllocExtentVector(left / min_alloc_size); - r = alloc[id]->alloc_extents(left, min_alloc_size, - hint, &extents, &count); - if (r < 0) { + r = alloc[id]->alloc_extents(left, min_alloc_size, hint, + &extents, &count, &alloc_len); + if (r < 0 || alloc_len < left) { derr << __func__ << " allocate failed on 0x" << std::hex << left << " min_alloc_size 0x" << min_alloc_size << std::dec << dendl; alloc[id]->dump(); assert(0 == "allocate failed... wtf"); return r; } + for (int i = 0; i < count; i++) { bluefs_extent_t e = bluefs_extent_t(id, extents[i].offset, extents[i].length); if (!ev->empty() && diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index fbe6d246da0..f8b0761869e 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -3593,10 +3593,11 @@ int BlueStore::_balance_bluefs_freespace(vector *extents) assert(r == 0); int count = 0; + uint64_t alloc_len = 0; AllocExtentVector exts = AllocExtentVector(gift / min_alloc_size); - r = alloc->alloc_extents(gift, g_conf->bluefs_alloc_size, 0, 0, &exts, &count); + r = alloc->alloc_extents(gift, g_conf->bluefs_alloc_size, 0, 0, &exts, &count, &alloc_len); - if (r < 0) { + if (r < 0 || alloc_len < gift) { derr << __func__ << " allocate failed on 0x" << std::hex << gift << " min_alloc_size 0x" << min_alloc_size << std::dec << dendl; alloc->dump(); @@ -7832,11 +7833,12 @@ int BlueStore::_do_alloc_write( } int count = 0; + uint64_t alloc_len = 0; AllocExtentVector extents = AllocExtentVector(final_length / min_alloc_size); int r = alloc->alloc_extents(final_length, min_alloc_size, max_alloc_size, - hint, &extents, &count); - assert(r == 0); + hint, &extents, &count, &alloc_len); + assert(r == 0 && alloc_len == final_length); need -= final_length; txc->statfs_delta.allocated() += final_length; assert(count > 0); diff --git a/src/os/bluestore/StupidAllocator.cc b/src/os/bluestore/StupidAllocator.cc index 64ab67c120b..33bcd062667 100644 --- a/src/os/bluestore/StupidAllocator.cc +++ b/src/os/bluestore/StupidAllocator.cc @@ -206,7 +206,8 @@ int StupidAllocator::alloc_extents( uint64_t max_alloc_size, int64_t hint, mempool::bluestore_alloc::vector *extents, - int *count) + int *count, + uint64_t *ret_len) { uint64_t allocated_size = 0; uint64_t offset = 0; @@ -216,6 +217,8 @@ int StupidAllocator::alloc_extents( if (max_alloc_size == 0) { max_alloc_size = want_size; } + *count = 0; + *ret_len = 0; ExtentList block_list = ExtentList(extents, 1, max_alloc_size); @@ -234,8 +237,8 @@ int StupidAllocator::alloc_extents( } *count = block_list.get_extent_count(); - if (want_size - allocated_size > 0) { - release_extents(extents, *count); + *ret_len = allocated_size; + if (allocated_size == 0) { return -ENOSPC; } diff --git a/src/os/bluestore/StupidAllocator.h b/src/os/bluestore/StupidAllocator.h index cb694cb182c..9aeab7b5111 100644 --- a/src/os/bluestore/StupidAllocator.h +++ b/src/os/bluestore/StupidAllocator.h @@ -32,7 +32,7 @@ public: int alloc_extents( uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size, - int64_t hint, mempool::bluestore_alloc::vector *extents, int *count); + int64_t hint, mempool::bluestore_alloc::vector *extents, int *count, uint64_t *ret_len); int allocate( uint64_t want_size, uint64_t alloc_unit, int64_t hint, -- 2.39.5