1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
From cca3144aca7f7c19772065421f9b02205a84e0b8 Mon Sep 17 00:00:00 2001
From: Casey Bodley <cbodley@redhat.com>
Date: Tue, 15 Feb 2022 18:27:10 -0500
Subject: [PATCH] common: replace BitVector::NoInitAllocator with wrapper
struct
in c++20, the deprecated `struct std::allocator<T>::rebind` template was
removed, so `BitVector` no longer compiles. without a `rebind` to
inherit, `std::allocator_traits<NoInitAllocator>::rebind_alloc<U>` was
looking for `NoInitAllocator<U>`, 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 <cbodley@redhat.com>
---
Fixes:
http://errors.yoctoproject.org/Errors/Details/701862/
Upstream-Status: Backport [https://github.com/ceph/ceph/commit/4f0ad8aab6b21a1fd57a7c1630d298e31b5d9bb6]
src/common/bit_vector.hpp | 27 +++++++++++----------------
1 file changed, 11 insertions(+), 16 deletions(-)
diff --git a/src/common/bit_vector.hpp b/src/common/bit_vector.hpp
index 10ee6c3e..9ce3e8b1 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<BitVector *> &o);
private:
- struct NoInitAllocator : public std::allocator<__u32> {
- NoInitAllocator() {}
- NoInitAllocator(const std::allocator<__u32>& alloc)
- : std::allocator<__u32>(alloc) {
- }
-
- template <class U, class... Args>
- 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<u32_struct> 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;
}
}
|