Loading fs_mgr/libsnapshot/cow_reader.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -231,7 +231,7 @@ bool CowReader::ParseOps(std::optional<uint64_t> label) { memcpy(&footer_->op, ¤t_op, sizeof(footer->op)); off_t offs = lseek(fd_.get(), pos, SEEK_SET); if (offs < 0 || pos != static_cast<uint64_t>(offs)) { PLOG(ERROR) << "lseek next op failed"; PLOG(ERROR) << "lseek next op failed " << offs; return false; } if (!android::base::ReadFully(fd_, &footer->data, sizeof(footer->data))) { Loading @@ -251,7 +251,7 @@ bool CowReader::ParseOps(std::optional<uint64_t> label) { // Position for next cluster read off_t offs = lseek(fd_.get(), pos, SEEK_SET); if (offs < 0 || pos != static_cast<uint64_t>(offs)) { PLOG(ERROR) << "lseek next op failed"; PLOG(ERROR) << "lseek next op failed " << offs; return false; } ops_buffer->resize(current_op_num); Loading fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot_writer.h +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ class MockSnapshotWriter : public ISnapshotWriter { // Open the writer in write mode (no append). MOCK_METHOD(bool, Initialize, (), (override)); MOCK_METHOD(bool, VerifyMergeOps, (), (override, const, noexcept)); // Open the writer in append mode, with the last label to resume // from. See CowWriter::InitializeAppend. Loading fs_mgr/libsnapshot/include/libsnapshot/snapshot_writer.h +9 −2 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ class ISnapshotWriter : public ICowWriter { virtual bool InitializeAppend(uint64_t label) = 0; virtual std::unique_ptr<FileDescriptor> OpenReader() = 0; virtual bool VerifyMergeOps() const noexcept = 0; protected: android::base::borrowed_fd GetSourceFd(); Loading @@ -58,7 +59,7 @@ class ISnapshotWriter : public ICowWriter { }; // Send writes to a COW or a raw device directly, based on a threshold. class CompressedSnapshotWriter : public ISnapshotWriter { class CompressedSnapshotWriter final : public ISnapshotWriter { public: CompressedSnapshotWriter(const CowOptions& options); Loading @@ -70,6 +71,7 @@ class CompressedSnapshotWriter : public ISnapshotWriter { bool Finalize() override; uint64_t GetCowSize() override; std::unique_ptr<FileDescriptor> OpenReader() override; bool VerifyMergeOps() const noexcept; protected: bool EmitCopy(uint64_t new_block, uint64_t old_block) override; Loading @@ -81,13 +83,14 @@ class CompressedSnapshotWriter : public ISnapshotWriter { bool EmitSequenceData(size_t num_ops, const uint32_t* data) override; private: std::unique_ptr<CowReader> OpenCowReader() const; android::base::unique_fd cow_device_; std::unique_ptr<CowWriter> cow_; }; // Write directly to a dm-snapshot device. class OnlineKernelSnapshotWriter : public ISnapshotWriter { class OnlineKernelSnapshotWriter final : public ISnapshotWriter { public: OnlineKernelSnapshotWriter(const CowOptions& options); Loading @@ -101,6 +104,10 @@ class OnlineKernelSnapshotWriter : public ISnapshotWriter { uint64_t GetCowSize() override { return cow_size_; } std::unique_ptr<FileDescriptor> OpenReader() override; // Online kernel snapshot writer doesn't care about merge sequences. // So ignore. bool VerifyMergeOps() const noexcept override { return true; } protected: 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; Loading fs_mgr/libsnapshot/snapshot_writer.cpp +15 −1 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ uint64_t CompressedSnapshotWriter::GetCowSize() { return cow_->GetCowSize(); } std::unique_ptr<FileDescriptor> CompressedSnapshotWriter::OpenReader() { std::unique_ptr<CowReader> CompressedSnapshotWriter::OpenCowReader() const { unique_fd cow_fd(dup(cow_device_.get())); if (cow_fd < 0) { PLOG(ERROR) << "dup COW device"; Loading @@ -79,6 +79,20 @@ std::unique_ptr<FileDescriptor> CompressedSnapshotWriter::OpenReader() { LOG(ERROR) << "Unable to read COW"; return nullptr; } return cow; } bool CompressedSnapshotWriter::VerifyMergeOps() const noexcept { auto cow_reader = OpenCowReader(); if (cow_reader == nullptr) { LOG(ERROR) << "Couldn't open CowReader"; return false; } return cow_reader->VerifyMergeOps(); } std::unique_ptr<FileDescriptor> CompressedSnapshotWriter::OpenReader() { auto cow = OpenCowReader(); auto reader = std::make_unique<CompressedSnapshotReader>(); if (!reader->SetCow(std::move(cow))) { Loading Loading
fs_mgr/libsnapshot/cow_reader.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -231,7 +231,7 @@ bool CowReader::ParseOps(std::optional<uint64_t> label) { memcpy(&footer_->op, ¤t_op, sizeof(footer->op)); off_t offs = lseek(fd_.get(), pos, SEEK_SET); if (offs < 0 || pos != static_cast<uint64_t>(offs)) { PLOG(ERROR) << "lseek next op failed"; PLOG(ERROR) << "lseek next op failed " << offs; return false; } if (!android::base::ReadFully(fd_, &footer->data, sizeof(footer->data))) { Loading @@ -251,7 +251,7 @@ bool CowReader::ParseOps(std::optional<uint64_t> label) { // Position for next cluster read off_t offs = lseek(fd_.get(), pos, SEEK_SET); if (offs < 0 || pos != static_cast<uint64_t>(offs)) { PLOG(ERROR) << "lseek next op failed"; PLOG(ERROR) << "lseek next op failed " << offs; return false; } ops_buffer->resize(current_op_num); Loading
fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot_writer.h +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ class MockSnapshotWriter : public ISnapshotWriter { // Open the writer in write mode (no append). MOCK_METHOD(bool, Initialize, (), (override)); MOCK_METHOD(bool, VerifyMergeOps, (), (override, const, noexcept)); // Open the writer in append mode, with the last label to resume // from. See CowWriter::InitializeAppend. Loading
fs_mgr/libsnapshot/include/libsnapshot/snapshot_writer.h +9 −2 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ class ISnapshotWriter : public ICowWriter { virtual bool InitializeAppend(uint64_t label) = 0; virtual std::unique_ptr<FileDescriptor> OpenReader() = 0; virtual bool VerifyMergeOps() const noexcept = 0; protected: android::base::borrowed_fd GetSourceFd(); Loading @@ -58,7 +59,7 @@ class ISnapshotWriter : public ICowWriter { }; // Send writes to a COW or a raw device directly, based on a threshold. class CompressedSnapshotWriter : public ISnapshotWriter { class CompressedSnapshotWriter final : public ISnapshotWriter { public: CompressedSnapshotWriter(const CowOptions& options); Loading @@ -70,6 +71,7 @@ class CompressedSnapshotWriter : public ISnapshotWriter { bool Finalize() override; uint64_t GetCowSize() override; std::unique_ptr<FileDescriptor> OpenReader() override; bool VerifyMergeOps() const noexcept; protected: bool EmitCopy(uint64_t new_block, uint64_t old_block) override; Loading @@ -81,13 +83,14 @@ class CompressedSnapshotWriter : public ISnapshotWriter { bool EmitSequenceData(size_t num_ops, const uint32_t* data) override; private: std::unique_ptr<CowReader> OpenCowReader() const; android::base::unique_fd cow_device_; std::unique_ptr<CowWriter> cow_; }; // Write directly to a dm-snapshot device. class OnlineKernelSnapshotWriter : public ISnapshotWriter { class OnlineKernelSnapshotWriter final : public ISnapshotWriter { public: OnlineKernelSnapshotWriter(const CowOptions& options); Loading @@ -101,6 +104,10 @@ class OnlineKernelSnapshotWriter : public ISnapshotWriter { uint64_t GetCowSize() override { return cow_size_; } std::unique_ptr<FileDescriptor> OpenReader() override; // Online kernel snapshot writer doesn't care about merge sequences. // So ignore. bool VerifyMergeOps() const noexcept override { return true; } protected: 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; Loading
fs_mgr/libsnapshot/snapshot_writer.cpp +15 −1 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ uint64_t CompressedSnapshotWriter::GetCowSize() { return cow_->GetCowSize(); } std::unique_ptr<FileDescriptor> CompressedSnapshotWriter::OpenReader() { std::unique_ptr<CowReader> CompressedSnapshotWriter::OpenCowReader() const { unique_fd cow_fd(dup(cow_device_.get())); if (cow_fd < 0) { PLOG(ERROR) << "dup COW device"; Loading @@ -79,6 +79,20 @@ std::unique_ptr<FileDescriptor> CompressedSnapshotWriter::OpenReader() { LOG(ERROR) << "Unable to read COW"; return nullptr; } return cow; } bool CompressedSnapshotWriter::VerifyMergeOps() const noexcept { auto cow_reader = OpenCowReader(); if (cow_reader == nullptr) { LOG(ERROR) << "Couldn't open CowReader"; return false; } return cow_reader->VerifyMergeOps(); } std::unique_ptr<FileDescriptor> CompressedSnapshotWriter::OpenReader() { auto cow = OpenCowReader(); auto reader = std::make_unique<CompressedSnapshotReader>(); if (!reader->SetCow(std::move(cow))) { Loading