From 505322f8ea80dd48660ed15194f4d6dfac10ad76 Mon Sep 17 00:00:00 2001
From: WangPengfei <wpf_1253@qq.com>
Date: Mon, 3 Aug 2020 09:44:11 +0800
Subject: [PATCH] 	modified:   common/legacy_config_opts.h 
 modified:   common/options.cc 	modified:   compressor/Compressor.h 
 modified:   compressor/QatAccel.cc 	modified:   compressor/QatAccel.h 
 modified:   compressor/brotli/BrotliCompressor.cc 	modified:  
 compressor/brotli/BrotliCompressor.h 	modified:  
 compressor/lz4/LZ4Compressor.h 	modified:  
 compressor/snappy/SnappyCompressor.h 	modified:  
 compressor/zlib/ZlibCompressor.cc 	modified:  
 compressor/zlib/ZlibCompressor.h 	modified:  
 compressor/zstd/ZstdCompressor.h 	modified:   os/bluestore/BlueStore.cc 
 modified:   os/bluestore/bluestore_types.cc 	modified:  
 os/bluestore/bluestore_types.h 	modified:   rgw/rgw_compression.cc 
 modified:   rgw/rgw_compression.h 	modified:   rgw/rgw_json_enc.cc 
 modified:   rgw/rgw_op.cc 	modified:   rgw/rgw_rados.cc 	modified:  
 rgw/rgw_rados.h 	modified:   test/compressor/compressor_example.h 
 modified:   test/compressor/test_compression.cc 	modified:  
 test/rgw/test_rgw_compression.cc

Signed-off-by: WangPengfei <wpf_1253@qq.com>
---
 src/common/legacy_config_opts.h           |  1 +
 src/common/options.cc                     |  5 ++
 src/compressor/Compressor.h               |  6 +-
 src/compressor/QatAccel.cc                |  9 +--
 src/compressor/QatAccel.h                 |  6 +-
 src/compressor/brotli/BrotliCompressor.cc |  9 +--
 src/compressor/brotli/BrotliCompressor.h  |  6 +-
 src/compressor/lz4/LZ4Compressor.h        | 15 ++---
 src/compressor/snappy/SnappyCompressor.h  | 15 ++---
 src/compressor/zlib/ZlibCompressor.cc     | 32 ++++++-----
 src/compressor/zlib/ZlibCompressor.h      | 10 ++--
 src/compressor/zstd/ZstdCompressor.h      |  9 +--
 src/os/bluestore/BlueStore.cc             |  6 +-
 src/os/bluestore/bluestore_types.cc       |  3 +
 src/os/bluestore/bluestore_types.h        |  6 +-
 src/rgw/rgw_compression.cc                |  4 +-
 src/rgw/rgw_compression.h                 |  2 +
 src/rgw/rgw_json_enc.cc                   |  3 +
 src/rgw/rgw_op.cc                         |  3 +
 src/rgw/rgw_rados.cc                      |  1 +
 src/rgw/rgw_rados.h                       | 10 +++-
 src/test/compressor/compressor_example.h  |  6 +-
 src/test/compressor/test_compression.cc   | 68 +++++++++++++----------
 src/test/rgw/test_rgw_compression.cc      |  2 +
 24 files changed, 145 insertions(+), 92 deletions(-)

diff --git a/src/common/legacy_config_opts.h b/src/common/legacy_config_opts.h
index 7aae31e8ea..cf6f9e874f 100644
--- a/src/common/legacy_config_opts.h
+++ b/src/common/legacy_config_opts.h
@@ -96,6 +96,7 @@ OPTION(xio_max_send_inline, OPT_INT) // xio maximum threshold to send inline
 
 OPTION(compressor_zlib_isal, OPT_BOOL)
 OPTION(compressor_zlib_level, OPT_INT) //regular zlib compression level, not applicable to isa-l optimized version
+OPTION(compressor_zlib_winsize, OPT_INT)
 
 OPTION(qat_compressor_enabled, OPT_BOOL)
 
