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

Commit 770bb3ec authored by Daniel Zheng's avatar Daniel Zheng
Browse files

libsnapshot: Add XorOp to v3 Cow

Adding in XOR operation to v3 writer. Parser has to go through ops and
create a mapping of XOR operation to it's data

Test: cow_api_test
Bug: 307452468
Change-Id: I51e13a59ba472b62bdcc05921f2e5d6e2c8ad2af
parent 6c7dca81
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -183,7 +183,7 @@ class CowReader final : public ICowReader {
    uint64_t num_total_data_ops_{};
    uint64_t num_ordered_ops_to_merge_{};
    bool has_seq_ops_{};
    std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc_;
    std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> xor_data_loc_;
    ReaderFlags reader_flag_;
    bool is_merge_{};
};
+3 −5
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ std::unique_ptr<CowReader> CowReader::CloneCowReader() {
    cow->merge_op_start_ = merge_op_start_;
    cow->num_total_data_ops_ = num_total_data_ops_;
    cow->num_ordered_ops_to_merge_ = num_ordered_ops_to_merge_;
    cow->data_loc_ = data_loc_;
    cow->xor_data_loc_ = xor_data_loc_;
    cow->block_pos_index_ = block_pos_index_;
    cow->is_merge_ = is_merge_;
    return cow;
@@ -139,7 +139,6 @@ bool CowReader::Parse(android::base::borrowed_fd fd, std::optional<uint64_t> lab
            LOG(ERROR) << "Unknown version: " << header_.prefix.major_version;
            return false;
    }

    if (!parser->Parse(fd, header_, label)) {
        return false;
    }
@@ -154,7 +153,7 @@ bool CowReader::Parse(android::base::borrowed_fd fd, std::optional<uint64_t> lab
    footer_ = parser->footer();
    fd_size_ = parser->fd_size();
    last_label_ = parser->last_label();
    data_loc_ = parser->data_loc();
    xor_data_loc_ = parser->xor_data_loc();

    // If we're resuming a write, we're not ready to merge
    if (label.has_value()) return true;
@@ -682,11 +681,10 @@ ssize_t CowReader::ReadData(const CowOperation* op, void* buffer, size_t buffer_

    uint64_t offset;
    if (op->type == kCowXorOp) {
        offset = data_loc_->at(op->new_block);
        offset = xor_data_loc_->at(op->new_block);
    } else {
        offset = GetCowOpSourceInfoData(*op);
    }

    if (!decompressor) {
        CowDataStream stream(this, offset + ignore_bytes, op->data_length - ignore_bytes);
        return stream.ReadFully(buffer, buffer_size);
+2 −1
Original line number Diff line number Diff line
@@ -82,7 +82,8 @@ static bool ShowRawOpStreamV2(borrowed_fd fd, const CowHeaderV3& header) {
    }
    for (const auto& op : *parser.get_v2ops()) {
        std::cout << op << "\n";
        if (auto iter = parser.data_loc()->find(op.new_block); iter != parser.data_loc()->end()) {
        if (auto iter = parser.xor_data_loc()->find(op.new_block);
            iter != parser.xor_data_loc()->end()) {
            std::cout << "    data loc: " << iter->second << "\n";
        }
    }
+4 −1
Original line number Diff line number Diff line
@@ -38,7 +38,9 @@ class CowParserBase {
                       std::optional<uint64_t> label = {}) = 0;
    virtual bool Translate(TranslatedCowOps* out) = 0;
    virtual std::optional<CowFooter> footer() const { return std::nullopt; }
    virtual std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc() const = 0;
    std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> xor_data_loc() {
        return xor_data_loc_;
    };

    uint64_t fd_size() const { return fd_size_; }
    const std::optional<uint64_t>& last_label() const { return last_label_; }
@@ -47,6 +49,7 @@ class CowParserBase {
    CowHeaderV3 header_ = {};
    uint64_t fd_size_;
    std::optional<uint64_t> last_label_;
    std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> xor_data_loc_ = {};
};

}  // namespace snapshot
+3 −7
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ bool CowParserV2::Parse(borrowed_fd fd, const CowHeaderV3& header, std::optional

bool CowParserV2::ParseOps(borrowed_fd fd, std::optional<uint64_t> label) {
    uint64_t pos;
    auto data_loc = std::make_shared<std::unordered_map<uint64_t, uint64_t>>();
    auto xor_data_loc = std::make_shared<std::unordered_map<uint64_t, uint64_t>>();

    // Skip the scratch space
    if (header_.prefix.major_version >= 2 && (header_.buffer_size > 0)) {
@@ -111,7 +111,7 @@ bool CowParserV2::ParseOps(borrowed_fd fd, std::optional<uint64_t> label) {
            auto& current_op = ops_buffer->data()[current_op_num];
            current_op_num++;
            if (current_op.type == kCowXorOp) {
                data_loc->insert({current_op.new_block, data_pos});
                xor_data_loc->insert({current_op.new_block, data_pos});
            }
            pos += sizeof(CowOperationV2) + GetNextOpOffset(current_op, header_.cluster_ops);
            data_pos += current_op.data_length + GetNextDataOffset(current_op, header_.cluster_ops);
@@ -193,7 +193,7 @@ bool CowParserV2::ParseOps(borrowed_fd fd, std::optional<uint64_t> label) {

    v2_ops_ = ops_buffer;
    v2_ops_->shrink_to_fit();
    data_loc_ = data_loc;
    xor_data_loc_ = xor_data_loc;
    return true;
}

@@ -239,9 +239,5 @@ bool CowParserV2::Translate(TranslatedCowOps* out) {
    return true;
}

std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> CowParserV2::data_loc() const {
    return data_loc_;
}

}  // namespace snapshot
}  // namespace android
Loading