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

Commit d6fe3032 authored by Kelvin Zhang's avatar Kelvin Zhang Committed by Gerrit Code Review
Browse files

Merge "Revert "Shove type into source_info"" into main

parents da3caeab b6153add
Loading
Loading
Loading
Loading
+7 −18
Original line number Original line Diff line number Diff line
@@ -161,6 +161,9 @@ struct CowOperationV2 {


// The on disk format of cow (currently ==  CowOperation)
// The on disk format of cow (currently ==  CowOperation)
struct CowOperationV3 {
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
    // If this operation reads from the data section of the COW, this contains
    // the length.
    // the length.
    uint16_t data_length;
    uint16_t data_length;
@@ -168,10 +171,6 @@ struct CowOperationV3 {
    // The block of data in the new image that this operation modifies.
    // The block of data in the new image that this operation modifies.
    uint32_t new_block;
    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.
    // The value of |source| depends on the operation code.
    //
    //
    // CopyOp: a 32-bit block location in the source image.
    // CopyOp: a 32-bit block location in the source image.
@@ -180,6 +179,8 @@ struct CowOperationV3 {
    // ZeroOp: unused
    // ZeroOp: unused
    // LabelOp: a 64-bit opaque identifier.
    // 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
    // A block is compressed if it’s data is < block_sz
    uint64_t source_info;
    uint64_t source_info;
} __attribute__((packed));
} __attribute__((packed));
@@ -211,21 +212,9 @@ static constexpr uint8_t kCowReadAheadNotStarted = 0;
static constexpr uint8_t kCowReadAheadInProgress = 1;
static constexpr uint8_t kCowReadAheadInProgress = 1;
static constexpr uint8_t kCowReadAheadDone = 2;
static constexpr uint8_t kCowReadAheadDone = 2;


// this is a mask to grab the last 48 bits of a 64 bit integer
static constexpr uint64_t kCowOpSourceInfoDataMask = (1ULL << 48) - 1;
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 constexpr uint64_t GetCowOpSourceInfoData(const CowOperation& op) {
static inline uint64_t GetCowOpSourceInfoData(const CowOperation& op) {
    return op.source_info & kCowOpSourceInfoDataMask;
    return op.source_info & kCowOpSourceInfoDataMask;
}
}


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


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


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


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


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


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


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


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


        uint64_t source_info = v2_op.source;
        uint64_t source_info = v2_op.source;
        if (GetCowOpSourceInfoType(new_op) != kCowLabelOp) {
        if (new_op.type != kCowLabelOp) {
            source_info &= kCowOpSourceInfoDataMask;
            source_info &= kCowOpSourceInfoDataMask;
            if (source_info != v2_op.source) {
            if (source_info != v2_op.source) {
                LOG(ERROR) << "Out-of-range source value in COW op: " << v2_op;
                LOG(ERROR) << "Out-of-range source value in COW op: " << v2_op;
@@ -167,7 +166,7 @@ bool CowReader::Parse(android::base::borrowed_fd fd, std::optional<uint64_t> lab
                return false;
                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
    // If we're resuming a write, we're not ready to merge
@@ -290,7 +289,7 @@ bool CowReader::PrepMergeOps() {
    for (size_t i = 0; i < ops_->size(); i++) {
    for (size_t i = 0; i < ops_->size(); i++) {
        auto& current_op = ops_->data()[i];
        auto& current_op = ops_->data()[i];


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


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


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


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


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


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


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


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


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


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


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


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