diff --git a/src/common/options.cc b/src/common/options.cc
index 8135ea8f1e..91a8472a1c 100644
--- a/src/common/options.cc
+++ b/src/common/options.cc
@@ -816,6 +816,11 @@ std::vector<Option> get_global_options() {
     .set_default(5)
     .set_description("Zlib compression level to use"),
 
+    Option("compressor_zlib_winsize", Option::TYPE_INT, Option::LEVEL_ADVANCED)
+    .set_default(-15)
+    .set_min_max(-15,32)
+    .set_description("Zlib compression winsize to use"),
+
     Option("qat_compressor_enabled", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
     .set_default(false)
     .set_description("Enable Intel QAT acceleration support for compression if available"),
diff --git a/src/compressor/Compressor.h b/src/compressor/Compressor.h
index a696521ad6..eb76a6e41c 100644
--- a/src/compressor/Compressor.h
+++ b/src/compressor/Compressor.h
@@ -88,11 +88,11 @@ public:
   CompressionAlgorithm get_type() const {
     return alg;
   }
-  virtual int compress(const ceph::bufferlist &in, ceph::bufferlist &out) = 0;
-  virtual int decompress(const ceph::bufferlist &in, ceph::bufferlist &out) = 0;
+  virtual int compress(const ceph::bufferlist &in, ceph::bufferlist &out, boost::optional<int32_t> &compressor_message) = 0;
+  virtual int decompress(const ceph::bufferlist &in, ceph::bufferlist &out, boost::optional<int32_t> compressor_message) = 0;
   // this is a bit weird but we need non-const iterator to be in
   // alignment with decode methods
-  virtual int decompress(ceph::bufferlist::const_iterator &p, size_t compressed_len, ceph::bufferlist &out) = 0;
+  virtual int decompress(ceph::bufferlist::const_iterator &p, size_t compressed_len, ceph::bufferlist &out, boost::optional<int32_t> compressor_message) = 0;
 
   static CompressorRef create(CephContext *cct, const std::string &type);
   static CompressorRef create(CephContext *cct, int alg);
diff --git a/src/compressor/QatAccel.cc b/src/compressor/QatAccel.cc
index 7836243b8a..69bfbbc470 100644
--- a/src/compressor/QatAccel.cc
+++ b/src/compressor/QatAccel.cc
@@ -59,7 +59,7 @@ bool QatAccel::init(const std::string &alg) {
   return true;
 }
 
-int QatAccel::compress(const bufferlist &in, bufferlist &out) {
+int QatAccel::compress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> &compressor_message) {
   for (auto &i : in.buffers()) {
     const unsigned char* c_in = (unsigned char*) i.c_str();
     unsigned int len = i.length();
@@ -75,14 +75,15 @@ int QatAccel::compress(const bufferlist &in, bufferlist &out) {
   return 0;
 }
 
-int QatAccel::decompress(const bufferlist &in, bufferlist &out) {
+int QatAccel::decompress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> compressor_message) {
   auto i = in.begin();
-  return decompress(i, in.length(), out);
+  return decompress(i, in.length(), out, compressor_message);
 }
 
 int QatAccel::decompress(bufferlist::const_iterator &p,
 		 size_t compressed_len,
-		 bufferlist &dst) {
+		 bufferlist &dst, 
+		 boost::optional<int32_t> &compressor_message) {
   unsigned int ratio_idx = 0;
   bool read_more = false;
   bool joint = false;
diff --git a/src/compressor/QatAccel.h b/src/compressor/QatAccel.h
index 295b180eb2..f15e330370 100644
--- a/src/compressor/QatAccel.h
+++ b/src/compressor/QatAccel.h
@@ -27,9 +27,9 @@ class QatAccel {
 
   bool init(const std::string &alg);
 
-  int compress(const bufferlist &in, bufferlist &out);
-  int decompress(const bufferlist &in, bufferlist &out);
-  int decompress(bufferlist::const_iterator &p, size_t compressed_len, bufferlist &dst);
+  int compress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> &compressor_message);
+  int decompress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> compressor_message);
+  int decompress(bufferlist::const_iterator &p, size_t compressed_len, bufferlist &dst, boost::optional<int32_t> compressor_message);
 };
 
 #endif
diff --git a/src/compressor/brotli/BrotliCompressor.cc b/src/compressor/brotli/BrotliCompressor.cc
index 27685da35b..ed4abef4bb 100644
--- a/src/compressor/brotli/BrotliCompressor.cc
+++ b/src/compressor/brotli/BrotliCompressor.cc
@@ -5,7 +5,7 @@
 
 #define MAX_LEN (CEPH_PAGE_SIZE)
 
-int BrotliCompressor::compress(const bufferlist &in, bufferlist &out) 
+int BrotliCompressor::compress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> &compressor_message) 
 {
   BrotliEncoderState* s = BrotliEncoderCreateInstance(nullptr,
                                                       nullptr,
@@ -49,7 +49,8 @@ int BrotliCompressor::compress(const bufferlist &in, bufferlist &out)
 
 int BrotliCompressor::decompress(bufferlist::const_iterator &p,
                                  size_t compressed_size,
-                                 bufferlist &out) 
+                                 bufferlist &out,
+				 boost::optional<int32_t> compressor_message) 
 {
   BrotliDecoderState* s = BrotliDecoderCreateInstance(nullptr,
                                                       nullptr,
@@ -88,8 +89,8 @@ int BrotliCompressor::decompress(bufferlist::const_iterator &p,
   return 0;
 }
 
-int BrotliCompressor::decompress(const bufferlist &in, bufferlist &out) 
+int BrotliCompressor::decompress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> compressor_message) 
 {  
   auto i = std::cbegin(in);
-  return decompress(i, in.length(), out);
+  return decompress(i, in.length(), out, compressor_message);
 }
diff --git a/src/compressor/brotli/BrotliCompressor.h b/src/compressor/brotli/BrotliCompressor.h
index 482fe5e20e..373300645f 100644
--- a/src/compressor/brotli/BrotliCompressor.h
+++ b/src/compressor/brotli/BrotliCompressor.h
@@ -22,9 +22,9 @@ class BrotliCompressor : public Compressor
   public:
   BrotliCompressor() : Compressor(COMP_ALG_BROTLI, "brotli") {}
   
-  int compress(const bufferlist &in, bufferlist &out) override;
-  int decompress(const bufferlist &in, bufferlist &out) override;
-  int decompress(bufferlist::const_iterator &p, size_t compressed_len, bufferlist &out) override;
+  int compress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> &compressor_message) override;
+  int decompress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> compressor_message) override;
+  int decompress(bufferlist::const_iterator &p, size_t compressed_len, bufferlist &out, boost::optional<int32_t> compressor_message) override;
 };
 
 #endif //CEPH_BROTLICOMPRESSOR_H
diff --git a/src/compressor/lz4/LZ4Compressor.h b/src/compressor/lz4/LZ4Compressor.h
index 8189f18f4c..0b528981bf 100644
--- a/src/compressor/lz4/LZ4Compressor.h
+++ b/src/compressor/lz4/LZ4Compressor.h
@@ -35,10 +35,10 @@ class LZ4Compressor : public Compressor {
 #endif
   }
 
-  int compress(const bufferlist &src, bufferlist &dst) override {
+  int compress(const bufferlist &src, bufferlist &dst, boost::optional<int32_t> &compressor_message) override {
 #ifdef HAVE_QATZIP
     if (qat_enabled)
-      return qat_accel.compress(src, dst);
+      return qat_accel.compress(src, dst, compressor_message);
 #endif
     bufferptr outptr = buffer::create_small_page_aligned(
       LZ4_compressBound(src.length()));
@@ -69,21 +69,22 @@ class LZ4Compressor : public Compressor {
     return 0;
   }
 
-  int decompress(const bufferlist &src, bufferlist &dst) override {
+  int decompress(const bufferlist &src, bufferlist &dst, boost::optional<int32_t> compressor_message) override {
 #ifdef HAVE_QATZIP
     if (qat_enabled)
-      return qat_accel.decompress(src, dst);
+      return qat_accel.decompress(src, dst, compressor_message);
 #endif
     auto i = std::cbegin(src);
-    return decompress(i, src.length(), dst);
+    return decompress(i, src.length(), dst, compressor_message);
   }
 
   int decompress(bufferlist::const_iterator &p,
 		 size_t compressed_len,
-		 bufferlist &dst) override {
+		 bufferlist &dst, 
+		 boost::optional<int32_t> compressor_message) override {
 #ifdef HAVE_QATZIP
     if (qat_enabled)
-      return qat_accel.decompress(p, compressed_len, dst);
+      return qat_accel.decompress(p, compressed_len, dst, compressor_message);
 #endif
     uint32_t count;
     std::vector<std::pair<uint32_t, uint32_t> > compressed_pairs;
diff --git a/src/compressor/snappy/SnappyCompressor.h b/src/compressor/snappy/SnappyCompressor.h
index 0291a92311..ce998f5c8e 100644
--- a/src/compressor/snappy/SnappyCompressor.h
+++ b/src/compressor/snappy/SnappyCompressor.h
@@ -66,10 +66,10 @@ class SnappyCompressor : public Compressor {
 #endif
   }
 
-  int compress(const bufferlist &src, bufferlist &dst) override {
+  int compress(const bufferlist &src, bufferlist &dst, boost::optional<int32_t> &compressor_message) override {
 #ifdef HAVE_QATZIP
     if (qat_enabled)
-      return qat_accel.compress(src, dst);
+      return qat_accel.compress(src, dst, compressor_message);
 #endif
     BufferlistSource source(const_cast<bufferlist&>(src).begin(), src.length());
     bufferptr ptr = buffer::create_small_page_aligned(
@@ -80,21 +80,22 @@ class SnappyCompressor : public Compressor {
     return 0;
   }
 
-  int decompress(const bufferlist &src, bufferlist &dst) override {
+  int decompress(const bufferlist &src, bufferlist &dst, boost::optional<int32_t> compressor_message) override {
 #ifdef HAVE_QATZIP
     if (qat_enabled)
-      return qat_accel.decompress(src, dst);
+      return qat_accel.decompress(src, dst, compressor_message);
 #endif
     auto i = src.begin();
-    return decompress(i, src.length(), dst);
+    return decompress(i, src.length(), dst, compressor_message);
   }
 
   int decompress(bufferlist::const_iterator &p,
 		 size_t compressed_len,
-		 bufferlist &dst) override {
+		 bufferlist &dst, 
+		 boost::optional<int32_t> compressor_message) override {
 #ifdef HAVE_QATZIP
     if (qat_enabled)
-      return qat_accel.decompress(p, compressed_len, dst);
+      return qat_accel.decompress(p, compressed_len, dst, compressor_message);
 #endif
     snappy::uint32 res_len = 0;
     BufferlistSource source_1(p, compressed_len);
diff --git a/src/compressor/zlib/ZlibCompressor.cc b/src/compressor/zlib/ZlibCompressor.cc
index e3064d2a21..0957e1d407 100644
--- a/src/compressor/zlib/ZlibCompressor.cc
+++ b/src/compressor/zlib/ZlibCompressor.cc
@@ -47,7 +47,7 @@ _prefix(std::ostream* _dout)
 // compression ratio.
 #define ZLIB_MEMORY_LEVEL 8
 
-int ZlibCompressor::zlib_compress(const bufferlist &in, bufferlist &out)
+int ZlibCompressor::zlib_compress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> &compressor_message)
 {
   int ret;
   unsigned have;
@@ -59,12 +59,13 @@ int ZlibCompressor::zlib_compress(const bufferlist &in, bufferlist &out)
   strm.zalloc = Z_NULL;
   strm.zfree = Z_NULL;
   strm.opaque = Z_NULL;
-  ret = deflateInit2(&strm, cct->_conf->compressor_zlib_level, Z_DEFLATED, ZLIB_DEFAULT_WIN_SIZE, ZLIB_MEMORY_LEVEL, Z_DEFAULT_STRATEGY);
+  ret = deflateInit2(&strm, cct->_conf->compressor_zlib_level, Z_DEFLATED, cct->_conf->compressor_zlib_winsize, ZLIB_MEMORY_LEVEL, Z_DEFAULT_STRATEGY);
   if (ret != Z_OK) {
     dout(1) << "Compression init error: init return "
          << ret << " instead of Z_OK" << dendl;
     return -1;
   }
+  compressor_message = cct->_conf->compressor_zlib_winsize;
 
   for (ceph::bufferlist::buffers_t::const_iterator i = in.buffers().begin();
       i != in.buffers().end();) {
@@ -108,7 +109,7 @@ int ZlibCompressor::zlib_compress(const bufferlist &in, bufferlist &out)
 }
 
 #if __x86_64__ && defined(HAVE_BETTER_YASM_ELF64)
-int ZlibCompressor::isal_compress(const bufferlist &in, bufferlist &out)
+int ZlibCompressor::isal_compress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> &compressor_message)
 {
   int ret;
   unsigned have;
@@ -120,6 +121,7 @@ int ZlibCompressor::isal_compress(const bufferlist &in, bufferlist &out)
   isal_deflate_init(&strm);
   strm.end_of_stream = 0;
 
+  compressor_message = ZLIB_DEFAULT_WIN_SIZE;
   for (ceph::bufferlist::buffers_t::const_iterator i = in.buffers().begin();
       i != in.buffers().end();) {
 
@@ -161,27 +163,27 @@ int ZlibCompressor::isal_compress(const bufferlist &in, bufferlist &out)
 }
 #endif
 
-int ZlibCompressor::compress(const bufferlist &in, bufferlist &out)
+int ZlibCompressor::compress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> &compressor_message)
 {
 #ifdef HAVE_QATZIP
   if (qat_enabled)
-    return qat_accel.compress(in, out);
+    return qat_accel.compress(in, out, compressor_message);
 #endif
 #if __x86_64__ && defined(HAVE_BETTER_YASM_ELF64)
   if (isal_enabled)
-    return isal_compress(in, out);
+    return isal_compress(in, out, compressor_message);
   else
-    return zlib_compress(in, out);
+    return zlib_compress(in, out, compressor_message);
 #else
-  return zlib_compress(in, out);
+  return zlib_compress(in, out, compressor_message);
 #endif
 }
 
-int ZlibCompressor::decompress(bufferlist::const_iterator &p, size_t compressed_size, bufferlist &out)
+int ZlibCompressor::decompress(bufferlist::const_iterator &p, size_t compressed_size, bufferlist &out, boost::optional<int32_t> compressor_message)
 {
 #ifdef HAVE_QATZIP
   if (qat_enabled)
-    return qat_accel.decompress(p, compressed_size, out);
+    return qat_accel.decompress(p, compressed_size, out, compressor_message);
 #endif
 
   int ret;
@@ -198,7 +200,9 @@ int ZlibCompressor::decompress(bufferlist::const_iterator &p, size_t compressed_
   strm.next_in = Z_NULL;
 
   // choose the variation of compressor
-  ret = inflateInit2(&strm, ZLIB_DEFAULT_WIN_SIZE);
+  if (!compressor_message)
+    compressor_message = ZLIB_DEFAULT_WIN_SIZE;
+  ret = inflateInit2(&strm, *compressor_message);
   if (ret != Z_OK) {
     dout(1) << "Decompression init error: init return "
          << ret << " instead of Z_OK" << dendl;
@@ -235,12 +239,12 @@ int ZlibCompressor::decompress(bufferlist::const_iterator &p, size_t compressed_
   return 0;
 }
 
-int ZlibCompressor::decompress(const bufferlist &in, bufferlist &out)
+int ZlibCompressor::decompress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> compressor_message)
 {
 #ifdef HAVE_QATZIP
   if (qat_enabled)
-    return qat_accel.decompress(in, out);
+    return qat_accel.decompress(in, out, compressor_message);
 #endif
   auto i = std::cbegin(in);
-  return decompress(i, in.length(), out);
+  return decompress(i, in.length(), out, compressor_message);
 }
diff --git a/src/compressor/zlib/ZlibCompressor.h b/src/compressor/zlib/ZlibCompressor.h
index d770547a94..5df5d6821f 100644
--- a/src/compressor/zlib/ZlibCompressor.h
+++ b/src/compressor/zlib/ZlibCompressor.h
@@ -34,12 +34,12 @@ public:
 #endif
   }
 
-  int compress(const bufferlist &in, bufferlist &out) override;
-  int decompress(const bufferlist &in, bufferlist &out) override;
-  int decompress(bufferlist::const_iterator &p, size_t compressed_len, bufferlist &out) override;
+  int compress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> &compressor_message) override;
+  int decompress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> compressor_message) override;
+  int decompress(bufferlist::const_iterator &p, size_t compressed_len, bufferlist &out, boost::optional<int32_t> compressor_message) override;
 private:
-  int zlib_compress(const bufferlist &in, bufferlist &out);
-  int isal_compress(const bufferlist &in, bufferlist &out);
+  int zlib_compress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> &compressor_message);
+  int isal_compress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> &compressor_message);
  };
 
 
diff --git a/src/compressor/zstd/ZstdCompressor.h b/src/compressor/zstd/ZstdCompressor.h
index 0b17c99ad1..ad76465a9d 100644
--- a/src/compressor/zstd/ZstdCompressor.h
+++ b/src/compressor/zstd/ZstdCompressor.h
@@ -28,7 +28,7 @@ class ZstdCompressor : public Compressor {
  public:
   ZstdCompressor() : Compressor(COMP_ALG_ZSTD, "zstd") {}
 
-  int compress(const bufferlist &src, bufferlist &dst) override {
+  int compress(const bufferlist &src, bufferlist &dst, boost::optional<int32_t> &compressor_message) override {
     ZSTD_CStream *s = ZSTD_createCStream();
     ZSTD_initCStream_srcSize(s, COMPRESSION_LEVEL, src.length());
     auto p = src.begin();
@@ -63,14 +63,15 @@ class ZstdCompressor : public Compressor {
     return 0;
   }
 
-  int decompress(const bufferlist &src, bufferlist &dst) override {
+  int decompress(const bufferlist &src, bufferlist &dst, boost::optional<int32_t> compressor_message) override {
     auto i = std::cbegin(src);
-    return decompress(i, src.length(), dst);
+    return decompress(i, src.length(), dst, compressor_message);
   }
 
   int decompress(bufferlist::const_iterator &p,
 		 size_t compressed_len,
-		 bufferlist &dst) override {
+		 bufferlist &dst,
+		 boost::optional<int32_t> compressor_message) override {
     if (compressed_len < 4) {
       return -1;
     }
diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc
index 253efb5a12..4f18a00d97 100644
--- a/src/os/bluestore/BlueStore.cc
+++ b/src/os/bluestore/BlueStore.cc
@@ -9413,7 +9413,7 @@ int BlueStore::_decompress(bufferlist& source, bufferlist* result)
     _set_compression_alert(false, alg_name);
     r = -EIO;
   } else {
-    r = cp->decompress(i, chdr.length, *result);
+    r = cp->decompress(i, chdr.length, *result, chdr.compressor_message);
     if (r < 0) {
       derr << __func__ << " decompression failed with exit code " << r << dendl;
       r = -EIO;
@@ -12519,7 +12519,8 @@ int BlueStore::_do_alloc_write(
 
       // FIXME: memory alignment here is bad
       bufferlist t;
-      int r = c->compress(wi.bl, t);
+      boost::optional<int32_t> compressor_message;
+      int r = c->compress(wi.bl, t, compressor_message);
       uint64_t want_len_raw = wi.blob_length * crr;
       uint64_t want_len = p2roundup(want_len_raw, min_alloc_size);
       bool rejected = false;
@@ -12531,6 +12532,7 @@ int BlueStore::_do_alloc_write(
 	bluestore_compression_header_t chdr;
 	chdr.type = c->get_type();
 	chdr.length = t.length();
+	chdr.compressor_message = compressor_message;
 	encode(chdr, wi.compressed_bl);
 	wi.compressed_bl.claim_append(t);
 
diff --git a/src/os/bluestore/bluestore_types.cc b/src/os/bluestore/bluestore_types.cc
index 4d7e14afd8..5c2f9b421d 100644
--- a/src/os/bluestore/bluestore_types.cc
+++ b/src/os/bluestore/bluestore_types.cc
@@ -1121,6 +1121,9 @@ void bluestore_compression_header_t::dump(Formatter *f) const
 {
   f->dump_unsigned("type", type);
   f->dump_unsigned("length", length);
+  if (compressor_message) {
+    f->dump_int("compressor_message", *compressor_message);
+  }
 }
 
 void bluestore_compression_header_t::generate_test_instances(
diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h
index f58a079c4a..b2b37b4d2b 100644
--- a/src/os/bluestore/bluestore_types.h
+++ b/src/os/bluestore/bluestore_types.h
@@ -1016,15 +1016,19 @@ WRITE_CLASS_DENC(bluestore_deferred_transaction_t)
 struct bluestore_compression_header_t {
   uint8_t type = Compressor::COMP_ALG_NONE;
   uint32_t length = 0;
+  boost::optional<int32_t> compressor_message;
 
   bluestore_compression_header_t() {}
   bluestore_compression_header_t(uint8_t _type)
     : type(_type) {}
 
   DENC(bluestore_compression_header_t, v, p) {
-    DENC_START(1, 1, p);
+    DENC_START(2, 1, p);
     denc(v.type, p);
     denc(v.length, p);
+    if (struct_v >= 2) {
+      denc(v.compressor_message, p);
+    }
     DENC_FINISH(p);
   }
   void dump(Formatter *f) const;
diff --git a/src/rgw/rgw_compression.cc b/src/rgw/rgw_compression.cc
index bcd7fbc27a..da26230e5e 100644
--- a/src/rgw/rgw_compression.cc
+++ b/src/rgw/rgw_compression.cc
@@ -15,7 +15,7 @@ int RGWPutObj_Compress::process(bufferlist&& in, uint64_t logical_offset)
     if ((logical_offset > 0 && compressed) || // if previous part was compressed
         (logical_offset == 0)) {              // or it's the first part
       ldout(cct, 10) << "Compression for rgw is enabled, compress part " << in.length() << dendl;
-      int cr = compressor->compress(in, out);
+      int cr = compressor->compress(in, out, compressor_message);
       if (cr < 0) {
         if (logical_offset > 0) {
           lderr(cct) << "Compression failed with exit code " << cr
@@ -96,7 +96,7 @@ int RGWGetObj_Decompress::handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len
       break;
     }
     in_bl.copy(ofs_in_bl, first_block->len, tmp);
-    int cr = compressor->decompress(tmp, out_bl);
+    int cr = compressor->decompress(tmp, out_bl, cs_info->compressor_message);
     if (cr < 0) {
       lderr(cct) << "Decompression failed with exit code " << cr << dendl;
       return cr;
diff --git a/src/rgw/rgw_compression.h b/src/rgw/rgw_compression.h
index e0448044ce..949b455fe0 100644
--- a/src/rgw/rgw_compression.h
+++ b/src/rgw/rgw_compression.h
@@ -37,6 +37,7 @@ class RGWPutObj_Compress : public rgw::putobj::Pipe
   CephContext* cct;
   bool compressed{false};
   CompressorRef compressor;
+  boost::optional<int32_t> compressor_message;
   std::vector<compression_block> blocks;
 public:
   RGWPutObj_Compress(CephContext* cct_, CompressorRef compressor,
@@ -47,6 +48,7 @@ public:
 
   bool is_compressed() { return compressed; }
   vector<compression_block>& get_compression_blocks() { return blocks; }
+  boost::optional<int32_t> get_compressor_message() { return compressor_message; }
 
 }; /* RGWPutObj_Compress */
 
diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc
index b9a2ed26bf..4ef1abe9d1 100644
--- a/src/rgw/rgw_json_enc.cc
+++ b/src/rgw/rgw_json_enc.cc
@@ -1751,5 +1751,8 @@ void RGWCompressionInfo::dump(Formatter *f) const
 {
   f->dump_string("compression_type", compression_type);
   f->dump_unsigned("orig_size", orig_size);
+  if (compressor_message) {
+    f->dump_int("compressor_message", *compressor_message);
+  }
   ::encode_json("blocks", blocks, f);
 }
diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc
index 0005c9ee30..8a37618b33 100644
--- a/src/rgw/rgw_op.cc
+++ b/src/rgw/rgw_op.cc
@@ -3876,6 +3876,7 @@ void RGWPutObj::execute()
     RGWCompressionInfo cs_info;
     cs_info.compression_type = plugin->get_type_name();
     cs_info.orig_size = s->obj_size;
+    cs_info.compressor_message = compressor->get_compressor_message();
     cs_info.blocks = move(compressor->get_compression_blocks());
     encode(cs_info, tmp);
     attrs[RGW_ATTR_COMPRESSION] = tmp;
@@ -4188,6 +4189,7 @@ void RGWPostObj::execute()
       RGWCompressionInfo cs_info;
       cs_info.compression_type = plugin->get_type_name();
       cs_info.orig_size = s->obj_size;
+      cs_info.compressor_message = compressor->get_compressor_message();
       cs_info.blocks = move(compressor->get_compression_blocks());
       encode(cs_info, tmp);
       emplace_attr(RGW_ATTR_COMPRESSION, std::move(tmp));
@@ -7061,6 +7063,7 @@ int RGWBulkUploadOp::handle_file(const boost::string_ref path,
     RGWCompressionInfo cs_info;
     cs_info.compression_type = plugin->get_type_name();
     cs_info.orig_size = s->obj_size;
+    cs_info.compressor_message = compressor->get_compressor_message();
     cs_info.blocks = std::move(compressor->get_compression_blocks());
     encode(cs_info, tmp);
     attrs.emplace(RGW_ATTR_COMPRESSION, std::move(tmp));
diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc
index 19a83da62f..f8200532f8 100644
--- a/src/rgw/rgw_rados.cc
+++ b/src/rgw/rgw_rados.cc
@@ -4407,6 +4407,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
     RGWCompressionInfo cs_info;
     cs_info.compression_type = plugin->get_type_name();
     cs_info.orig_size = cb.get_data_len();
+    cs_info.compressor_message = compressor->get_compressor_message();
     cs_info.blocks = move(compressor->get_compression_blocks());
     encode(cs_info, tmp);
     cb.get_attrs()[RGW_ATTR_COMPRESSION] = tmp;
diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h
index deb8b55328..1d763aa2bd 100644
--- a/src/rgw/rgw_rados.h
+++ b/src/rgw/rgw_rados.h
@@ -212,25 +212,31 @@ WRITE_CLASS_ENCODER(compression_block)
 struct RGWCompressionInfo {
   string compression_type;
   uint64_t orig_size;
+  boost::optional<int32_t> compressor_message;
   vector<compression_block> blocks;
 
   RGWCompressionInfo() : compression_type("none"), orig_size(0) {}
   RGWCompressionInfo(const RGWCompressionInfo& cs_info) : compression_type(cs_info.compression_type),
                                                           orig_size(cs_info.orig_size),
+							  compressor_message(cs_info.compressor_message),
                                                           blocks(cs_info.blocks) {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
+    ENCODE_START(2, 1, bl);
     encode(compression_type, bl);
     encode(orig_size, bl);
+    encode(compressor_message, bl);
     encode(blocks, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::const_iterator& bl) {
-     DECODE_START(1, bl);
+     DECODE_START(2, bl);
      decode(compression_type, bl);
      decode(orig_size, bl);
+     if (struct_v >= 2) {
+       decode(compressor_message, bl);
+     }
      decode(blocks, bl);
      DECODE_FINISH(bl);
   } 
diff --git a/src/test/compressor/compressor_example.h b/src/test/compressor/compressor_example.h
index a2dbd8f660..3afd59a7d2 100644
--- a/src/test/compressor/compressor_example.h
+++ b/src/test/compressor/compressor_example.h
@@ -32,18 +32,18 @@ public:
   CompressorExample() : Compressor(COMP_ALG_NONE, "example") {}
   ~CompressorExample() override {}
 
-  int compress(const bufferlist &in, bufferlist &out) override
+  int compress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> &compressor_message) override
   {
     out = in;
     return 0;
   }
 
-  int decompress(const bufferlist &in, bufferlist &out) override
+  int decompress(const bufferlist &in, bufferlist &out, boost::optional<int32_t> compressor_message) override
   {
     out = in;
     return 0;
   }
-  int decompress(bufferlist::const_iterator &p, size_t compressed_len, bufferlist &out) override
+  int decompress(bufferlist::const_iterator &p, size_t compressed_len, bufferlist &out, boost::optional<int32_t> compressor_message) override
   {
     p.copy(std::min<size_t>(p.get_remaining(), compressed_len), out);
     return 0;
diff --git a/src/test/compressor/test_compression.cc b/src/test/compressor/test_compression.cc
index 102ab56153..50921a49db 100644
--- a/src/test/compressor/test_compression.cc
+++ b/src/test/compressor/test_compression.cc
@@ -76,10 +76,11 @@ TEST_P(CompressorTest, small_round_trip)
   bufferlist orig;
   orig.append("This is a short string.  There are many strings like it but this one is mine.");
   bufferlist compressed;
-  int r = compressor->compress(orig, compressed);
+  boost::optional<int32_t> compressor_message;
+  int r = compressor->compress(orig, compressed, compressor_message);
   ASSERT_EQ(0, r);
   bufferlist decompressed;
-  r = compressor->decompress(compressed, decompressed);
+  r = compressor->decompress(compressed, decompressed, compressor_message);
   ASSERT_EQ(0, r);
   ASSERT_EQ(decompressed.length(), orig.length());
   ASSERT_TRUE(decompressed.contents_equal(orig));
@@ -95,10 +96,11 @@ TEST_P(CompressorTest, big_round_trip_repeated)
     orig.append("This is a short string.  There are many strings like it but this one is mine.");
   }
   bufferlist compressed;
-  int r = compressor->compress(orig, compressed);
+  boost::optional<int32_t> compressor_message;
+  int r = compressor->compress(orig, compressed, compressor_message);
   ASSERT_EQ(0, r);
   bufferlist decompressed;
-  r = compressor->decompress(compressed, decompressed);
+  r = compressor->decompress(compressed, decompressed, compressor_message);
   ASSERT_EQ(0, r);
   ASSERT_EQ(decompressed.length(), orig.length());
   ASSERT_TRUE(decompressed.contents_equal(orig));
@@ -124,10 +126,11 @@ TEST_P(CompressorTest, big_round_trip_randomish)
     orig.append(bp);
   }
   bufferlist compressed;
-  int r = compressor->compress(orig, compressed);
+  boost::optional<int32_t> compressor_message;
+  int r = compressor->compress(orig, compressed, compressor_message);
   ASSERT_EQ(0, r);
   bufferlist decompressed;
-  r = compressor->decompress(compressed, decompressed);
+  r = compressor->decompress(compressed, decompressed, compressor_message);
   ASSERT_EQ(0, r);
   ASSERT_EQ(decompressed.length(), orig.length());
   ASSERT_TRUE(decompressed.contents_equal(orig));
@@ -167,9 +170,10 @@ TEST_P(CompressorTest, compress_decompress)
   bufferlist after;
   bufferlist exp;
   in.append(test, len);
-  res = compressor->compress(in, out);
+  boost::optional<int32_t> compressor_message;
+  res = compressor->compress(in, out, compressor_message);
   EXPECT_EQ(res, 0);
-  res = compressor->decompress(out, after);
+  res = compressor->decompress(out, after, compressor_message);
   EXPECT_EQ(res, 0);
   exp.append(test);
   EXPECT_TRUE(exp.contents_equal(after));
@@ -177,7 +181,7 @@ TEST_P(CompressorTest, compress_decompress)
   size_t compressed_len = out.length();
   out.append_zero(12);
   auto it = out.cbegin();
-  res = compressor->decompress(it, compressed_len, after);
+  res = compressor->decompress(it, compressed_len, after, compressor_message);
   EXPECT_EQ(res, 0);
   EXPECT_TRUE(exp.contents_equal(after));
 
@@ -190,7 +194,7 @@ TEST_P(CompressorTest, compress_decompress)
   out.clear();
   in.append(data);
   exp = in;
-  res = compressor->compress(in, out);
+  res = compressor->compress(in, out, compressor_message);
   EXPECT_EQ(res, 0);
   compressed_len = out.length();
   out.append_zero(0x10000 - out.length());
@@ -203,7 +207,7 @@ TEST_P(CompressorTest, compress_decompress)
   out.swap(prefix);
   it = out.cbegin();
   it.advance(prefix_len);
-  res = compressor->decompress(it, compressed_len, after);
+  res = compressor->decompress(it, compressed_len, after, compressor_message);
   EXPECT_EQ(res, 0);
   EXPECT_TRUE(exp.contents_equal(after));
 }
@@ -216,7 +220,8 @@ TEST_P(CompressorTest, sharded_input_decompress)
   int len = test.size();
   bufferlist in, out;
   in.append(test.c_str(), len);
-  int res = compressor->compress(in, out);
+  boost::optional<int32_t> compressor_message;
+  int res = compressor->compress(in, out, compressor_message);
   EXPECT_EQ(res, 0);
   EXPECT_GT(out.length(), small_prefix_size);
 
@@ -234,7 +239,7 @@ TEST_P(CompressorTest, sharded_input_decompress)
   }
 
   bufferlist after;
-  res = compressor->decompress(out2, after);
+  res = compressor->decompress(out2, after, compressor_message);
   EXPECT_EQ(res, 0);
 }
 
@@ -248,7 +253,8 @@ void test_compress(CompressorRef compressor, size_t size)
   in.append(data, size);
   for (size_t t = 0; t < 10000; t++) {
     bufferlist out;
-    int res = compressor->compress(in, out);
+    boost::optional<int32_t> compressor_message;
+    int res = compressor->compress(in, out, compressor_message);
     EXPECT_EQ(res, 0);
   }
   free(data);
@@ -262,11 +268,12 @@ void test_decompress(CompressorRef compressor, size_t size)
   }
   bufferlist in, out;
   in.append(data, size);
-  int res = compressor->compress(in, out);
+  boost::optional<int32_t> compressor_message;
+  int res = compressor->compress(in, out, compressor_message);
   EXPECT_EQ(res, 0);
   for (size_t t = 0; t < 10000; t++) {
     bufferlist out_dec;
-    int res = compressor->decompress(out, out_dec);
+    int res = compressor->decompress(out, out_dec, compressor_message);
     EXPECT_EQ(res, 0);
   }
   free(data);
@@ -363,10 +370,11 @@ TEST(ZlibCompressor, zlib_isal_compatibility)
   bufferlist in, out;
   in.append(test, len);
   // isal -> zlib
-  int res = isal->compress(in, out);
+  boost::optional<int32_t> compressor_message;
+  int res = isal->compress(in, out, compressor_message);
   EXPECT_EQ(res, 0);
   bufferlist after;
-  res = zlib->decompress(out, after);
+  res = zlib->decompress(out, after, compressor_message);
   EXPECT_EQ(res, 0);
   bufferlist exp;
   exp.append(static_cast<char*>(test));
@@ -375,9 +383,9 @@ TEST(ZlibCompressor, zlib_isal_compatibility)
   out.clear();
   exp.clear();
   // zlib -> isal
-  res = zlib->compress(in, out);
+  res = zlib->compress(in, out, compressor_message);
   EXPECT_EQ(res, 0);
-  res = isal->decompress(out, after);
+  res = isal->decompress(out, after, compressor_message);
   EXPECT_EQ(res, 0);
   exp.append(static_cast<char*>(test));
   EXPECT_TRUE(exp.contents_equal(after));
@@ -431,10 +439,11 @@ TEST(ZlibCompressor, isal_compress_zlib_decompress_random)
     bufferlist in, out;
     in.append(test, size);
 
-    int res = isal->compress(in, out);
+    boost::optional<int32_t> compressor_message;
+    int res = isal->compress(in, out, compressor_message);
     EXPECT_EQ(res, 0);
     bufferlist after;
-    res = zlib->decompress(out, after);
+    res = zlib->decompress(out, after, compressor_message);
     EXPECT_EQ(res, 0);
     bufferlist exp;
     exp.append(test, size);
@@ -470,10 +479,11 @@ TEST(ZlibCompressor, isal_compress_zlib_decompress_walk)
     bufferlist in, out;
     in.append(test, size);
 
-    int res = isal->compress(in, out);
+    boost::optional<int32_t> compressor_message;
+    int res = isal->compress(in, out, compressor_message);
     EXPECT_EQ(res, 0);
     bufferlist after;
-    res = zlib->decompress(out, after);
+    res = zlib->decompress(out, after, compressor_message);
     EXPECT_EQ(res, 0);
     bufferlist exp;
     exp.append(test, size);
@@ -508,10 +518,11 @@ TEST(QAT, enc_qat_dec_noqat) {
       bufferlist in, out;
       in.append(test, size);
   
-      int res = q->compress(in, out);
+      boost::optional<int32_t> compressor_message;
+      int res = q->compress(in, out, compressor_message);
       EXPECT_EQ(res, 0);
       bufferlist after;
-      res = noq->decompress(out, after);
+      res = noq->decompress(out, after, compressor_message);
       EXPECT_EQ(res, 0);
       bufferlist exp;
       exp.append(test, size);
@@ -544,10 +555,11 @@ TEST(QAT, enc_noqat_dec_qat) {
       bufferlist in, out;
       in.append(test, size);
   
-      int res = noq->compress(in, out);
+      boost::optional<int32_t> compressor_message;
+      int res = noq->compress(in, out, compressor_message);
       EXPECT_EQ(res, 0);
       bufferlist after;
-      res = q->decompress(out, after);
+      res = q->decompress(out, after, compressor_message);
       EXPECT_EQ(res, 0);
       bufferlist exp;
       exp.append(test, size);
diff --git a/src/test/rgw/test_rgw_compression.cc b/src/test/rgw/test_rgw_compression.cc
index 936b8f7c97..b1e3403281 100644
--- a/src/test/rgw/test_rgw_compression.cc
+++ b/src/test/rgw/test_rgw_compression.cc
@@ -129,6 +129,7 @@ TEST(Compress, LimitedChunkSize)
     RGWCompressionInfo cs_info;
     cs_info.compression_type = plugin->get_type_name();
     cs_info.orig_size = s;
+    cs_info.compressor_message = compressor.get_compressor_message();
     cs_info.blocks = move(compressor.get_compression_blocks());
 
     ut_get_sink_size d_sink;
@@ -167,6 +168,7 @@ TEST(Compress, BillionZeros)
   RGWCompressionInfo cs_info;
   cs_info.compression_type = plugin->get_type_name();
   cs_info.orig_size = size*1000;
+  cs_info.compressor_message = compressor.get_compressor_message();
   cs_info.blocks = move(compressor.get_compression_blocks());
 
   ut_get_sink d_sink;
-- 
2.17.1

