diff --git a/fs_mgr/libsnapshot/cow_format.cpp b/fs_mgr/libsnapshot/cow_format.cpp index 0753c492e..20672b3b7 100644 --- a/fs_mgr/libsnapshot/cow_format.cpp +++ b/fs_mgr/libsnapshot/cow_format.cpp @@ -37,6 +37,8 @@ std::ostream& operator<<(std::ostream& os, CowOperation const& op) { os << "kCowLabelOp, "; else if (op.type == kCowClusterOp) os << "kCowClusterOp "; + else if (op.type == kCowSequenceOp) + os << "kCowSequenceOp "; else if (op.type == kCowFooterOp) os << "kCowFooterOp "; else @@ -81,6 +83,7 @@ bool IsMetadataOp(const CowOperation& op) { case kCowLabelOp: case kCowClusterOp: case kCowFooterOp: + case kCowSequenceOp: return true; default: return false; diff --git a/fs_mgr/libsnapshot/cow_reader.cpp b/fs_mgr/libsnapshot/cow_reader.cpp index 2349e4a06..28ca418c5 100644 --- a/fs_mgr/libsnapshot/cow_reader.cpp +++ b/fs_mgr/libsnapshot/cow_reader.cpp @@ -201,6 +201,8 @@ bool CowReader::ParseOps(std::optional label) { current_op_num--; done = true; break; + } else if (current_op.type == kCowSequenceOp) { + has_seq_ops_ = true; } } diff --git a/fs_mgr/libsnapshot/cow_writer.cpp b/fs_mgr/libsnapshot/cow_writer.cpp index 526fedeb6..df2bc963f 100644 --- a/fs_mgr/libsnapshot/cow_writer.cpp +++ b/fs_mgr/libsnapshot/cow_writer.cpp @@ -76,9 +76,8 @@ bool ICowWriter::AddLabel(uint64_t label) { return EmitLabel(label); } -bool ICowWriter::AddSequenceData(size_t /*num_ops*/, const uint32_t* /*data*/) { - LOG(ERROR) << "AddSequenceData not yet implemented"; - return false; +bool ICowWriter::AddSequenceData(size_t num_ops, const uint32_t* data) { + return EmitSequenceData(num_ops, data); } bool ICowWriter::ValidateNewBlock(uint64_t new_block) { @@ -337,6 +336,26 @@ bool CowWriter::EmitLabel(uint64_t label) { return WriteOperation(op) && Sync(); } +bool CowWriter::EmitSequenceData(size_t num_ops, const uint32_t* data) { + CHECK(!merge_in_progress_); + size_t to_add = 0; + size_t max_ops = std::numeric_limits::max() / sizeof(uint32_t); + while (num_ops > 0) { + CowOperation op = {}; + op.type = kCowSequenceOp; + op.source = next_data_pos_; + to_add = std::min(num_ops, max_ops); + op.data_length = static_cast(to_add * sizeof(uint32_t)); + if (!WriteOperation(op, data, op.data_length)) { + PLOG(ERROR) << "AddSequenceData: write failed"; + return false; + } + num_ops -= to_add; + data += to_add; + } + return true; +} + bool CowWriter::EmitCluster() { CowOperation op = {}; op.type = kCowClusterOp; diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h index 000e5e14b..23713774a 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h @@ -148,6 +148,7 @@ static constexpr uint8_t kCowReplaceOp = 2; static constexpr uint8_t kCowZeroOp = 3; static constexpr uint8_t kCowLabelOp = 4; static constexpr uint8_t kCowClusterOp = 5; +static constexpr uint8_t kCowSequenceOp = 7; static constexpr uint8_t kCowFooterOp = -1; static constexpr uint8_t kCowCompressNone = 0; diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h index 669e58ac6..16899c077 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h @@ -165,6 +165,7 @@ class CowReader : public ICowReader { std::shared_ptr> ops_; uint64_t total_data_ops_; uint64_t copy_ops_; + bool has_seq_ops_; }; } // namespace snapshot diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h index fbe646143..03ffb46ad 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h @@ -85,6 +85,7 @@ class ICowWriter { virtual bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) = 0; virtual bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) = 0; virtual bool EmitLabel(uint64_t label) = 0; + virtual bool EmitSequenceData(size_t num_ops, const uint32_t* data) = 0; bool ValidateNewBlock(uint64_t new_block); @@ -120,6 +121,7 @@ class CowWriter : public ICowWriter { virtual bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) override; virtual bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) override; virtual bool EmitLabel(uint64_t label) override; + virtual bool EmitSequenceData(size_t num_ops, const uint32_t* data) override; private: bool EmitCluster(); diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_writer.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_writer.h index bf5ce8bb5..c00dafabd 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_writer.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_writer.h @@ -76,6 +76,7 @@ class CompressedSnapshotWriter : public ISnapshotWriter { bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) override; bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) override; bool EmitLabel(uint64_t label) override; + bool EmitSequenceData(size_t num_ops, const uint32_t* data) override; private: android::base::unique_fd cow_device_; @@ -103,6 +104,7 @@ class OnlineKernelSnapshotWriter : public ISnapshotWriter { bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) override; bool EmitCopy(uint64_t new_block, uint64_t old_block) override; bool EmitLabel(uint64_t label) override; + bool EmitSequenceData(size_t num_ops, const uint32_t* data) override; private: android::base::unique_fd snapshot_fd_; diff --git a/fs_mgr/libsnapshot/snapshot_writer.cpp b/fs_mgr/libsnapshot/snapshot_writer.cpp index 080f3b79d..34b3e87b3 100644 --- a/fs_mgr/libsnapshot/snapshot_writer.cpp +++ b/fs_mgr/libsnapshot/snapshot_writer.cpp @@ -114,6 +114,10 @@ bool CompressedSnapshotWriter::EmitLabel(uint64_t label) { return cow_->AddLabel(label); } +bool CompressedSnapshotWriter::EmitSequenceData(size_t num_ops, const uint32_t* data) { + return cow_->AddSequenceData(num_ops, data); +} + bool CompressedSnapshotWriter::Initialize() { return cow_->Initialize(cow_device_); } @@ -183,6 +187,11 @@ bool OnlineKernelSnapshotWriter::EmitLabel(uint64_t) { return true; } +bool OnlineKernelSnapshotWriter::EmitSequenceData(size_t, const uint32_t*) { + // Not Needed + return true; +} + std::unique_ptr OnlineKernelSnapshotWriter::OpenReader() { unique_fd fd(dup(snapshot_fd_.get())); if (fd < 0) {