Skip to content

Commit 80b7d68

Browse files
committed
os/bluestore/compression: Fix Estimator::split_and_compress
Fixed calculation on effective blob size. When fully non-compressible data is passed, it could cause losing few bytes in the end. Example: -107> 2025-05-17T20:40:50.468+0000 7f267a42f640 15 bluestore(/var/lib/ceph/osd/ceph-4) _do_write_v2_compressed 200000~78002 -> 200000~78002 -106> 2025-05-17T20:40:50.468+0000 7f267a42f640 20 blobs to put: 200000~f000(4d61) 20f000~f000(b51) 21e000~f000(b51) 22d000~f000(b51) 23c000~f000(b51) 24b000~f000(b51) 25a000~f000(b51) 269000~f000(b51) In result we split 0x78002 into 8 * 0xf000, losing 0x2 in the process. Calculations for original: >>> size=0x78002 >>> blobs=(size+0xffff) / 0x10000 >>> blob_size = size / blobs >>> print hex(size), blobs, hex(blob_size) 0x78002 8 0xf000 <-this means roundup is 0xf000 Calculations for fixed: >>> size=0x78002 >>> blobs=(size+0xffff) / 0x10000 >>> blob_size = (size+blobs-1) / blobs >>> print hex(size), blobs, hex(blob_size) 0x78002 8 0xf001 <-this meand roundup is 0x10000 Fixes: https://tracker.ceph.com/issues/71353 Signed-off-by: Adam Kupczyk <[email protected]>
1 parent 45c2b71 commit 80b7d68

File tree

1 file changed

+5
-6
lines changed

1 file changed

+5
-6
lines changed

src/os/bluestore/Compression.cc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,11 @@ int32_t Estimator::split_and_compress(
188188
uint32_t size = data_bl.length();
189189
ceph_assert(size > 0);
190190
uint32_t blobs = (size + wctx->target_blob_size - 1) / wctx->target_blob_size;
191-
uint32_t blob_size = p2roundup(size / blobs, au_size);
192-
std::vector<uint32_t> blob_sizes(blobs);
193-
for (auto& i: blob_sizes) {
194-
i = std::min(size, blob_size);
195-
size -= i;
196-
}
191+
uint32_t blob_size = p2roundup((size + blobs - 1) / blobs, au_size);
192+
// dividing 'size' to 'blobs'
193+
// blobs[*] = blob_size; blobs[last] = whatever remains from 'size'
194+
std::vector<uint32_t> blob_sizes(blobs, blob_size);
195+
blob_sizes.back() = size - blob_size * (blobs - 1);
197196
int32_t disk_needed = 0;
198197
uint32_t bl_src_off = 0;
199198
for (auto& i: blob_sizes) {

0 commit comments

Comments
 (0)