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

Commit d091522d authored by Daniel Rosenberg's avatar Daniel Rosenberg
Browse files

libsnapshot: Clone worker readers from snapuserd

We'll need to have the Cow Files parsed to deal with xor ops, since
their data location is implicit from the format. Since the relevant data
is all stored in shared pointers, we can pass that data into the workers
without needing to reparse or copy.

Bug: 177104308
Test: builds
Change-Id: I96ac3da1ae620be48e5340c9f146c523b3ce74b6
parent d83b2efb
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
@@ -45,6 +45,23 @@ static void SHA256(const void*, size_t, uint8_t[]) {
#endif
}

std::unique_ptr<CowReader> CowReader::CloneCowReader() {
    auto cow = std::make_unique<CowReader>();
    cow->owned_fd_.reset();
    cow->header_ = header_;
    cow->footer_ = footer_;
    cow->fd_size_ = fd_size_;
    cow->last_label_ = last_label_;
    cow->ops_ = ops_;
    cow->merge_op_blocks_ = merge_op_blocks_;
    cow->block_map_ = block_map_;
    cow->num_total_data_ops_ = num_total_data_ops_;
    cow->num_ordered_ops_to_merge_ = num_ordered_ops_to_merge_;
    cow->has_seq_ops_ = has_seq_ops_;
    cow->data_loc_ = data_loc_;
    return cow;
}

bool CowReader::InitForMerge(android::base::unique_fd&& fd) {
    owned_fd_ = std::move(fd);
    fd_ = owned_fd_.get();
@@ -138,6 +155,7 @@ bool CowReader::Parse(android::base::borrowed_fd fd, std::optional<uint64_t> lab

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

    // Skip the scratch space
    if (header_.major_version >= 2 && (header_.buffer_size > 0)) {
@@ -185,7 +203,7 @@ bool CowReader::ParseOps(std::optional<uint64_t> label) {
            auto& current_op = ops_buffer->data()[current_op_num];
            current_op_num++;
            if (current_op.type == kCowXorOp) {
                data_loc_[current_op.new_block] = data_pos;
                data_loc->insert({current_op.new_block, data_pos});
            }
            pos += sizeof(CowOperation) + GetNextOpOffset(current_op, header_.cluster_ops);
            data_pos += current_op.data_length + GetNextDataOffset(current_op, header_.cluster_ops);
@@ -279,6 +297,7 @@ bool CowReader::ParseOps(std::optional<uint64_t> label) {

    ops_ = ops_buffer;
    ops_->shrink_to_fit();
    data_loc_ = data_loc;

    return true;
}
@@ -619,7 +638,7 @@ bool CowReader::ReadData(const CowOperation& op, IByteSink* sink) {

    uint64_t offset;
    if (op.type == kCowXorOp) {
        offset = data_loc_[op.new_block];
        offset = data_loc_->at(op.new_block);
    } else {
        offset = op.source;
    }
+4 −1
Original line number Diff line number Diff line
@@ -136,6 +136,9 @@ class CowReader : public ICowReader {

    void CloseCowFd() { owned_fd_ = {}; }

    // Creates a clone of the current CowReader without the file handlers
    std::unique_ptr<CowReader> CloneCowReader();

  private:
    bool ParseOps(std::optional<uint64_t> label);
    bool PrepMergeOps();
@@ -153,7 +156,7 @@ class CowReader : public ICowReader {
    uint64_t num_total_data_ops_;
    uint64_t num_ordered_ops_to_merge_;
    bool has_seq_ops_;
    std::unordered_map<uint64_t, uint64_t> data_loc_;
    std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc_;
};

}  // namespace snapshot
+4 −0
Original line number Diff line number Diff line
@@ -53,6 +53,10 @@ bool Snapuserd::InitializeWorkers() {
    return true;
}

std::unique_ptr<CowReader> Snapuserd::CloneReaderForWorker() {
    return reader_->CloneCowReader();
}

bool Snapuserd::CommitMerge(int num_merge_ops) {
    struct CowHeader* ch = reinterpret_cast<struct CowHeader*>(mapped_addr_);
    ch->num_merge_ops += num_merge_ops;
+1 −0
Original line number Diff line number Diff line
@@ -244,6 +244,7 @@ class Snapuserd : public std::enable_shared_from_this<Snapuserd> {
    void* GetExceptionBuffer(size_t i) { return vec_[i].get(); }

    bool InitializeWorkers();
    std::unique_ptr<CowReader> CloneReaderForWorker();
    std::shared_ptr<Snapuserd> GetSharedPtr() { return shared_from_this(); }

    std::vector<std::pair<sector_t, const CowOperation*>>& GetChunkVec() { return chunk_vec_; }
+2 −2
Original line number Diff line number Diff line
@@ -105,11 +105,11 @@ bool WorkerThread::InitializeFds() {
}

bool WorkerThread::InitReader() {
    reader_ = std::make_unique<CowReader>();
    reader_ = snapuserd_->CloneReaderForWorker();

    if (!reader_->InitForMerge(std::move(cow_fd_))) {
        return false;
    }

    return true;
}