From 485fe695c12fc5917a7451ca21bbac8c8e9ccc55 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 26 Oct 2020 18:22:44 -0700 Subject: [PATCH] libsnapshot: Stop reading ops once we reach a footer. Bug: 168554689 Test: vts_libsnapshot_test Change-Id: Id8b5ba33220028c856d3761832fe231fd93e94cd --- fs_mgr/libsnapshot/cow_reader.cpp | 24 ++++++++++++++++++------ fs_mgr/libsnapshot/snapshot_test.cpp | 3 +++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/fs_mgr/libsnapshot/cow_reader.cpp b/fs_mgr/libsnapshot/cow_reader.cpp index 5fac0ac8f..f10ccb608 100644 --- a/fs_mgr/libsnapshot/cow_reader.cpp +++ b/fs_mgr/libsnapshot/cow_reader.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -117,8 +118,7 @@ bool CowReader::ParseOps() { PLOG(ERROR) << "lseek ops failed"; return false; } - uint64_t next_last_label = 0; - bool has_next = false; + std::optional next_last_label; auto ops_buffer = std::make_shared>(); if (has_footer_) ops_buffer->reserve(footer_.op.num_ops); uint64_t current_op_num = 0; @@ -146,11 +146,23 @@ bool CowReader::ParseOps() { has_last_label_ = true; last_label_ = current_op.source; } else { - last_label_ = next_last_label; - if (has_next) has_last_label_ = true; - next_last_label = current_op.source; - has_next = true; + if (next_last_label) { + last_label_ = next_last_label.value(); + has_last_label_ = true; + } + next_last_label = {current_op.source}; } + } else if (current_op.type == kCowFooterOp) { + memcpy(&footer_.op, ¤t_op, sizeof(footer_.op)); + + if (android::base::ReadFully(fd_, &footer_.data, sizeof(footer_.data))) { + has_footer_ = true; + if (next_last_label) { + last_label_ = next_last_label.value(); + has_last_label_ = true; + } + } + break; } } diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp index ec92dcdee..9660357a1 100644 --- a/fs_mgr/libsnapshot/snapshot_test.cpp +++ b/fs_mgr/libsnapshot/snapshot_test.cpp @@ -953,6 +953,9 @@ class SnapshotUpdateTest : public SnapshotTest { if (!WriteRandomData(writer.get(), &hashes_[name])) { return AssertionFailure() << "Unable to write random data to snapshot " << name; } + if (!writer->Finalize()) { + return AssertionFailure() << "Unable to finalize COW for " << name; + } } else { std::string path; auto res = MapUpdateSnapshot(name, &path);