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
This commit is contained in:
parent
d83b2efb12
commit
d091522de9
5 changed files with 32 additions and 5 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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_; }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue