libsnapshot: Fix CowWriter::Finalize() not restoring footer correctly.
Bug: 173432386 Test: cow_api_test Change-Id: If1b856fcdcd6b6ded5e00342037308c6b35d6fc0
This commit is contained in:
parent
d5bd5437b0
commit
bf3020b749
|
@ -757,6 +757,30 @@ TEST_F(CowTest, ClusterAppendTest) {
|
||||||
ASSERT_TRUE(iter->Done());
|
ASSERT_TRUE(iter->Done());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CowTest, AppendAfterFinalize) {
|
||||||
|
CowOptions options;
|
||||||
|
options.cluster_ops = 0;
|
||||||
|
auto writer = std::make_unique<CowWriter>(options);
|
||||||
|
ASSERT_TRUE(writer->Initialize(cow_->fd));
|
||||||
|
|
||||||
|
std::string data = "This is some data, believe it";
|
||||||
|
data.resize(options.block_size, '\0');
|
||||||
|
ASSERT_TRUE(writer->AddRawBlocks(50, data.data(), data.size()));
|
||||||
|
ASSERT_TRUE(writer->AddLabel(3));
|
||||||
|
ASSERT_TRUE(writer->Finalize());
|
||||||
|
|
||||||
|
std::string data2 = "More data!";
|
||||||
|
data2.resize(options.block_size, '\0');
|
||||||
|
ASSERT_TRUE(writer->AddRawBlocks(51, data2.data(), data2.size()));
|
||||||
|
ASSERT_TRUE(writer->Finalize());
|
||||||
|
|
||||||
|
ASSERT_EQ(lseek(cow_->fd, 0, SEEK_SET), 0);
|
||||||
|
|
||||||
|
// COW should be valid.
|
||||||
|
CowReader reader;
|
||||||
|
ASSERT_TRUE(reader.Parse(cow_->fd));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace snapshot
|
} // namespace snapshot
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
|
|
|
@ -229,7 +229,8 @@ bool CowReader::ParseOps(std::optional<uint64_t> label) {
|
||||||
|
|
||||||
if (footer_) {
|
if (footer_) {
|
||||||
if (ops_buffer->size() != footer_->op.num_ops) {
|
if (ops_buffer->size() != footer_->op.num_ops) {
|
||||||
LOG(ERROR) << "num ops does not match";
|
LOG(ERROR) << "num ops does not match, expected " << footer_->op.num_ops << ", found "
|
||||||
|
<< ops_buffer->size();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ops_buffer->size() * sizeof(CowOperation) != footer_->op.ops_size) {
|
if (ops_buffer->size() * sizeof(CowOperation) != footer_->op.ops_size) {
|
||||||
|
|
|
@ -376,6 +376,7 @@ bool CowWriter::Finalize() {
|
||||||
auto continue_data_pos = next_data_pos_;
|
auto continue_data_pos = next_data_pos_;
|
||||||
auto continue_op_pos = next_op_pos_;
|
auto continue_op_pos = next_op_pos_;
|
||||||
auto continue_size = ops_.size();
|
auto continue_size = ops_.size();
|
||||||
|
auto continue_num_ops = footer_.op.num_ops;
|
||||||
bool extra_cluster = false;
|
bool extra_cluster = false;
|
||||||
|
|
||||||
// Footer should be at the end of a file, so if there is data after the current block, end it
|
// Footer should be at the end of a file, so if there is data after the current block, end it
|
||||||
|
@ -408,9 +409,9 @@ bool CowWriter::Finalize() {
|
||||||
current_data_size_ = continue_data_size;
|
current_data_size_ = continue_data_size;
|
||||||
next_data_pos_ = continue_data_pos;
|
next_data_pos_ = continue_data_pos;
|
||||||
next_op_pos_ = continue_op_pos;
|
next_op_pos_ = continue_op_pos;
|
||||||
|
footer_.op.num_ops = continue_num_ops;
|
||||||
ops_.resize(continue_size);
|
ops_.resize(continue_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sync();
|
return Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue