From: Igor Fedotov Date: Thu, 24 Jul 2025 22:30:55 +0000 (+0300) Subject: compressor/zstd: correct buffer end detection using get_remaining() X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=54b4582199d7273c2da1e291c51fd436c2b54813;p=ceph.git compressor/zstd: correct buffer end detection using get_remaining() Replace p.end() check with get_remaining() to properly detect buffer exhaustion. The source bufferlist may contain empty pointers at the end, causing p.end() to return false even when all data has been processed during compression. Signed-off-by: Igor Fedotov --- diff --git a/src/compressor/zstd/ZstdCompressor.h b/src/compressor/zstd/ZstdCompressor.h index 859bd6b578cc..17aff35de5fa 100644 --- a/src/compressor/zstd/ZstdCompressor.h +++ b/src/compressor/zstd/ZstdCompressor.h @@ -51,7 +51,7 @@ class ZstdCompressor : public Compressor { return -EINVAL; } } - ceph_assert(p.end()); + ceph_assert(p.get_remaining() == 0); ZSTD_freeCStream(s); diff --git a/src/test/compressor/test_compression.cc b/src/test/compressor/test_compression.cc index c5e4724cefcf..6dfccdaa410a 100644 --- a/src/test/compressor/test_compression.cc +++ b/src/test/compressor/test_compression.cc @@ -213,13 +213,14 @@ TEST_P(CompressorTest, compress_decompress) bufferlist in, out; bufferlist after; bufferlist exp; + in.append(test, len); + exp.append(test); std::optional compressor_message; res = compressor->compress(in, out, compressor_message); EXPECT_EQ(res, 0); res = compressor->decompress(out, after, compressor_message); EXPECT_EQ(res, 0); - exp.append(test); EXPECT_TRUE(exp.contents_equal(after)); after.clear(); size_t compressed_len = out.length(); @@ -229,6 +230,25 @@ TEST_P(CompressorTest, compress_decompress) EXPECT_EQ(res, 0); EXPECT_TRUE(exp.contents_equal(after)); + //compressing bl which has got empty bufferptr at the end + in.clear(); + out.clear(); + after.clear(); + exp.clear(); + + const size_t PREALLOC_SIZE = 1; // any non-zero value would suffice here + bufferlist dummy(PREALLOC_SIZE); // this appends an empty preallocated ptr to the end of the bufferlist + EXPECT_TRUE(dummy.buffers().back().length() == 0); // make sure we have empty ptr at the end + in.append(test, len); + in.append(dummy); + exp.append(test); + + res = compressor->compress(in, out, compressor_message); + EXPECT_EQ(res, 0); + res = compressor->decompress(out, after, compressor_message); + EXPECT_EQ(res, 0); + EXPECT_TRUE(exp.contents_equal(after)); + //large block and non-begin iterator for continuous block std::string data; data.resize(0x10000 * 1);