Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ad06ccf authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Support ZSTD in userspace COW" am: 9f6e8856 am: 16ee1caa

parents da41d6ab 16ee1caa
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -196,6 +196,7 @@ cc_binary {
        "libfastbootshim",
        "libfastbootshim",
        "libsnapshot_cow",
        "libsnapshot_cow",
        "liblz4",
        "liblz4",
        "libzstd",
        "libsnapshot_nobinder",
        "libsnapshot_nobinder",
        "update_metadata-protos",
        "update_metadata-protos",
        "liburing",
        "liburing",
+1 −0
Original line number Original line Diff line number Diff line
@@ -163,6 +163,7 @@ cc_defaults {
        "libbrotli",
        "libbrotli",
        "libz",
        "libz",
        "liblz4",
        "liblz4",
        "libzstd",
    ],
    ],
    export_include_dirs: ["include"],
    export_include_dirs: ["include"],
}
}
+2 −1
Original line number Original line Diff line number Diff line
@@ -157,7 +157,8 @@ enum CowCompressionAlgorithm : uint8_t {
    kCowCompressNone = 0,
    kCowCompressNone = 0,
    kCowCompressGz = 1,
    kCowCompressGz = 1,
    kCowCompressBrotli = 2,
    kCowCompressBrotli = 2,
    kCowCompressLz4 = 3
    kCowCompressLz4 = 3,
    kCowCompressZstd = 4,
};
};


static constexpr uint8_t kCowReadAheadNotStarted = 0;
static constexpr uint8_t kCowReadAheadNotStarted = 0;
+20 −0
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@
#include <libsnapshot/cow_writer.h>
#include <libsnapshot/cow_writer.h>
#include <lz4.h>
#include <lz4.h>
#include <zlib.h>
#include <zlib.h>
#include <zstd.h>


namespace android {
namespace android {
namespace snapshot {
namespace snapshot {
@@ -40,6 +41,8 @@ std::optional<CowCompressionAlgorithm> CompressionAlgorithmFromString(std::strin
        return {kCowCompressBrotli};
        return {kCowCompressBrotli};
    } else if (name == "lz4") {
    } else if (name == "lz4") {
        return {kCowCompressLz4};
        return {kCowCompressLz4};
    } else if (name == "zstd") {
        return {kCowCompressZstd};
    } else if (name == "none" || name.empty()) {
    } else if (name == "none" || name.empty()) {
        return {kCowCompressNone};
        return {kCowCompressNone};
    } else {
    } else {
@@ -112,6 +115,23 @@ std::basic_string<uint8_t> CompressWorker::Compress(CowCompressionAlgorithm comp
            }
            }
            return buffer;
            return buffer;
        }
        }
        case kCowCompressZstd: {
            std::basic_string<uint8_t> buffer(ZSTD_compressBound(length), '\0');
            const auto compressed_size =
                    ZSTD_compress(buffer.data(), buffer.size(), data, length, 0);
            if (compressed_size <= 0) {
                LOG(ERROR) << "ZSTD compression failed " << compressed_size;
                return {};
            }
            // Don't run compression if the compressed output is larger
            if (compressed_size >= length) {
                buffer.resize(length);
                memcpy(buffer.data(), data, length);
            } else {
                buffer.resize(compressed_size);
            }
            return buffer;
        }
        default:
        default:
            LOG(ERROR) << "unhandled compression type: " << compression;
            LOG(ERROR) << "unhandled compression type: " << compression;
            break;
            break;
+50 −0
Original line number Original line Diff line number Diff line
@@ -17,12 +17,15 @@
#include "cow_decompress.h"
#include "cow_decompress.h"


#include <array>
#include <array>
#include <cstring>
#include <utility>
#include <utility>
#include <vector>


#include <android-base/logging.h>
#include <android-base/logging.h>
#include <brotli/decode.h>
#include <brotli/decode.h>
#include <lz4.h>
#include <lz4.h>
#include <zlib.h>
#include <zlib.h>
#include <zstd.h>


namespace android {
namespace android {
namespace snapshot {
namespace snapshot {
@@ -336,9 +339,56 @@ class Lz4Decompressor final : public IDecompressor {
    }
    }
};
};


class ZstdDecompressor final : public IDecompressor {
  public:
    ssize_t Decompress(void* buffer, size_t buffer_size, size_t decompressed_size,
                       size_t ignore_bytes = 0) override {
        if (buffer_size < decompressed_size - ignore_bytes) {
            LOG(INFO) << "buffer size " << buffer_size
                      << " is not large enough to hold decompressed data. Decompressed size "
                      << decompressed_size << ", ignore_bytes " << ignore_bytes;
            return -1;
        }
        if (ignore_bytes == 0) {
            if (!Decompress(buffer, decompressed_size)) {
                return -1;
            }
            return decompressed_size;
        }
        std::vector<unsigned char> ignore_buf(decompressed_size);
        if (!Decompress(buffer, decompressed_size)) {
            return -1;
        }
        memcpy(buffer, ignore_buf.data() + ignore_bytes, buffer_size);
        return decompressed_size;
    }
    bool Decompress(void* output_buffer, const size_t output_size) {
        std::string input_buffer;
        input_buffer.resize(stream_->Size());
        size_t bytes_read = stream_->Read(input_buffer.data(), input_buffer.size());
        if (bytes_read != input_buffer.size()) {
            LOG(ERROR) << "Failed to read all input at once. Expected: " << input_buffer.size()
                       << " actual: " << bytes_read;
            return false;
        }
        const auto bytes_decompressed = ZSTD_decompress(output_buffer, output_size,
                                                        input_buffer.data(), input_buffer.size());
        if (bytes_decompressed != output_size) {
            LOG(ERROR) << "Failed to decompress ZSTD block, expected output size: " << output_size
                       << ", actual: " << bytes_decompressed;
            return false;
        }
        return true;
    }
};

std::unique_ptr<IDecompressor> IDecompressor::Lz4() {
std::unique_ptr<IDecompressor> IDecompressor::Lz4() {
    return std::make_unique<Lz4Decompressor>();
    return std::make_unique<Lz4Decompressor>();
}
}


std::unique_ptr<IDecompressor> IDecompressor::Zstd() {
    return std::make_unique<ZstdDecompressor>();
}

}  // namespace snapshot
}  // namespace snapshot
}  // namespace android
}  // namespace android
Loading