[blobfs] WIP Switch to chunked compression

WIP change, not intended to be landed.

Change-Id: I116705fa3c5a2fec46a9f5342e954aa6fa95ed60
diff --git a/zircon/system/ulib/blobfs/BUILD.gn b/zircon/system/ulib/blobfs/BUILD.gn
index 6eb5843..5ddd61f 100644
--- a/zircon/system/ulib/blobfs/BUILD.gn
+++ b/zircon/system/ulib/blobfs/BUILD.gn
@@ -75,6 +75,9 @@
     "common.cc",
     "compression-algorithm.cc",
     "compression/chunked.cc",
+    "compression/chunked.h",
+    "compression/compressor.h",
+    "compression/compressor.h",
     "compression/decompressor.cc",
     "compression/lz4.cc",
     "compression/zstd-plain.cc",
@@ -133,6 +136,7 @@
       "blobfs.cc",
       "cache-node.cc",
       "compression/blob-compressor.cc",
+      "compression/blob-compressor.h",
       "compression/zstd-compressed-block-collection.cc",
       "compression/zstd-seekable-blob-collection.cc",
       "compression/zstd-seekable-blob.cc",
diff --git a/zircon/system/ulib/blobfs/compression/chunked.cc b/zircon/system/ulib/blobfs/compression/chunked.cc
index dc3ead8d..70ab807 100644
--- a/zircon/system/ulib/blobfs/compression/chunked.cc
+++ b/zircon/system/ulib/blobfs/compression/chunked.cc
@@ -5,7 +5,6 @@
 #include "chunked.h"
 
 #include <zircon/errors.h>
-#include <zircon/status.h>
 #include <zircon/types.h>
 
 #include <fs/trace.h>
@@ -47,6 +46,13 @@
   return ZX_OK;
 }
 
+size_t ChunkedCompressor::BufferMax(size_t input_length) {
+  chunked_compression::CompressionParams params;
+  params.compression_level = kDefaultLevel;
+  params.chunk_size = chunked_compression::CompressionParams::ChunkSizeForInputSize(input_length);
+  return params.ComputeOutputSizeLimit(input_length);
+}
+
 zx_status_t ChunkedCompressor::SetOutput(void* dst, size_t dst_len) {
   if (dst_len < compressor_.ComputeOutputSizeLimit(input_len_)) {
     return ZX_ERR_BUFFER_TOO_SMALL;
@@ -152,8 +158,7 @@
         decompressor_.DecompressFrame(seek_table_, i, src, max_compressed_size - src_offset, dst,
                                       *uncompressed_size - dst_offset, &bytes_in_frame);
     if (status != chunked_compression::kStatusOk) {
-      FS_TRACE_ERROR("blobfs DecompressFrame failed: %s\n",
-                     zx_status_get_string(ToZxStatus(status)));
+      FS_TRACE_ERROR("blobfs DecompressFrame failed: %d\n", status);
       return ToZxStatus(status);
     }
     src_offset += entry.compressed_size;
diff --git a/zircon/system/ulib/blobfs/compression/chunked.h b/zircon/system/ulib/blobfs/compression/chunked.h
index 36fc041..e77debb 100644
--- a/zircon/system/ulib/blobfs/compression/chunked.h
+++ b/zircon/system/ulib/blobfs/compression/chunked.h
@@ -34,6 +34,10 @@
   static zx_status_t Create(size_t input_size, size_t* output_limit_out,
                             std::unique_ptr<ChunkedCompressor>* out);
 
+  // Returns the maximum possible size a buffer would need to be
+  // in order to compress data of size |input_length|.
+  static size_t BufferMax(size_t input_length);
+
   // Registers |dst| as the output for compression.
   // Must be called before |Update()| or |End()| are called.
   zx_status_t SetOutput(void* dst, size_t dst_len);
diff --git a/zircon/system/ulib/blobfs/host.cc b/zircon/system/ulib/blobfs/host.cc
index f0d98eb..d640fb1 100644
--- a/zircon/system/ulib/blobfs/host.cc
+++ b/zircon/system/ulib/blobfs/host.cc
@@ -30,9 +30,9 @@
 #include <fs/trace.h>
 #include <safemath/checked_math.h>
 
+#include "compression/chunked.h"
 #include "compression/compressor.h"
 #include "compression/decompressor.h"
-#include "compression/zstd-seekable.h"
 
 using digest::Digest;
 using digest::MerkleTreeCreator;
@@ -46,8 +46,8 @@
 // TODO(markdittmer): Abstract choice of host compressor, decompressor and metadata flag to support
 // choosing from multiple strategies. This has already been done in non-host code but host tools do
 // not use |BlobCompressor| the same way.
-using HostCompressor = ZSTDSeekableCompressor;
-using HostDecompressor = ZSTDSeekableDecompressor;
+using HostCompressor = ChunkedCompressor;
+using HostDecompressor = ChunkedDecompressor;
 
 zx_status_t ReadBlockOffset(int fd, uint64_t bno, off_t offset, void* data) {
   off_t off = offset + bno * kBlobfsBlockSize;
@@ -95,11 +95,16 @@
 
   zx_status_t status;
   std::unique_ptr<HostCompressor> compressor;
-  if ((status = HostCompressor::Create(mapping.length(), out_info->compressed_data.get(), max,
+  size_t output_limit;
+  if ((status = HostCompressor::Create(mapping.length(), &output_limit,
                                        &compressor)) != ZX_OK) {
     FS_TRACE_ERROR("Failed to initialize blobfs compressor: %d\n", status);
     return status;
   }
+  if ((status = compressor->SetOutput(out_info->compressed_data.get(), max)) != ZX_OK) {
+    FS_TRACE_ERROR("Failed to initialize blobfs compressor: %d\n", status);
+    return status;
+  }
 
   if ((status = compressor->Update(mapping.data(), mapping.length())) != ZX_OK) {
     FS_TRACE_ERROR("Failed to update blobfs compressor: %d\n", status);
diff --git a/zircon/system/ulib/blobfs/include/blobfs/mount.h b/zircon/system/ulib/blobfs/include/blobfs/mount.h
index 83185ff..10e2e24 100644
--- a/zircon/system/ulib/blobfs/include/blobfs/mount.h
+++ b/zircon/system/ulib/blobfs/include/blobfs/mount.h
@@ -51,7 +51,7 @@
   // Compression algorithm to use when storing blobs.
   // Blobs that are already stored on disk using another compression algorithm from disk are not
   // affected by this flag.
-  CompressionAlgorithm write_compression_algorithm = CompressionAlgorithm::ZSTD_SEEKABLE;
+  CompressionAlgorithm write_compression_algorithm = CompressionAlgorithm::CHUNKED;
 };
 
 // Begins serving requests to the filesystem by parsing the on-disk format using |device|. If