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);