]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
compressor/snappy: fix decompress buffer sizing for large buffers
authorSage Weil <sage@redhat.com>
Thu, 6 Oct 2016 15:36:33 +0000 (11:36 -0400)
committerSage Weil <sage@redhat.com>
Thu, 6 Oct 2016 19:36:07 +0000 (15:36 -0400)
4 bytes is enough for small buffers, but fails for larger buffers because
snappy encodes the length as a varint.  8 is enough.

Signed-off-by: Sage Weil <sage@redhat.com>
src/compressor/snappy/SnappyCompressor.h

index 38a345a1f27a5697137d5421f2bc9ee7fa3ce017..f842fc9c526aadf854143b7e9859af9cc74faabf 100644 (file)
@@ -77,10 +77,15 @@ class SnappyCompressor : public Compressor {
                 size_t compressed_len,
                 bufferlist &dst) override {
     size_t res_len = 0;
-    // Trick, decompress only need first 32bits buffer
+    // Trick, decompress only need first few bytes of buffer.  note
+    // that 4 bytes is *not* enough.. it works for small buffers (a
+    // few MB), but not large ones (~260 MB), because the 32-bit value
+    // is encoded as a varint.  From snappy.cc:
+    //     if (Varint::Parse32WithLimit(start, limit, &v) != NULL) {
+    // 8 bytes is enough.
     bufferlist::const_iterator ptmp = p;
     bufferlist tmp;
-    ptmp.copy(4, tmp);
+    ptmp.copy(std::min(8lu, compressed_len), tmp);
     if (!snappy::GetUncompressedLength(tmp.c_str(), tmp.length(), &res_len)) {
       return -1;
     }
@@ -91,7 +96,7 @@ class SnappyCompressor : public Compressor {
       dst.append(ptr);
       return 0;
     }
-    return -1;
+    return -2;
   }
 };