diff --git a/src/os/bluestore/bluestore_types.cc b/src/os/bluestore/bluestore_types.cc index f85f842f6ad..5c967dc4e3a 100644 --- a/src/os/bluestore/bluestore_types.cc +++ b/src/os/bluestore/bluestore_types.cc @@ -356,11 +356,12 @@ ostream& operator<<(ostream& out, const bluestore_extent_ref_map_t& m) bluestore_blob_use_tracker_t::bluestore_blob_use_tracker_t( const bluestore_blob_use_tracker_t& tracker) : au_size{tracker.au_size}, - num_au{tracker.num_au}, + num_au(0), + alloc_au(0), bytes_per_au{nullptr} { - if (num_au > 0) { - allocate(); + if (tracker.num_au > 0) { + allocate(tracker.num_au); std::copy(tracker.bytes_per_au, tracker.bytes_per_au + num_au, bytes_per_au); } else { total_bytes = tracker.total_bytes; @@ -375,9 +376,8 @@ bluestore_blob_use_tracker_t::operator=(const bluestore_blob_use_tracker_t& rhs) } clear(); au_size = rhs.au_size; - num_au = rhs.num_au; if (rhs.num_au > 0) { - allocate(); + allocate( rhs.num_au); std::copy(rhs.bytes_per_au, rhs.bytes_per_au + num_au, bytes_per_au); } else { total_bytes = rhs.total_bytes; @@ -385,19 +385,31 @@ bluestore_blob_use_tracker_t::operator=(const bluestore_blob_use_tracker_t& rhs) return *this; } -void bluestore_blob_use_tracker_t::allocate() +void bluestore_blob_use_tracker_t::allocate(uint32_t au_count) { - ceph_assert(num_au != 0); - bytes_per_au = new uint32_t[num_au]; + ceph_assert(au_count != 0); + ceph_assert(num_au == 0); + ceph_assert(alloc_au == 0); + num_au = alloc_au = au_count; + bytes_per_au = new uint32_t[alloc_au]; mempool::get_pool( mempool::pool_index_t(mempool::mempool_bluestore_cache_other)). - adjust_count(1, sizeof(uint32_t) * num_au); + adjust_count(alloc_au, sizeof(uint32_t) * alloc_au); for (uint32_t i = 0; i < num_au; ++i) { bytes_per_au[i] = 0; } } +void bluestore_blob_use_tracker_t::release(uint32_t au_count, uint32_t* ptr) { + if (au_count) { + delete[] ptr; + mempool::get_pool( + mempool::pool_index_t(mempool::mempool_bluestore_cache_other)). + adjust_count(-au_count, -sizeof(uint32_t) * au_count); + } +} + void bluestore_blob_use_tracker_t::init( uint32_t full_length, uint32_t _au_size) { ceph_assert(!au_size || is_empty()); @@ -407,8 +419,7 @@ void bluestore_blob_use_tracker_t::init( uint32_t _num_au = round_up_to(full_length, _au_size) / _au_size; au_size = _au_size; if ( _num_au > 1 ) { - num_au = _num_au; - allocate(); + allocate(_num_au); } } diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h index 3a7db755668..3895d0fd88e 100644 --- a/src/os/bluestore/bluestore_types.h +++ b/src/os/bluestore/bluestore_types.h @@ -244,10 +244,11 @@ struct bluestore_blob_use_tracker_t { // 1) Struct isn't packed hence it's padded. And even if it's packed see 2) // 2) Mem manager has its own granularity, most probably >= 8 bytes // - uint32_t au_size; // Allocation (=tracking) unit size, - // == 0 if uninitialized - uint32_t num_au; // Amount of allocation units tracked - // == 0 if single unit or the whole blob is tracked + uint32_t au_size; // Allocation (=tracking) unit size, + // == 0 if uninitialized + uint32_t num_au; // Amount of allocation units tracked + // == 0 if single unit or the whole blob is tracked + uint32_t alloc_au; // Amount of allocation units allocated union { uint32_t* bytes_per_au; @@ -255,7 +256,7 @@ struct bluestore_blob_use_tracker_t { }; bluestore_blob_use_tracker_t() - : au_size(0), num_au(0), bytes_per_au(nullptr) { + : au_size(0), num_au(0), alloc_au(0), bytes_per_au(nullptr) { } bluestore_blob_use_tracker_t(const bluestore_blob_use_tracker_t& tracker); bluestore_blob_use_tracker_t& operator=(const bluestore_blob_use_tracker_t& rhs); @@ -264,15 +265,11 @@ struct bluestore_blob_use_tracker_t { } void clear() { - if (num_au != 0) { - delete[] bytes_per_au; - mempool::get_pool( - mempool::pool_index_t(mempool::mempool_bluestore_cache_other)). - adjust_count(-1, -sizeof(uint32_t) * num_au); - } + release(alloc_au, bytes_per_au); + num_au = 0; + alloc_au = 0; bytes_per_au = 0; au_size = 0; - num_au = 0; } uint32_t get_referenced_bytes() const { @@ -308,7 +305,6 @@ struct bluestore_blob_use_tracker_t { ceph_assert(_num_au <= num_au); if (_num_au) { num_au = _num_au; // bytes_per_au array is left unmodified - } else { clear(); } @@ -334,15 +330,17 @@ struct bluestore_blob_use_tracker_t { if (_num_au > num_au) { auto old_bytes = bytes_per_au; auto old_num_au = num_au; - num_au = _num_au; - allocate(); + auto old_alloc_au = alloc_au; + alloc_au = num_au = 0; // to bypass an assertion in allocate() + bytes_per_au = nullptr; + allocate(_num_au); for (size_t i = 0; i < old_num_au; i++) { bytes_per_au[i] = old_bytes[i]; } for (size_t i = old_num_au; i < num_au; i++) { bytes_per_au[i] = 0; } - delete[] old_bytes; + release(old_alloc_au, old_bytes); } } } @@ -407,12 +405,14 @@ struct bluestore_blob_use_tracker_t { clear(); denc_varint(au_size, p); if (au_size) { - denc_varint(num_au, p); - if (!num_au) { + uint32_t _num_au; + denc_varint(_num_au, p); + if (!_num_au) { + num_au = 0; denc_varint(total_bytes, p); } else { - allocate(); - for (size_t i = 0; i < num_au; ++i) { + allocate(_num_au); + for (size_t i = 0; i < _num_au; ++i) { denc_varint(bytes_per_au[i], p); } } @@ -422,7 +422,8 @@ struct bluestore_blob_use_tracker_t { void dump(Formatter *f) const; static void generate_test_instances(list& o); private: - void allocate(); + void allocate(uint32_t _num_au); + void release(uint32_t _num_au, uint32_t* ptr); }; WRITE_CLASS_DENC(bluestore_blob_use_tracker_t) ostream& operator<<(ostream& out, const bluestore_blob_use_tracker_t& rm);