aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-extended/ceph/ceph/0002-common-replace-BitVector-NoInitAllocator-with-wrappe.patch
blob: 4f46d22339108f4635c4348d08b4b6868c5416e2 (plain)
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;
   }
 }