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

Commit 0103d8e6 authored by Daniel Zheng's avatar Daniel Zheng Committed by Automerger Merge Worker
Browse files

Merge "Shove type into source_info" into main am: a3646037 am: 4833be35...

Merge "Shove type into source_info" into main am: a3646037 am: 4833be35 am: a961ebc2 am: 296e0773

Original change: https://android-review.googlesource.com/c/platform/system/core/+/2775834



Change-Id: Ib5edaed4cd7ddbf129e6ba32d399e3153136d818
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 563fbeac 296e0773
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -149,9 +149,6 @@ struct CowOperationV2 {

// The on disk format of cow (currently ==  CowOperation)
struct CowOperationV3 {
    // The operation code (see the constants and structures below).
    uint8_t type;

    // If this operation reads from the data section of the COW, this contains
    // the length.
    uint16_t data_length;
@@ -159,6 +156,10 @@ struct CowOperationV3 {
    // The block of data in the new image that this operation modifies.
    uint32_t new_block;

    // source_info with have the following layout
    // |---4 bits ---| ---12 bits---| --- 48 bits ---|
    // |--- type --- | -- unused -- | --- source --- |
    //
    // The value of |source| depends on the operation code.
    //
    // CopyOp: a 32-bit block location in the source image.
@@ -167,8 +168,6 @@ struct CowOperationV3 {
    // ZeroOp: unused
    // LabelOp: a 64-bit opaque identifier.
    //
    // For ops other than Label:
    //  Bits 47-62 are reserved and must be zero.
    // A block is compressed if it’s data is < block_sz
    uint64_t source_info;
} __attribute__((packed));
@@ -200,9 +199,21 @@ static constexpr uint8_t kCowReadAheadNotStarted = 0;
static constexpr uint8_t kCowReadAheadInProgress = 1;
static constexpr uint8_t kCowReadAheadDone = 2;

static constexpr uint64_t kCowOpSourceInfoDataMask = (1ULL << 48) - 1;
// this is a mask to grab the last 48 bits of a 64 bit integer
static constexpr uint64_t kCowOpSourceInfoDataMask = (0x1ULL << 48) - 1;
// this is a mask to grab the first 4 bits of a 64 bit integer
static constexpr uint64_t kCowOpSourceInfoTypeBit = 60;
static constexpr uint64_t kCowOpSourceInfoTypeNumBits = 4;
static constexpr uint64_t kCowOpSourceInfoTypeMask = (1 << kCowOpSourceInfoTypeNumBits) - 1;

static constexpr void SetCowOpSourceInfoType(CowOperation* op, const uint8_t type) {
    op->source_info |= uint64_t(type) << kCowOpSourceInfoTypeBit;
}
static constexpr uint64_t GetCowOpSourceInfoType(const CowOperation& op) {
    return (op.source_info >> kCowOpSourceInfoTypeBit) & kCowOpSourceInfoTypeMask;
}

static inline uint64_t GetCowOpSourceInfoData(const CowOperation& op) {
static constexpr uint64_t GetCowOpSourceInfoData(const CowOperation& op) {
    return op.source_info & kCowOpSourceInfoDataMask;
}

+10 −7
Original line number Diff line number Diff line
@@ -81,16 +81,19 @@ std::ostream& operator<<(std::ostream& os, CowOperationV2 const& op) {

std::ostream& operator<<(std::ostream& os, CowOperation const& op) {
    os << "CowOperation(";
    EmitCowTypeString(os, op.type);
    if (op.type == kCowReplaceOp || op.type == kCowXorOp || op.type == kCowSequenceOp) {
    EmitCowTypeString(os, GetCowOpSourceInfoType(op));
    if (GetCowOpSourceInfoType(op) == kCowReplaceOp || GetCowOpSourceInfoType(op) == kCowXorOp ||
        GetCowOpSourceInfoType(op) == kCowSequenceOp) {
        os << ", data_length:" << op.data_length;
    }
    if (op.type != kCowClusterOp && op.type != kCowSequenceOp && op.type != kCowLabelOp) {
    if (GetCowOpSourceInfoType(op) != kCowClusterOp &&
        GetCowOpSourceInfoType(op) != kCowSequenceOp && GetCowOpSourceInfoType(op) != kCowLabelOp) {
        os << ", new_block:" << op.new_block;
    }
    if (op.type == kCowXorOp || op.type == kCowReplaceOp || op.type == kCowCopyOp) {
    if (GetCowOpSourceInfoType(op) == kCowXorOp || GetCowOpSourceInfoType(op) == kCowReplaceOp ||
        GetCowOpSourceInfoType(op) == kCowCopyOp) {
        os << ", source:" << (op.source_info & kCowOpSourceInfoDataMask);
    } else if (op.type == kCowClusterOp) {
    } else if (GetCowOpSourceInfoType(op) == kCowClusterOp) {
        os << ", cluster_data:" << (op.source_info & kCowOpSourceInfoDataMask);
    } else {
        os << ", label:0x" << android::base::StringPrintf("%" PRIx64, op.source_info);
@@ -120,7 +123,7 @@ int64_t GetNextDataOffset(const CowOperationV2& op, uint32_t cluster_ops) {
}

bool IsMetadataOp(const CowOperation& op) {
    switch (op.type) {
    switch (GetCowOpSourceInfoType(op)) {
        case kCowLabelOp:
        case kCowClusterOp:
        case kCowFooterOp:
@@ -132,7 +135,7 @@ bool IsMetadataOp(const CowOperation& op) {
}

bool IsOrderedOp(const CowOperation& op) {
    switch (op.type) {
    switch (GetCowOpSourceInfoType(op)) {
        case kCowCopyOp:
        case kCowXorOp:
            return true;
+8 −7
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include <android-base/file.h>
#include <android-base/logging.h>
#include <libsnapshot/cow_format.h>
#include <libsnapshot/cow_reader.h>
#include <zlib.h>

@@ -110,7 +111,7 @@ bool CowReader::Parse(android::base::borrowed_fd fd, std::optional<uint64_t> lab
        const auto& v2_op = parser.ops()->at(i);

        auto& new_op = ops_->at(i);
        new_op.type = v2_op.type;
        SetCowOpSourceInfoType(&new_op, v2_op.type);
        new_op.data_length = v2_op.data_length;

        if (v2_op.new_block > std::numeric_limits<uint32_t>::max()) {
@@ -120,7 +121,7 @@ bool CowReader::Parse(android::base::borrowed_fd fd, std::optional<uint64_t> lab
        new_op.new_block = v2_op.new_block;

        uint64_t source_info = v2_op.source;
        if (new_op.type != kCowLabelOp) {
        if (GetCowOpSourceInfoType(new_op) != kCowLabelOp) {
            source_info &= kCowOpSourceInfoDataMask;
            if (source_info != v2_op.source) {
                LOG(ERROR) << "Out-of-range source value in COW op: " << v2_op;
@@ -137,7 +138,7 @@ bool CowReader::Parse(android::base::borrowed_fd fd, std::optional<uint64_t> lab
                return false;
            }
        }
        new_op.source_info = source_info;
        new_op.source_info |= source_info;
    }

    // If we're resuming a write, we're not ready to merge
@@ -260,7 +261,7 @@ bool CowReader::PrepMergeOps() {
    for (size_t i = 0; i < ops_->size(); i++) {
        auto& current_op = ops_->data()[i];

        if (current_op.type == kCowSequenceOp) {
        if (GetCowOpSourceInfoType(current_op) == kCowSequenceOp) {
            size_t seq_len = current_op.data_length / sizeof(uint32_t);

            merge_op_blocks->resize(merge_op_blocks->size() + seq_len);
@@ -572,7 +573,7 @@ std::unique_ptr<ICowOpIter> CowReader::GetMergeOpIter(bool ignore_progress) {
}

bool CowReader::GetRawBytes(const CowOperation* op, void* buffer, size_t len, size_t* read) {
    switch (op->type) {
    switch (GetCowOpSourceInfoType(*op)) {
        case kCowSequenceOp:
        case kCowReplaceOp:
        case kCowXorOp:
@@ -665,7 +666,7 @@ ssize_t CowReader::ReadData(const CowOperation* op, void* buffer, size_t buffer_
    }

    uint64_t offset;
    if (op->type == kCowXorOp) {
    if (GetCowOpSourceInfoType(*op) == kCowXorOp) {
        offset = data_loc_->at(op->new_block);
    } else {
        offset = GetCowOpSourceInfoData(*op);
@@ -682,7 +683,7 @@ ssize_t CowReader::ReadData(const CowOperation* op, void* buffer, size_t buffer_
}

bool CowReader::GetSourceOffset(const CowOperation* op, uint64_t* source_offset) {
    switch (op->type) {
    switch (GetCowOpSourceInfoType(*op)) {
        case kCowCopyOp:
            *source_offset = GetCowOpSourceInfoData(*op) * header_.block_size;
            return true;
+9 −7
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <gflags/gflags.h>
#include <libsnapshot/cow_format.h>
#include <libsnapshot/cow_reader.h>
#include "parser_v2.h"

@@ -198,7 +199,7 @@ static bool Inspect(const std::string& path) {

        if (!FLAGS_silent && FLAGS_show_ops) std::cout << *op << "\n";

        if ((FLAGS_decompress || extract_to >= 0) && op->type == kCowReplaceOp) {
        if ((FLAGS_decompress || extract_to >= 0) && GetCowOpSourceInfoType(*op) == kCowReplaceOp) {
            if (reader.ReadData(op, buffer.data(), buffer.size()) < 0) {
                std::cerr << "Failed to decompress for :" << *op << "\n";
                success = false;
@@ -212,12 +213,13 @@ static bool Inspect(const std::string& path) {
                    return false;
                }
            }
        } else if (extract_to >= 0 && !IsMetadataOp(*op) && op->type != kCowZeroOp) {
        } else if (extract_to >= 0 && !IsMetadataOp(*op) &&
                   GetCowOpSourceInfoType(*op) != kCowZeroOp) {
            PLOG(ERROR) << "Cannot extract op yet: " << *op;
            return false;
        }

        if (op->type == kCowSequenceOp && FLAGS_show_merge_sequence) {
        if (GetCowOpSourceInfoType(*op) == kCowSequenceOp && FLAGS_show_merge_sequence) {
            size_t read;
            std::vector<uint32_t> merge_op_blocks;
            size_t seq_len = op->data_length / sizeof(uint32_t);
@@ -235,13 +237,13 @@ static bool Inspect(const std::string& path) {
            }
        }

        if (op->type == kCowCopyOp) {
        if (GetCowOpSourceInfoType(*op) == kCowCopyOp) {
            copy_ops++;
        } else if (op->type == kCowReplaceOp) {
        } else if (GetCowOpSourceInfoType(*op) == kCowReplaceOp) {
            replace_ops++;
        } else if (op->type == kCowZeroOp) {
        } else if (GetCowOpSourceInfoType(*op) == kCowZeroOp) {
            zero_ops++;
        } else if (op->type == kCowXorOp) {
        } else if (GetCowOpSourceInfoType(*op) == kCowXorOp) {
            xor_ops++;
        }

+6 −5
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ ssize_t CompressedSnapshotReader::ReadBlock(uint64_t chunk, size_t start_offset,
        op = ops_[chunk];
    }

    if (!op || op->type == kCowCopyOp) {
    if (!op || GetCowOpSourceInfoType(*op) == kCowCopyOp) {
        borrowed_fd fd = GetSourceFd();
        if (fd < 0) {
            // GetSourceFd sets errno.
@@ -169,15 +169,15 @@ ssize_t CompressedSnapshotReader::ReadBlock(uint64_t chunk, size_t start_offset,
            // ReadFullyAtOffset sets errno.
            return -1;
        }
    } else if (op->type == kCowZeroOp) {
    } else if (GetCowOpSourceInfoType(*op) == kCowZeroOp) {
        memset(buffer, 0, bytes_to_read);
    } else if (op->type == kCowReplaceOp) {
    } else if (GetCowOpSourceInfoType(*op) == kCowReplaceOp) {
        if (cow_->ReadData(op, buffer, bytes_to_read, start_offset) < bytes_to_read) {
            LOG(ERROR) << "CompressedSnapshotReader failed to read replace op";
            errno = EIO;
            return -1;
        }
    } else if (op->type == kCowXorOp) {
    } else if (GetCowOpSourceInfoType(*op) == kCowXorOp) {
        borrowed_fd fd = GetSourceFd();
        if (fd < 0) {
            // GetSourceFd sets errno.
@@ -208,7 +208,8 @@ ssize_t CompressedSnapshotReader::ReadBlock(uint64_t chunk, size_t start_offset,
            ((char*)buffer)[i] ^= data[i];
        }
    } else {
        LOG(ERROR) << "CompressedSnapshotReader unknown op type: " << uint32_t(op->type);
        LOG(ERROR) << "CompressedSnapshotReader unknown op type: "
                   << uint32_t(GetCowOpSourceInfoType(*op));
        errno = EINVAL;
        return -1;
    }
Loading