From: Casey Bodley Date: Tue, 15 Feb 2022 23:27:10 +0000 (-0500) Subject: common: replace BitVector::NoInitAllocator with wrapper struct X-Git-Tag: v16.2.8~133^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F45179%2Fhead;p=ceph.git common: replace BitVector::NoInitAllocator with wrapper struct in c++20, the deprecated `struct std::allocator::rebind` template was removed, so `BitVector` no longer compiles. without a `rebind` to inherit, `std::allocator_traits::rebind_alloc` was looking for `NoInitAllocator`, but it isn't a template class further investigation found that in c++17, `vector<__u32, NoInitAllocator>` was rebinding this `NoInitAllocator` to `std::allocator<__u32>` and preventing the no-init optimization from taking effect instead of messing with the allocator to avoid zero-initialization, wrap each __u32 in a struct whose constructor does not initialize the value Fixes: https://tracker.ceph.com/issues/54279 Signed-off-by: Casey Bodley (cherry picked from commit 4f0ad8aab6b21a1fd57a7c1630d298e31b5d9bb6) --- diff --git a/src/common/bit_vector.hpp b/src/common/bit_vector.hpp index 10ee6c3ed6ccd..9ce3e8b1ebb23 100644 --- a/src/common/bit_vector.hpp +++ b/src/common/bit_vector.hpp @@ -223,23 +223,18 @@ public: static void generate_test_instances(std::list &o); private: - struct NoInitAllocator : public std::allocator<__u32> { - NoInitAllocator() {} - NoInitAllocator(const std::allocator<__u32>& alloc) - : std::allocator<__u32>(alloc) { - } - - template - void construct(U* p, Args&&... args) const { - } - }; - bufferlist m_data; uint64_t m_size; bool m_crc_enabled; mutable __u32 m_header_crc; - mutable std::vector<__u32, NoInitAllocator> m_data_crcs; + + // inhibit value-initialization when used in std::vector + struct u32_struct { + u32_struct() {} + __u32 val; + }; + mutable std::vector m_data_crcs; void resize(uint64_t elements, bool zero); @@ -351,7 +346,7 @@ void BitVector<_b>::encode_data(bufferlist& bl, uint64_t data_byte_offset, bufferlist bit; bit.substr_of(m_data, data_byte_offset, len); - m_data_crcs[data_byte_offset / BLOCK_SIZE] = bit.crc32c(0); + m_data_crcs[data_byte_offset / BLOCK_SIZE].val = bit.crc32c(0); bl.claim_append(bit); data_byte_offset += BLOCK_SIZE; @@ -385,7 +380,7 @@ void BitVector<_b>::decode_data(bufferlist::const_iterator& it, bufferlist bit; bit.append(ptr); if (m_crc_enabled && - m_data_crcs[data_byte_offset / BLOCK_SIZE] != bit.crc32c(0)) { + m_data_crcs[data_byte_offset / BLOCK_SIZE].val != bit.crc32c(0)) { throw buffer::malformed_input("invalid data block CRC"); } data.append(bit); @@ -499,7 +494,7 @@ void BitVector<_b>::encode_data_crcs(bufferlist& bl, uint64_t offset, compute_index(offset + length - 1, &index, &shift); uint64_t end_crc_index = index / BLOCK_SIZE; while (crc_index <= end_crc_index) { - __u32 crc = m_data_crcs[crc_index++]; + __u32 crc = m_data_crcs[crc_index++].val; ceph::encode(crc, bl); } } @@ -520,7 +515,7 @@ void BitVector<_b>::decode_data_crcs(bufferlist::const_iterator& it, while (remaining > 0) { __u32 crc; ceph::decode(crc, it); - m_data_crcs[crc_index++] = crc; + m_data_crcs[crc_index++].val = crc; --remaining; } }