libsnapshot: Don't PrepMergeOps on resume
If we're reading up to a label, we're resuming setting up the file, and there is no reason to expect the ops we require for sequence ops to be present. In that case, skip prepping for merge, and return an empty merge iterator if it is mistakenly requested. Test: cow_api_test CowTest.ResumeSeqOp Change-Id: Idd93bd4c4209197b9728fcb21a7191aae971b62d
This commit is contained in:
parent
e278cee742
commit
a7573c7b90
2 changed files with 55 additions and 1 deletions
|
@ -1113,6 +1113,54 @@ TEST_F(CowTest, MissingSeqOp) {
|
|||
ASSERT_FALSE(reader.Parse(cow_->fd));
|
||||
}
|
||||
|
||||
TEST_F(CowTest, ResumeSeqOp) {
|
||||
CowOptions options;
|
||||
auto writer = std::make_unique<CowWriter>(options);
|
||||
const int seq_len = 10;
|
||||
uint32_t sequence[seq_len];
|
||||
for (int i = 0; i < seq_len; i++) {
|
||||
sequence[i] = i + 1;
|
||||
}
|
||||
|
||||
ASSERT_TRUE(writer->Initialize(cow_->fd));
|
||||
|
||||
ASSERT_TRUE(writer->AddSequenceData(seq_len, sequence));
|
||||
ASSERT_TRUE(writer->AddZeroBlocks(1, seq_len / 2));
|
||||
ASSERT_TRUE(writer->AddLabel(1));
|
||||
ASSERT_TRUE(writer->AddZeroBlocks(1 + seq_len / 2, 1));
|
||||
|
||||
ASSERT_EQ(lseek(cow_->fd, 0, SEEK_SET), 0);
|
||||
auto reader = std::make_unique<CowReader>();
|
||||
ASSERT_TRUE(reader->Parse(cow_->fd, 1));
|
||||
auto itr = reader->GetRevMergeOpIter();
|
||||
ASSERT_TRUE(itr->Done());
|
||||
|
||||
writer = std::make_unique<CowWriter>(options);
|
||||
ASSERT_TRUE(writer->InitializeAppend(cow_->fd, 1));
|
||||
ASSERT_TRUE(writer->AddZeroBlocks(1 + seq_len / 2, seq_len / 2));
|
||||
ASSERT_TRUE(writer->Finalize());
|
||||
|
||||
ASSERT_EQ(lseek(cow_->fd, 0, SEEK_SET), 0);
|
||||
|
||||
reader = std::make_unique<CowReader>();
|
||||
ASSERT_TRUE(reader->Parse(cow_->fd));
|
||||
|
||||
auto iter = reader->GetRevMergeOpIter();
|
||||
|
||||
uint64_t expected_block = 10;
|
||||
while (!iter->Done() && expected_block > 0) {
|
||||
ASSERT_FALSE(iter->Done());
|
||||
const auto& op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op.new_block, expected_block);
|
||||
|
||||
iter->Next();
|
||||
expected_block--;
|
||||
}
|
||||
ASSERT_EQ(expected_block, 0);
|
||||
ASSERT_TRUE(iter->Done());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, RevMergeOpItrTest) {
|
||||
CowOptions options;
|
||||
options.cluster_ops = 5;
|
||||
|
|
|
@ -34,7 +34,11 @@
|
|||
namespace android {
|
||||
namespace snapshot {
|
||||
|
||||
CowReader::CowReader() : fd_(-1), header_(), fd_size_(0) {}
|
||||
CowReader::CowReader()
|
||||
: fd_(-1),
|
||||
header_(),
|
||||
fd_size_(0),
|
||||
merge_op_blocks_(std::make_shared<std::vector<uint32_t>>()) {}
|
||||
|
||||
static void SHA256(const void*, size_t, uint8_t[]) {
|
||||
#if 0
|
||||
|
@ -150,6 +154,8 @@ bool CowReader::Parse(android::base::borrowed_fd fd, std::optional<uint64_t> lab
|
|||
if (!ParseOps(label)) {
|
||||
return false;
|
||||
}
|
||||
// If we're resuming a write, we're not ready to merge
|
||||
if (label.has_value()) return true;
|
||||
return PrepMergeOps();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue