]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
compressor/zstd: correct buffer end detection using get_remaining() 64682/head
authorIgor Fedotov <igor.fedotov@croit.io>
Thu, 24 Jul 2025 22:30:55 +0000 (01:30 +0300)
committerIgor Fedotov <igor.fedotov@croit.io>
Fri, 25 Jul 2025 11:05:42 +0000 (14:05 +0300)
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 <igor.fedotov@croit.io>
src/compressor/zstd/ZstdCompressor.h
src/test/compressor/test_compression.cc

index 859bd6b578cc7a27b3ead44ffc0ad127c186ad85..17aff35de5fa6bd4ce6b40a638dc8dcb86f95295 100644 (file)
@@ -51,7 +51,7 @@ class ZstdCompressor : public Compressor {
        return -EINVAL;
       }
     }
-    ceph_assert(p.end());
+    ceph_assert(p.get_remaining() == 0);
 
     ZSTD_freeCStream(s);
 
index c5e4724cefcf70e5fb2ad27d198395768a0bbcb4..6dfccdaa410aa5f3c7b14de8019f02316aa50e93 100644 (file)
@@ -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<int32_t> 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);