From cccf94da463aa15370fe674bda24d168d331ceca Mon Sep 17 00:00:00 2001 From: Igor Fedotov Date: Fri, 14 Feb 2020 00:57:29 +0300 Subject: [PATCH] os/bluestore: extend AvlAllocator interface. Signed-off-by: Igor Fedotov --- src/os/bluestore/AvlAllocator.cc | 88 +++++++++++++++++++++++++------- src/os/bluestore/AvlAllocator.h | 15 ++++++ 2 files changed, 85 insertions(+), 18 deletions(-) diff --git a/src/os/bluestore/AvlAllocator.cc b/src/os/bluestore/AvlAllocator.cc index c6f63fe35bf5d..d4158a20d81ad 100644 --- a/src/os/bluestore/AvlAllocator.cc +++ b/src/os/bluestore/AvlAllocator.cc @@ -57,7 +57,7 @@ uint64_t AvlAllocator::_block_picker(const Tree& t, void AvlAllocator::_add_to_tree(uint64_t start, uint64_t size) { - assert(size != 0); + ceph_assert(size != 0); uint64_t end = start + size; @@ -92,19 +92,9 @@ void AvlAllocator::_add_to_tree(uint64_t start, uint64_t size) } } -void AvlAllocator::_remove_from_tree(uint64_t start, uint64_t size) +void AvlAllocator::_process_range_removal(uint64_t start, uint64_t end, + AvlAllocator::range_tree_t::iterator& rs) { - uint64_t end = start + size; - - assert(size != 0); - assert(size <= num_free); - - auto rs = range_tree.find(range_t{start, end}, range_tree.key_comp()); - /* Make sure we completely overlap with someone */ - assert(rs != range_tree.end()); - assert(rs->start <= start); - assert(rs->end >= end); - bool left_over = (rs->start != start); bool right_over = (rs->end != end); @@ -135,6 +125,58 @@ void AvlAllocator::_remove_from_tree(uint64_t start, uint64_t size) } } +void AvlAllocator::_remove_from_tree(uint64_t start, uint64_t size) +{ + uint64_t end = start + size; + + ceph_assert(size != 0); + ceph_assert(size <= num_free); + + auto rs = range_tree.find(range_t{start, end}, range_tree.key_comp()); + /* Make sure we completely overlap with someone */ + ceph_assert(rs != range_tree.end()); + ceph_assert(rs->start <= start); + ceph_assert(rs->end >= end); + + _process_range_removal(start, end, rs); +} + +void AvlAllocator::_try_remove_from_tree(uint64_t start, uint64_t size, + std::function cb) +{ + uint64_t end = start + size; + + ceph_assert(size != 0); + + auto rs = range_tree.find(range_t{ start, end }, + range_tree.key_comp()); + + if (rs == range_tree.end() || rs->start >= end) { + cb(start, size, false); + return; + } + + do { + + auto next_rs = rs; + ++next_rs; + + if (start < rs->start) { + cb(start, rs->start - start, false); + start = rs->start; + } + auto range_end = std::min(rs->end, end); + _process_range_removal(start, range_end, rs); + cb(start, range_end - start, true); + start = range_end; + + rs = next_rs; + } while (rs != range_tree.end() && rs->start < end && start < end); + if (start < end) { + cb(start, end - start, false); + } +} + int64_t AvlAllocator::_allocate( uint64_t want, uint64_t unit, @@ -174,7 +216,7 @@ int AvlAllocator::_allocate( return -ENOSPC; } size = p2align(max_size, unit); - assert(size > 0); + ceph_assert(size > 0); force_range_size_alloc = true; } /* @@ -185,7 +227,7 @@ int AvlAllocator::_allocate( * region. */ const uint64_t align = size & -size; - assert(align != 0); + ceph_assert(align != 0); uint64_t *cursor = &lbas[cbits(align) - 1]; const int free_pct = num_free * 100 / num_total; @@ -226,6 +268,16 @@ void AvlAllocator::_release(const interval_set& release_set) } } +void AvlAllocator::_release(const PExtentVector& release_set) { + for (auto& e : release_set) { + ldout(cct, 10) << __func__ << std::hex + << " offset 0x" << e.offset + << " length 0x" << e.length + << std::dec << dendl; + _add_to_tree(e.offset, e.length); + } +} + void AvlAllocator::_shutdown() { range_size_tree.clear(); @@ -275,15 +327,15 @@ int64_t AvlAllocator::allocate( << " max_alloc_size 0x" << max_alloc_size << " hint 0x" << hint << std::dec << dendl; - assert(isp2(unit)); - assert(want % unit == 0); + ceph_assert(isp2(unit)); + ceph_assert(want % unit == 0); if (max_alloc_size == 0) { max_alloc_size = want; } if (constexpr auto cap = std::numeric_limits::max(); max_alloc_size >= cap) { - max_alloc_size = cap; + max_alloc_size = p2align(uint64_t(cap), (uint64_t)block_size); } std::lock_guard l(lock); return _allocate(want, unit, max_alloc_size, hint, extents); diff --git a/src/os/bluestore/AvlAllocator.h b/src/os/bluestore/AvlAllocator.h index 79bb3f42d2fda..05dfb98b28b20 100644 --- a/src/os/bluestore/AvlAllocator.h +++ b/src/os/bluestore/AvlAllocator.h @@ -77,6 +77,13 @@ public: int64_t hint, PExtentVector *extents) override; void release(const interval_set& release_set) override; + int64_t get_capacity() const { + return num_total; + } + + uint64_t get_block_size() const { + return block_size; + } uint64_t get_free() override; double get_fragmentation() override; @@ -231,8 +238,16 @@ protected: PExtentVector *extents); void _release(const interval_set& release_set); + void _release(const PExtentVector& release_set); void _shutdown(); void _add_to_tree(uint64_t start, uint64_t size); + void _process_range_removal(uint64_t start, uint64_t end, range_tree_t::iterator& rs); void _remove_from_tree(uint64_t start, uint64_t size); + void _try_remove_from_tree(uint64_t start, uint64_t size, + std::function cb); + + uint64_t _get_free() const { + return num_free; + } }; -- 2.39.5