diff --git a/fs_mgr/libsnapshot/cow_reader.cpp b/fs_mgr/libsnapshot/cow_reader.cpp index 2acd15847..3f59001b3 100644 --- a/fs_mgr/libsnapshot/cow_reader.cpp +++ b/fs_mgr/libsnapshot/cow_reader.cpp @@ -45,6 +45,23 @@ static void SHA256(const void*, size_t, uint8_t[]) { #endif } +std::unique_ptr CowReader::CloneCowReader() { + auto cow = std::make_unique(); + 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 lab bool CowReader::ParseOps(std::optional label) { uint64_t pos; + auto data_loc = std::make_shared>(); // Skip the scratch space if (header_.major_version >= 2 && (header_.buffer_size > 0)) { @@ -185,7 +203,7 @@ bool CowReader::ParseOps(std::optional 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 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; } diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h index eeaa5c670..0786e82f0 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h @@ -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 CloneCowReader(); + private: bool ParseOps(std::optional 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 data_loc_; + std::shared_ptr> data_loc_; }; } // namespace snapshot diff --git a/fs_mgr/libsnapshot/snapuserd/snapuserd.cpp b/fs_mgr/libsnapshot/snapuserd/snapuserd.cpp index 31d0221ef..e0675b415 100644 --- a/fs_mgr/libsnapshot/snapuserd/snapuserd.cpp +++ b/fs_mgr/libsnapshot/snapuserd/snapuserd.cpp @@ -53,6 +53,10 @@ bool Snapuserd::InitializeWorkers() { return true; } +std::unique_ptr Snapuserd::CloneReaderForWorker() { + return reader_->CloneCowReader(); +} + bool Snapuserd::CommitMerge(int num_merge_ops) { struct CowHeader* ch = reinterpret_cast(mapped_addr_); ch->num_merge_ops += num_merge_ops; diff --git a/fs_mgr/libsnapshot/snapuserd/snapuserd.h b/fs_mgr/libsnapshot/snapuserd/snapuserd.h index 95d2f7726..3cb5ee2a8 100644 --- a/fs_mgr/libsnapshot/snapuserd/snapuserd.h +++ b/fs_mgr/libsnapshot/snapuserd/snapuserd.h @@ -244,6 +244,7 @@ class Snapuserd : public std::enable_shared_from_this { void* GetExceptionBuffer(size_t i) { return vec_[i].get(); } bool InitializeWorkers(); + std::unique_ptr CloneReaderForWorker(); std::shared_ptr GetSharedPtr() { return shared_from_this(); } std::vector>& GetChunkVec() { return chunk_vec_; } diff --git a/fs_mgr/libsnapshot/snapuserd/snapuserd_worker.cpp b/fs_mgr/libsnapshot/snapuserd/snapuserd_worker.cpp index 13d45fe4a..d515f648a 100644 --- a/fs_mgr/libsnapshot/snapuserd/snapuserd_worker.cpp +++ b/fs_mgr/libsnapshot/snapuserd/snapuserd_worker.cpp @@ -105,11 +105,11 @@ bool WorkerThread::InitializeFds() { } bool WorkerThread::InitReader() { - reader_ = std::make_unique(); + reader_ = snapuserd_->CloneReaderForWorker(); + if (!reader_->InitForMerge(std::move(cow_fd_))) { return false; } - return true; }