From: Sage Weil Date: Thu, 6 Oct 2016 15:36:33 +0000 (-0400) Subject: compressor/snappy: fix decompress buffer sizing for large buffers X-Git-Tag: v11.1.0~704^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=06ae3da85fa6f3c14dd149030c274fc42c166c78;p=ceph.git compressor/snappy: fix decompress buffer sizing for large buffers 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 --- diff --git a/src/compressor/snappy/SnappyCompressor.h b/src/compressor/snappy/SnappyCompressor.h index 38a345a1f27a..f842fc9c526a 100644 --- a/src/compressor/snappy/SnappyCompressor.h +++ b/src/compressor/snappy/SnappyCompressor.h @@ -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; } };