libsnapshot: Refactor compress function
Move compress() function to a dedicated file.
This is in preparation for variable block size
compression and async writes.
No change in functional logic.
Bug: 254188450
Test: Full OTA Pixel
Signed-off-by: Akilesh Kailash <akailash@google.com>
Change-Id: I7681e9a4d884eac1ccbf8adeb1fc6bd1a9fedfa6
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index a47a24c..474d482 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -177,6 +177,7 @@
"libsnapshot_cow/cow_reader.cpp",
"libsnapshot_cow/cow_writer.cpp",
"libsnapshot_cow/cow_format.cpp",
+ "libsnapshot_cow/cow_compress.cpp",
],
host_supported: true,
recovery_available: true,
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_compress.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_compress.cpp
new file mode 100644
index 0000000..e58f45a
--- /dev/null
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_compress.cpp
@@ -0,0 +1,98 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <limits>
+#include <queue>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <brotli/encode.h>
+#include <libsnapshot/cow_format.h>
+#include <libsnapshot/cow_reader.h>
+#include <libsnapshot/cow_writer.h>
+#include <lz4.h>
+#include <zlib.h>
+
+namespace android {
+namespace snapshot {
+
+std::basic_string<uint8_t> CowWriter::Compress(const void* data, size_t length) {
+ switch (compression_) {
+ case kCowCompressGz: {
+ const auto bound = compressBound(length);
+ std::basic_string<uint8_t> buffer(bound, '\0');
+
+ uLongf dest_len = bound;
+ auto rv = compress2(buffer.data(), &dest_len, reinterpret_cast<const Bytef*>(data),
+ length, Z_BEST_COMPRESSION);
+ if (rv != Z_OK) {
+ LOG(ERROR) << "compress2 returned: " << rv;
+ return {};
+ }
+ buffer.resize(dest_len);
+ return buffer;
+ }
+ case kCowCompressBrotli: {
+ const auto bound = BrotliEncoderMaxCompressedSize(length);
+ if (!bound) {
+ LOG(ERROR) << "BrotliEncoderMaxCompressedSize returned 0";
+ return {};
+ }
+ std::basic_string<uint8_t> buffer(bound, '\0');
+
+ size_t encoded_size = bound;
+ auto rv = BrotliEncoderCompress(
+ BROTLI_DEFAULT_QUALITY, BROTLI_DEFAULT_WINDOW, BROTLI_DEFAULT_MODE, length,
+ reinterpret_cast<const uint8_t*>(data), &encoded_size, buffer.data());
+ if (!rv) {
+ LOG(ERROR) << "BrotliEncoderCompress failed";
+ return {};
+ }
+ buffer.resize(encoded_size);
+ return buffer;
+ }
+ case kCowCompressLz4: {
+ const auto bound = LZ4_compressBound(length);
+ if (!bound) {
+ LOG(ERROR) << "LZ4_compressBound returned 0";
+ return {};
+ }
+ std::basic_string<uint8_t> buffer(bound, '\0');
+
+ const auto compressed_size = LZ4_compress_default(
+ static_cast<const char*>(data), reinterpret_cast<char*>(buffer.data()), length,
+ buffer.size());
+ if (compressed_size <= 0) {
+ LOG(ERROR) << "LZ4_compress_default failed, input size: " << length
+ << ", compression bound: " << bound << ", ret: " << compressed_size;
+ return {};
+ }
+ buffer.resize(compressed_size);
+ return buffer;
+ }
+ default:
+ LOG(ERROR) << "unhandled compression type: " << compression_;
+ break;
+ }
+ return {};
+}
+
+} // namespace snapshot
+} // namespace android
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp
index 7281fc2..e4f019e 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp
@@ -404,67 +404,6 @@
return true;
}
-std::basic_string<uint8_t> CowWriter::Compress(const void* data, size_t length) {
- switch (compression_) {
- case kCowCompressGz: {
- const auto bound = compressBound(length);
- std::basic_string<uint8_t> buffer(bound, '\0');
-
- uLongf dest_len = bound;
- auto rv = compress2(buffer.data(), &dest_len, reinterpret_cast<const Bytef*>(data),
- length, Z_BEST_COMPRESSION);
- if (rv != Z_OK) {
- LOG(ERROR) << "compress2 returned: " << rv;
- return {};
- }
- buffer.resize(dest_len);
- return buffer;
- }
- case kCowCompressBrotli: {
- const auto bound = BrotliEncoderMaxCompressedSize(length);
- if (!bound) {
- LOG(ERROR) << "BrotliEncoderMaxCompressedSize returned 0";
- return {};
- }
- std::basic_string<uint8_t> buffer(bound, '\0');
-
- size_t encoded_size = bound;
- auto rv = BrotliEncoderCompress(
- BROTLI_DEFAULT_QUALITY, BROTLI_DEFAULT_WINDOW, BROTLI_DEFAULT_MODE, length,
- reinterpret_cast<const uint8_t*>(data), &encoded_size, buffer.data());
- if (!rv) {
- LOG(ERROR) << "BrotliEncoderCompress failed";
- return {};
- }
- buffer.resize(encoded_size);
- return buffer;
- }
- case kCowCompressLz4: {
- const auto bound = LZ4_compressBound(length);
- if (!bound) {
- LOG(ERROR) << "LZ4_compressBound returned 0";
- return {};
- }
- std::basic_string<uint8_t> buffer(bound, '\0');
-
- const auto compressed_size = LZ4_compress_default(
- static_cast<const char*>(data), reinterpret_cast<char*>(buffer.data()), length,
- buffer.size());
- if (compressed_size <= 0) {
- LOG(ERROR) << "LZ4_compress_default failed, input size: " << length
- << ", compression bound: " << bound << ", ret: " << compressed_size;
- return {};
- }
- buffer.resize(compressed_size);
- return buffer;
- }
- default:
- LOG(ERROR) << "unhandled compression type: " << compression_;
- break;
- }
- return {};
-}
-
// TODO: Fix compilation issues when linking libcrypto library
// when snapuserd is compiled as part of ramdisk.
static void SHA256(const void*, size_t, uint8_t[]) {