Merge changes Ie8ac02ad,I876f858a,Iccfd6e72 am: f9bdc146ff am: f2e17bf783
Original change: https://android-review.googlesource.com/c/platform/system/core/+/2566920 Change-Id: I3d2af2a2042fdef6eaa8760213e024d929046818 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
ba0e557238
10 changed files with 184 additions and 203 deletions
|
|
@ -35,7 +35,6 @@ class ICowReader {
|
|||
virtual ~ICowReader() {}
|
||||
|
||||
// Return the file header.
|
||||
virtual bool GetHeader(CowHeader* header) = 0;
|
||||
virtual CowHeader& GetHeader() = 0;
|
||||
|
||||
// Return the file footer.
|
||||
|
|
@ -68,13 +67,14 @@ class ICowReader {
|
|||
size_t ignore_bytes = 0) = 0;
|
||||
};
|
||||
|
||||
// Iterate over a sequence of COW operations.
|
||||
// Iterate over a sequence of COW operations. The iterator is bidirectional.
|
||||
class ICowOpIter {
|
||||
public:
|
||||
virtual ~ICowOpIter() {}
|
||||
|
||||
// True if there are no more items to read forward, false otherwise.
|
||||
virtual bool Done() = 0;
|
||||
// Returns true if the iterator is at the end of the operation list.
|
||||
// If true, Get() and Next() must not be called.
|
||||
virtual bool AtEnd() = 0;
|
||||
|
||||
// Read the current operation.
|
||||
virtual const CowOperation& Get() = 0;
|
||||
|
|
@ -82,11 +82,13 @@ class ICowOpIter {
|
|||
// Advance to the next item.
|
||||
virtual void Next() = 0;
|
||||
|
||||
// Returns true if the iterator is at the beginning of the operation list.
|
||||
// If true, Prev() must not be called; Get() however will be valid if
|
||||
// AtEnd() is not true.
|
||||
virtual bool AtBegin() = 0;
|
||||
|
||||
// Advance to the previous item.
|
||||
virtual void Prev() = 0;
|
||||
|
||||
// True if there are no more items to read backwards, false otherwise
|
||||
virtual bool RDone() = 0;
|
||||
};
|
||||
|
||||
class CowReader final : public ICowReader {
|
||||
|
|
@ -107,7 +109,6 @@ class CowReader final : public ICowReader {
|
|||
bool InitForMerge(android::base::unique_fd&& fd);
|
||||
bool VerifyMergeOps() override;
|
||||
|
||||
bool GetHeader(CowHeader* header) override;
|
||||
bool GetFooter(CowFooter* footer) override;
|
||||
|
||||
bool GetLastLabel(uint64_t* label) override;
|
||||
|
|
|
|||
|
|
@ -62,23 +62,24 @@ TEST_F(CowTest, CopyContiguous) {
|
|||
ASSERT_EQ(lseek(cow_->fd, 0, SEEK_SET), 0);
|
||||
|
||||
CowReader reader;
|
||||
CowHeader header;
|
||||
CowFooter footer;
|
||||
ASSERT_TRUE(reader.Parse(cow_->fd));
|
||||
ASSERT_TRUE(reader.GetHeader(&header));
|
||||
ASSERT_TRUE(reader.GetFooter(&footer));
|
||||
|
||||
const auto& header = reader.GetHeader();
|
||||
ASSERT_EQ(header.magic, kCowMagicNumber);
|
||||
ASSERT_EQ(header.major_version, kCowVersionMajor);
|
||||
ASSERT_EQ(header.minor_version, kCowVersionMinor);
|
||||
ASSERT_EQ(header.block_size, options.block_size);
|
||||
|
||||
CowFooter footer;
|
||||
ASSERT_TRUE(reader.GetFooter(&footer));
|
||||
ASSERT_EQ(footer.op.num_ops, 100);
|
||||
|
||||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
|
||||
size_t i = 0;
|
||||
while (!iter->Done()) {
|
||||
while (!iter->AtEnd()) {
|
||||
auto op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
ASSERT_EQ(op->compression, kCowCompressNone);
|
||||
|
|
@ -110,20 +111,21 @@ TEST_F(CowTest, ReadWrite) {
|
|||
ASSERT_EQ(lseek(cow_->fd, 0, SEEK_SET), 0);
|
||||
|
||||
CowReader reader;
|
||||
CowHeader header;
|
||||
CowFooter footer;
|
||||
ASSERT_TRUE(reader.Parse(cow_->fd));
|
||||
ASSERT_TRUE(reader.GetHeader(&header));
|
||||
ASSERT_TRUE(reader.GetFooter(&footer));
|
||||
|
||||
const auto& header = reader.GetHeader();
|
||||
ASSERT_EQ(header.magic, kCowMagicNumber);
|
||||
ASSERT_EQ(header.major_version, kCowVersionMajor);
|
||||
ASSERT_EQ(header.minor_version, kCowVersionMinor);
|
||||
ASSERT_EQ(header.block_size, options.block_size);
|
||||
|
||||
CowFooter footer;
|
||||
ASSERT_TRUE(reader.GetFooter(&footer));
|
||||
ASSERT_EQ(footer.op.num_ops, 4);
|
||||
|
||||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
|
|
@ -135,7 +137,7 @@ TEST_F(CowTest, ReadWrite) {
|
|||
std::string sink(data.size(), '\0');
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
|
|
@ -146,7 +148,7 @@ TEST_F(CowTest, ReadWrite) {
|
|||
ASSERT_EQ(sink, data);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
|
||||
// Note: the zero operation gets split into two blocks.
|
||||
|
|
@ -157,7 +159,7 @@ TEST_F(CowTest, ReadWrite) {
|
|||
ASSERT_EQ(op->source, 0);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
|
@ -167,7 +169,7 @@ TEST_F(CowTest, ReadWrite) {
|
|||
ASSERT_EQ(op->source, 0);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, ReadWriteXor) {
|
||||
|
|
@ -188,20 +190,21 @@ TEST_F(CowTest, ReadWriteXor) {
|
|||
ASSERT_EQ(lseek(cow_->fd, 0, SEEK_SET), 0);
|
||||
|
||||
CowReader reader;
|
||||
CowHeader header;
|
||||
CowFooter footer;
|
||||
ASSERT_TRUE(reader.Parse(cow_->fd));
|
||||
ASSERT_TRUE(reader.GetHeader(&header));
|
||||
ASSERT_TRUE(reader.GetFooter(&footer));
|
||||
|
||||
const auto& header = reader.GetHeader();
|
||||
ASSERT_EQ(header.magic, kCowMagicNumber);
|
||||
ASSERT_EQ(header.major_version, kCowVersionMajor);
|
||||
ASSERT_EQ(header.minor_version, kCowVersionMinor);
|
||||
ASSERT_EQ(header.block_size, options.block_size);
|
||||
|
||||
CowFooter footer;
|
||||
ASSERT_TRUE(reader.GetFooter(&footer));
|
||||
ASSERT_EQ(footer.op.num_ops, 4);
|
||||
|
||||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
|
|
@ -213,7 +216,7 @@ TEST_F(CowTest, ReadWriteXor) {
|
|||
std::string sink(data.size(), '\0');
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowXorOp);
|
||||
|
|
@ -225,7 +228,7 @@ TEST_F(CowTest, ReadWriteXor) {
|
|||
ASSERT_EQ(sink, data);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
|
||||
// Note: the zero operation gets split into two blocks.
|
||||
|
|
@ -236,7 +239,7 @@ TEST_F(CowTest, ReadWriteXor) {
|
|||
ASSERT_EQ(op->source, 0);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
|
@ -246,7 +249,7 @@ TEST_F(CowTest, ReadWriteXor) {
|
|||
ASSERT_EQ(op->source, 0);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, CompressGz) {
|
||||
|
|
@ -270,7 +273,7 @@ TEST_F(CowTest, CompressGz) {
|
|||
|
||||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
|
||||
std::string sink(data.size(), '\0');
|
||||
|
|
@ -283,7 +286,7 @@ TEST_F(CowTest, CompressGz) {
|
|||
ASSERT_EQ(sink, data);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
class CompressionTest : public CowTest, public testing::WithParamInterface<const char*> {};
|
||||
|
|
@ -325,7 +328,7 @@ TEST_P(CompressionTest, ThreadedBatchWrites) {
|
|||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
int total_blocks = 0;
|
||||
while (!iter->Done()) {
|
||||
while (!iter->AtEnd()) {
|
||||
auto op = &iter->Get();
|
||||
|
||||
if (op->type == kCowXorOp) {
|
||||
|
|
@ -399,7 +402,7 @@ TEST_P(CompressionTest, NoBatchWrites) {
|
|||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
int total_blocks = 0;
|
||||
while (!iter->Done()) {
|
||||
while (!iter->AtEnd()) {
|
||||
auto op = &iter->Get();
|
||||
|
||||
if (op->type == kCowReplaceOp) {
|
||||
|
|
@ -515,7 +518,7 @@ TEST_F(CowTest, ClusterCompressGz) {
|
|||
|
||||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
|
||||
std::string sink(data.size(), '\0');
|
||||
|
|
@ -528,13 +531,13 @@ TEST_F(CowTest, ClusterCompressGz) {
|
|||
ASSERT_EQ(sink, data);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
|
||||
sink = {};
|
||||
|
|
@ -546,13 +549,13 @@ TEST_F(CowTest, ClusterCompressGz) {
|
|||
ASSERT_EQ(sink, data2);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, CompressTwoBlocks) {
|
||||
|
|
@ -576,9 +579,9 @@ TEST_F(CowTest, CompressTwoBlocks) {
|
|||
|
||||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
|
||||
std::string sink(options.block_size, '\0');
|
||||
|
||||
|
|
@ -655,7 +658,7 @@ TEST_F(CowTest, AppendLabelSmall) {
|
|||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
|
|
@ -665,21 +668,21 @@ TEST_F(CowTest, AppendLabelSmall) {
|
|||
sink = {};
|
||||
sink.resize(data2.size(), '\0');
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 3);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data2);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, AppendLabelMissing) {
|
||||
|
|
@ -718,20 +721,20 @@ TEST_F(CowTest, AppendLabelMissing) {
|
|||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 0);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, AppendExtendedCorrupted) {
|
||||
|
|
@ -776,13 +779,13 @@ TEST_F(CowTest, AppendExtendedCorrupted) {
|
|||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 5);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, AppendbyLabel) {
|
||||
|
|
@ -827,7 +830,7 @@ TEST_F(CowTest, AppendbyLabel) {
|
|||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
|
|
@ -837,7 +840,7 @@ TEST_F(CowTest, AppendbyLabel) {
|
|||
sink = {};
|
||||
sink.resize(options.block_size, '\0');
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
|
|
@ -845,32 +848,32 @@ TEST_F(CowTest, AppendbyLabel) {
|
|||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 4);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 5);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, ClusterTest) {
|
||||
|
|
@ -908,7 +911,7 @@ TEST_F(CowTest, ClusterTest) {
|
|||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
|
|
@ -916,58 +919,58 @@ TEST_F(CowTest, ClusterTest) {
|
|||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 4);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 5);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 6);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, ClusterAppendTest) {
|
||||
|
|
@ -1007,14 +1010,14 @@ TEST_F(CowTest, ClusterAppendTest) {
|
|||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 50);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
|
|
@ -1022,13 +1025,13 @@ TEST_F(CowTest, ClusterAppendTest) {
|
|||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->Done());
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, AppendAfterFinalize) {
|
||||
|
|
@ -1065,8 +1068,7 @@ AssertionResult WriteDataBlock(CowWriter* writer, uint64_t new_block, std::strin
|
|||
|
||||
AssertionResult CompareDataBlock(CowReader* reader, const CowOperation& op,
|
||||
const std::string& data) {
|
||||
CowHeader header;
|
||||
reader->GetHeader(&header);
|
||||
const auto& header = reader->GetHeader();
|
||||
|
||||
std::string cmp = data;
|
||||
cmp.resize(header.block_size, '\0');
|
||||
|
|
@ -1116,7 +1118,7 @@ TEST_F(CowTest, ResumeMidCluster) {
|
|||
size_t max_in_cluster = 0;
|
||||
size_t num_in_cluster = 0;
|
||||
size_t num_clusters = 0;
|
||||
while (!iter->Done()) {
|
||||
while (!iter->AtEnd()) {
|
||||
const auto& op = iter->Get();
|
||||
|
||||
num_in_cluster++;
|
||||
|
|
@ -1177,7 +1179,7 @@ TEST_F(CowTest, ResumeEndCluster) {
|
|||
size_t max_in_cluster = 0;
|
||||
size_t num_in_cluster = 0;
|
||||
size_t num_clusters = 0;
|
||||
while (!iter->Done()) {
|
||||
while (!iter->AtEnd()) {
|
||||
const auto& op = iter->Get();
|
||||
|
||||
num_in_cluster++;
|
||||
|
|
@ -1229,7 +1231,7 @@ TEST_F(CowTest, DeleteMidCluster) {
|
|||
size_t max_in_cluster = 0;
|
||||
size_t num_in_cluster = 0;
|
||||
size_t num_clusters = 0;
|
||||
while (!iter->Done()) {
|
||||
while (!iter->AtEnd()) {
|
||||
const auto& op = iter->Get();
|
||||
|
||||
num_in_cluster++;
|
||||
|
|
@ -1273,14 +1275,14 @@ TEST_F(CowTest, BigSeqOp) {
|
|||
auto iter = reader.GetRevMergeOpIter();
|
||||
|
||||
for (int i = 0; i < seq_len; i++) {
|
||||
ASSERT_TRUE(!iter->Done());
|
||||
ASSERT_TRUE(!iter->AtEnd());
|
||||
const auto& op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op.new_block, seq_len - i);
|
||||
|
||||
iter->Next();
|
||||
}
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, MissingSeqOp) {
|
||||
|
|
@ -1324,7 +1326,7 @@ TEST_F(CowTest, ResumeSeqOp) {
|
|||
auto reader = std::make_unique<CowReader>();
|
||||
ASSERT_TRUE(reader->Parse(cow_->fd, 1));
|
||||
auto itr = reader->GetRevMergeOpIter();
|
||||
ASSERT_TRUE(itr->Done());
|
||||
ASSERT_TRUE(itr->AtEnd());
|
||||
|
||||
writer = std::make_unique<CowWriter>(options);
|
||||
ASSERT_TRUE(writer->InitializeAppend(cow_->fd, 1));
|
||||
|
|
@ -1339,8 +1341,8 @@ TEST_F(CowTest, ResumeSeqOp) {
|
|||
auto iter = reader->GetRevMergeOpIter();
|
||||
|
||||
uint64_t expected_block = 10;
|
||||
while (!iter->Done() && expected_block > 0) {
|
||||
ASSERT_FALSE(iter->Done());
|
||||
while (!iter->AtEnd() && expected_block > 0) {
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
const auto& op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op.new_block, expected_block);
|
||||
|
|
@ -1349,7 +1351,7 @@ TEST_F(CowTest, ResumeSeqOp) {
|
|||
expected_block--;
|
||||
}
|
||||
ASSERT_EQ(expected_block, 0);
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, RevMergeOpItrTest) {
|
||||
|
|
@ -1390,7 +1392,7 @@ TEST_F(CowTest, RevMergeOpItrTest) {
|
|||
auto iter = reader.GetRevMergeOpIter();
|
||||
auto expected_new_block = revMergeOpSequence.begin();
|
||||
|
||||
while (!iter->Done() && expected_new_block != revMergeOpSequence.end()) {
|
||||
while (!iter->AtEnd() && expected_new_block != revMergeOpSequence.end()) {
|
||||
const auto& op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op.new_block, *expected_new_block);
|
||||
|
|
@ -1399,7 +1401,7 @@ TEST_F(CowTest, RevMergeOpItrTest) {
|
|||
expected_new_block++;
|
||||
}
|
||||
ASSERT_EQ(expected_new_block, revMergeOpSequence.end());
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, LegacyRevMergeOpItrTest) {
|
||||
|
|
@ -1439,7 +1441,7 @@ TEST_F(CowTest, LegacyRevMergeOpItrTest) {
|
|||
auto iter = reader.GetRevMergeOpIter();
|
||||
auto expected_new_block = revMergeOpSequence.begin();
|
||||
|
||||
while (!iter->Done() && expected_new_block != revMergeOpSequence.end()) {
|
||||
while (!iter->AtEnd() && expected_new_block != revMergeOpSequence.end()) {
|
||||
const auto& op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op.new_block, *expected_new_block);
|
||||
|
|
@ -1448,7 +1450,7 @@ TEST_F(CowTest, LegacyRevMergeOpItrTest) {
|
|||
expected_new_block++;
|
||||
}
|
||||
ASSERT_EQ(expected_new_block, revMergeOpSequence.end());
|
||||
ASSERT_TRUE(iter->Done());
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
}
|
||||
|
||||
TEST_F(CowTest, InvalidMergeOrderTest) {
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ bool CowReader::PrepMergeOps() {
|
|||
bool CowReader::VerifyMergeOps() {
|
||||
auto itr = GetMergeOpIter(true);
|
||||
std::unordered_map<uint64_t, CowOperation> overwritten_blocks;
|
||||
while (!itr->Done()) {
|
||||
while (!itr->AtEnd()) {
|
||||
CowOperation op = itr->Get();
|
||||
uint64_t block;
|
||||
bool offset;
|
||||
|
|
@ -544,11 +544,6 @@ bool CowReader::VerifyMergeOps() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CowReader::GetHeader(CowHeader* header) {
|
||||
*header = header_;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CowReader::GetFooter(CowFooter* footer) {
|
||||
if (!footer_) return false;
|
||||
*footer = footer_.value();
|
||||
|
|
@ -565,12 +560,12 @@ class CowOpIter final : public ICowOpIter {
|
|||
public:
|
||||
CowOpIter(std::shared_ptr<std::vector<CowOperation>>& ops, uint64_t start);
|
||||
|
||||
bool Done() override;
|
||||
bool AtEnd() override;
|
||||
const CowOperation& Get() override;
|
||||
void Next() override;
|
||||
|
||||
void Prev() override;
|
||||
bool RDone() override;
|
||||
bool AtBegin() override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::vector<CowOperation>> ops_;
|
||||
|
|
@ -582,26 +577,26 @@ CowOpIter::CowOpIter(std::shared_ptr<std::vector<CowOperation>>& ops, uint64_t s
|
|||
op_iter_ = ops_->begin() + start;
|
||||
}
|
||||
|
||||
bool CowOpIter::RDone() {
|
||||
bool CowOpIter::AtBegin() {
|
||||
return op_iter_ == ops_->begin();
|
||||
}
|
||||
|
||||
void CowOpIter::Prev() {
|
||||
CHECK(!RDone());
|
||||
CHECK(!AtBegin());
|
||||
op_iter_--;
|
||||
}
|
||||
|
||||
bool CowOpIter::Done() {
|
||||
bool CowOpIter::AtEnd() {
|
||||
return op_iter_ == ops_->end();
|
||||
}
|
||||
|
||||
void CowOpIter::Next() {
|
||||
CHECK(!Done());
|
||||
CHECK(!AtEnd());
|
||||
op_iter_++;
|
||||
}
|
||||
|
||||
const CowOperation& CowOpIter::Get() {
|
||||
CHECK(!Done());
|
||||
CHECK(!AtEnd());
|
||||
return (*op_iter_);
|
||||
}
|
||||
|
||||
|
|
@ -610,12 +605,12 @@ class CowRevMergeOpIter final : public ICowOpIter {
|
|||
explicit CowRevMergeOpIter(std::shared_ptr<std::vector<CowOperation>> ops,
|
||||
std::shared_ptr<std::vector<int>> block_pos_index, uint64_t start);
|
||||
|
||||
bool Done() override;
|
||||
bool AtEnd() override;
|
||||
const CowOperation& Get() override;
|
||||
void Next() override;
|
||||
|
||||
void Prev() override;
|
||||
bool RDone() override;
|
||||
bool AtBegin() override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::vector<CowOperation>> ops_;
|
||||
|
|
@ -629,12 +624,12 @@ class CowMergeOpIter final : public ICowOpIter {
|
|||
explicit CowMergeOpIter(std::shared_ptr<std::vector<CowOperation>> ops,
|
||||
std::shared_ptr<std::vector<int>> block_pos_index, uint64_t start);
|
||||
|
||||
bool Done() override;
|
||||
bool AtEnd() override;
|
||||
const CowOperation& Get() override;
|
||||
void Next() override;
|
||||
|
||||
void Prev() override;
|
||||
bool RDone() override;
|
||||
bool AtBegin() override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::vector<CowOperation>> ops_;
|
||||
|
|
@ -651,26 +646,26 @@ CowMergeOpIter::CowMergeOpIter(std::shared_ptr<std::vector<CowOperation>> ops,
|
|||
block_iter_ = cow_op_index_vec_->begin() + start;
|
||||
}
|
||||
|
||||
bool CowMergeOpIter::RDone() {
|
||||
bool CowMergeOpIter::AtBegin() {
|
||||
return block_iter_ == cow_op_index_vec_->begin();
|
||||
}
|
||||
|
||||
void CowMergeOpIter::Prev() {
|
||||
CHECK(!RDone());
|
||||
CHECK(!AtBegin());
|
||||
block_iter_--;
|
||||
}
|
||||
|
||||
bool CowMergeOpIter::Done() {
|
||||
bool CowMergeOpIter::AtEnd() {
|
||||
return block_iter_ == cow_op_index_vec_->end();
|
||||
}
|
||||
|
||||
void CowMergeOpIter::Next() {
|
||||
CHECK(!Done());
|
||||
CHECK(!AtEnd());
|
||||
block_iter_++;
|
||||
}
|
||||
|
||||
const CowOperation& CowMergeOpIter::Get() {
|
||||
CHECK(!Done());
|
||||
CHECK(!AtEnd());
|
||||
return ops_->data()[*block_iter_];
|
||||
}
|
||||
|
||||
|
|
@ -683,26 +678,26 @@ CowRevMergeOpIter::CowRevMergeOpIter(std::shared_ptr<std::vector<CowOperation>>
|
|||
block_riter_ = cow_op_index_vec_->rbegin();
|
||||
}
|
||||
|
||||
bool CowRevMergeOpIter::RDone() {
|
||||
bool CowRevMergeOpIter::AtBegin() {
|
||||
return block_riter_ == cow_op_index_vec_->rbegin();
|
||||
}
|
||||
|
||||
void CowRevMergeOpIter::Prev() {
|
||||
CHECK(!RDone());
|
||||
CHECK(!AtBegin());
|
||||
block_riter_--;
|
||||
}
|
||||
|
||||
bool CowRevMergeOpIter::Done() {
|
||||
bool CowRevMergeOpIter::AtEnd() {
|
||||
return block_riter_ == cow_op_index_vec_->rend() - start_;
|
||||
}
|
||||
|
||||
void CowRevMergeOpIter::Next() {
|
||||
CHECK(!Done());
|
||||
CHECK(!AtEnd());
|
||||
block_riter_++;
|
||||
}
|
||||
|
||||
const CowOperation& CowRevMergeOpIter::Get() {
|
||||
CHECK(!Done());
|
||||
CHECK(!AtEnd());
|
||||
return ops_->data()[*block_riter_];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -392,10 +392,11 @@ bool CowWriter::OpenForAppend(uint64_t label) {
|
|||
auto reader = std::make_unique<CowReader>();
|
||||
std::queue<CowOperation> toAdd;
|
||||
|
||||
if (!reader->Parse(fd_, {label}) || !reader->GetHeader(&header_)) {
|
||||
if (!reader->Parse(fd_, {label})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
header_ = reader->GetHeader();
|
||||
options_.block_size = header_.block_size;
|
||||
options_.cluster_ops = header_.cluster_ops;
|
||||
|
||||
|
|
@ -405,7 +406,7 @@ bool CowWriter::OpenForAppend(uint64_t label) {
|
|||
|
||||
auto iter = reader->GetOpIter();
|
||||
|
||||
while (!iter->Done()) {
|
||||
while (!iter->AtEnd()) {
|
||||
AddOperation(iter->Get());
|
||||
iter->Next();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
|
@ -38,16 +39,16 @@ void MyLogger(android::base::LogId, android::base::LogSeverity severity, const c
|
|||
}
|
||||
|
||||
static void usage(void) {
|
||||
LOG(ERROR) << "Usage: inspect_cow [-sd] <COW_FILE>";
|
||||
LOG(ERROR) << "\t -s Run Silent";
|
||||
LOG(ERROR) << "\t -d Attempt to decompress";
|
||||
LOG(ERROR) << "\t -b Show data for failed decompress";
|
||||
LOG(ERROR) << "\t -l Show ops";
|
||||
LOG(ERROR) << "\t -m Show ops in reverse merge order";
|
||||
LOG(ERROR) << "\t -n Show ops in merge order";
|
||||
LOG(ERROR) << "\t -a Include merged ops in any merge order listing";
|
||||
LOG(ERROR) << "\t -o Shows sequence op block order";
|
||||
LOG(ERROR) << "\t -v Verifies merge order has no conflicts\n";
|
||||
std::cerr << "Usage: inspect_cow [-sd] <COW_FILE>\n";
|
||||
std::cerr << "\t -s Run Silent\n";
|
||||
std::cerr << "\t -d Attempt to decompress\n";
|
||||
std::cerr << "\t -b Show data for failed decompress\n";
|
||||
std::cerr << "\t -l Show ops\n";
|
||||
std::cerr << "\t -m Show ops in reverse merge order\n";
|
||||
std::cerr << "\t -n Show ops in merge order\n";
|
||||
std::cerr << "\t -a Include merged ops in any merge order listing\n";
|
||||
std::cerr << "\t -o Shows sequence op block order\n";
|
||||
std::cerr << "\t -v Verifies merge order has no conflicts\n";
|
||||
}
|
||||
|
||||
enum OpIter { Normal, RevMerge, Merge };
|
||||
|
|
@ -89,37 +90,40 @@ static bool Inspect(const std::string& path, Options opt) {
|
|||
}
|
||||
|
||||
CowReader reader;
|
||||
|
||||
auto start_time = std::chrono::steady_clock::now();
|
||||
if (!reader.Parse(fd)) {
|
||||
LOG(ERROR) << "parse failed: " << path;
|
||||
return false;
|
||||
}
|
||||
std::chrono::duration<double> parse_time = std::chrono::steady_clock::now() - start_time;
|
||||
|
||||
CowHeader header;
|
||||
if (!reader.GetHeader(&header)) {
|
||||
LOG(ERROR) << "could not get header: " << path;
|
||||
return false;
|
||||
}
|
||||
const CowHeader& header = reader.GetHeader();
|
||||
CowFooter footer;
|
||||
bool has_footer = false;
|
||||
if (reader.GetFooter(&footer)) has_footer = true;
|
||||
|
||||
if (!opt.silent) {
|
||||
std::cout << "Major version: " << header.major_version << "\n";
|
||||
std::cout << "Minor version: " << header.minor_version << "\n";
|
||||
std::cout << "Version: " << header.major_version << "." << header.minor_version << "\n";
|
||||
std::cout << "Header size: " << header.header_size << "\n";
|
||||
std::cout << "Footer size: " << header.footer_size << "\n";
|
||||
std::cout << "Block size: " << header.block_size << "\n";
|
||||
std::cout << "Num merge ops: " << header.num_merge_ops << "\n";
|
||||
std::cout << "RA buffer size: " << header.buffer_size << "\n";
|
||||
std::cout << "\n";
|
||||
std::cout << "Merge ops: " << header.num_merge_ops << "\n";
|
||||
std::cout << "Readahead buffer: " << header.buffer_size << " bytes\n";
|
||||
if (has_footer) {
|
||||
std::cout << "Total Ops size: " << footer.op.ops_size << "\n";
|
||||
std::cout << "Number of Ops: " << footer.op.num_ops << "\n";
|
||||
std::cout << "\n";
|
||||
std::cout << "Footer: ops usage: " << footer.op.ops_size << " bytes\n";
|
||||
std::cout << "Footer: op count: " << footer.op.num_ops << "\n";
|
||||
} else {
|
||||
std::cout << "Footer: none\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!opt.silent) {
|
||||
std::cout << "Parse time: " << (parse_time.count() * 1000) << "ms\n";
|
||||
}
|
||||
|
||||
if (opt.verify_sequence) {
|
||||
std::cout << "\n";
|
||||
if (reader.VerifyMergeOps()) {
|
||||
std::cout << "\nMerge sequence is consistent.\n";
|
||||
} else {
|
||||
|
|
@ -140,7 +144,7 @@ static bool Inspect(const std::string& path, Options opt) {
|
|||
|
||||
bool success = true;
|
||||
uint64_t xor_ops = 0, copy_ops = 0, replace_ops = 0, zero_ops = 0;
|
||||
while (!iter->Done()) {
|
||||
while (!iter->AtEnd()) {
|
||||
const CowOperation& op = iter->Get();
|
||||
|
||||
if (!opt.silent && opt.show_ops) std::cout << op << "\n";
|
||||
|
|
@ -186,9 +190,11 @@ static bool Inspect(const std::string& path, Options opt) {
|
|||
|
||||
if (!opt.silent) {
|
||||
auto total_ops = replace_ops + zero_ops + copy_ops + xor_ops;
|
||||
std::cout << "Total-data-ops: " << total_ops << "Replace-ops: " << replace_ops
|
||||
<< " Zero-ops: " << zero_ops << " Copy-ops: " << copy_ops
|
||||
<< " Xor_ops: " << xor_ops << std::endl;
|
||||
std::cout << "Data ops: " << total_ops << "\n";
|
||||
std::cout << "Replace ops: " << replace_ops << "\n";
|
||||
std::cout << "Zero ops: " << zero_ops << "\n";
|
||||
std::cout << "Copy ops: " << copy_ops << "\n";
|
||||
std::cout << "Xor ops: " << xor_ops << "\n";
|
||||
}
|
||||
|
||||
return success;
|
||||
|
|
@ -237,15 +243,17 @@ int main(int argc, char** argv) {
|
|||
break;
|
||||
default:
|
||||
android::snapshot::usage();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
android::base::InitLogging(argv, android::snapshot::MyLogger);
|
||||
|
||||
if (argc < optind + 1) {
|
||||
android::snapshot::usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
android::base::InitLogging(argv, android::snapshot::MyLogger);
|
||||
|
||||
if (!android::snapshot::Inspect(argv[optind], opt)) {
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,15 +80,12 @@ bool ReadFdFileDescriptor::Flush() {
|
|||
bool CompressedSnapshotReader::SetCow(std::unique_ptr<CowReader>&& cow) {
|
||||
cow_ = std::move(cow);
|
||||
|
||||
CowHeader header;
|
||||
if (!cow_->GetHeader(&header)) {
|
||||
return false;
|
||||
}
|
||||
const auto& header = cow_->GetHeader();
|
||||
block_size_ = header.block_size;
|
||||
|
||||
// Populate the operation map.
|
||||
op_iter_ = cow_->GetOpIter();
|
||||
while (!op_iter_->Done()) {
|
||||
while (!op_iter_->AtEnd()) {
|
||||
const CowOperation* op = &op_iter_->Get();
|
||||
if (IsMetadataOp(*op)) {
|
||||
op_iter_->Next();
|
||||
|
|
|
|||
|
|
@ -347,7 +347,6 @@ void Snapuserd::CheckMergeCompletionStatus() {
|
|||
*/
|
||||
bool Snapuserd::ReadMetadata() {
|
||||
reader_ = std::make_unique<CowReader>();
|
||||
CowHeader header;
|
||||
CowOptions options;
|
||||
bool metadata_found = false;
|
||||
int replace_ops = 0, zero_ops = 0, copy_ops = 0;
|
||||
|
|
@ -359,11 +358,7 @@ bool Snapuserd::ReadMetadata() {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!reader_->GetHeader(&header)) {
|
||||
SNAP_LOG(ERROR) << "Failed to get header";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& header = reader_->GetHeader();
|
||||
if (!(header.block_size == BLOCK_SZ)) {
|
||||
SNAP_LOG(ERROR) << "Invalid header block size found: " << header.block_size;
|
||||
return false;
|
||||
|
|
@ -395,7 +390,7 @@ bool Snapuserd::ReadMetadata() {
|
|||
// this memset will ensure that metadata read is completed.
|
||||
memset(de_ptr.get(), 0, (exceptions_per_area_ * sizeof(struct disk_exception)));
|
||||
|
||||
while (!cowop_rm_iter->Done()) {
|
||||
while (!cowop_rm_iter->AtEnd()) {
|
||||
const CowOperation* cow_op = &cowop_rm_iter->Get();
|
||||
struct disk_exception* de =
|
||||
reinterpret_cast<struct disk_exception*>((char*)de_ptr.get() + offset);
|
||||
|
|
@ -442,7 +437,7 @@ bool Snapuserd::ReadMetadata() {
|
|||
sizeof(struct disk_exception));
|
||||
memset(de_ptr.get(), 0, (exceptions_per_area_ * sizeof(struct disk_exception)));
|
||||
|
||||
if (cowop_rm_iter->Done()) {
|
||||
if (cowop_rm_iter->AtEnd()) {
|
||||
vec_.push_back(std::move(de_ptr));
|
||||
}
|
||||
}
|
||||
|
|
@ -462,7 +457,7 @@ bool Snapuserd::ReadMetadata() {
|
|||
<< " Number of replace/zero ops completed in this area: " << num_ops
|
||||
<< " Pending copy ops for this area: " << pending_ordered_ops;
|
||||
|
||||
while (!cowop_rm_iter->Done()) {
|
||||
while (!cowop_rm_iter->AtEnd()) {
|
||||
do {
|
||||
const CowOperation* cow_op = &cowop_rm_iter->Get();
|
||||
|
||||
|
|
@ -531,7 +526,7 @@ bool Snapuserd::ReadMetadata() {
|
|||
source_blocks.insert(cow_op->new_block);
|
||||
prev_id = cow_op->new_block;
|
||||
cowop_rm_iter->Next();
|
||||
} while (!cowop_rm_iter->Done() && pending_ordered_ops);
|
||||
} while (!cowop_rm_iter->AtEnd() && pending_ordered_ops);
|
||||
|
||||
data_chunk_id = GetNextAllocatableChunkId(data_chunk_id);
|
||||
SNAP_LOG(DEBUG) << "Batch Merge copy-ops of size: " << vec.size()
|
||||
|
|
@ -574,7 +569,7 @@ bool Snapuserd::ReadMetadata() {
|
|||
sizeof(struct disk_exception));
|
||||
memset(de_ptr.get(), 0, (exceptions_per_area_ * sizeof(struct disk_exception)));
|
||||
|
||||
if (cowop_rm_iter->Done()) {
|
||||
if (cowop_rm_iter->AtEnd()) {
|
||||
vec_.push_back(std::move(de_ptr));
|
||||
SNAP_LOG(DEBUG) << "ReadMetadata() completed; Number of Areas: " << vec_.size();
|
||||
}
|
||||
|
|
@ -636,8 +631,7 @@ bool Snapuserd::ReadMetadata() {
|
|||
}
|
||||
|
||||
bool Snapuserd::MmapMetadata() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
|
||||
if (header.major_version >= 2 && header.buffer_size > 0) {
|
||||
total_mapped_addr_length_ = header.header_size + BUFFER_REGION_DEFAULT_SIZE;
|
||||
|
|
@ -832,8 +826,7 @@ bool Snapuserd::Start() {
|
|||
}
|
||||
|
||||
uint64_t Snapuserd::GetBufferMetadataOffset() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
|
||||
size_t size = header.header_size + sizeof(BufferState);
|
||||
return size;
|
||||
|
|
@ -848,16 +841,14 @@ uint64_t Snapuserd::GetBufferMetadataOffset() {
|
|||
*
|
||||
*/
|
||||
size_t Snapuserd::GetBufferMetadataSize() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
|
||||
size_t metadata_bytes = (header.buffer_size * sizeof(struct ScratchMetadata)) / BLOCK_SZ;
|
||||
return metadata_bytes;
|
||||
}
|
||||
|
||||
size_t Snapuserd::GetBufferDataOffset() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
|
||||
return (header.header_size + GetBufferMetadataSize());
|
||||
}
|
||||
|
|
@ -866,16 +857,14 @@ size_t Snapuserd::GetBufferDataOffset() {
|
|||
* (2MB - 8K = 2088960 bytes) will be the buffer region to hold the data.
|
||||
*/
|
||||
size_t Snapuserd::GetBufferDataSize() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
|
||||
size_t size = header.buffer_size - GetBufferMetadataSize();
|
||||
return size;
|
||||
}
|
||||
|
||||
struct BufferState* Snapuserd::GetBufferState() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
|
||||
struct BufferState* ra_state =
|
||||
reinterpret_cast<struct BufferState*>((char*)mapped_addr_ + header.header_size);
|
||||
|
|
|
|||
|
|
@ -98,8 +98,7 @@ bool SnapshotHandler::CommitMerge(int num_merge_ops) {
|
|||
}
|
||||
} else {
|
||||
reader_->UpdateMergeOpsCompleted(num_merge_ops);
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
|
||||
if (lseek(cow_fd_.get(), 0, SEEK_SET) < 0) {
|
||||
SNAP_PLOG(ERROR) << "lseek failed";
|
||||
|
|
@ -154,7 +153,6 @@ bool SnapshotHandler::CheckMergeCompletionStatus() {
|
|||
|
||||
bool SnapshotHandler::ReadMetadata() {
|
||||
reader_ = std::make_unique<CowReader>(CowReader::ReaderFlags::USERSPACE_MERGE, true);
|
||||
CowHeader header;
|
||||
CowOptions options;
|
||||
|
||||
SNAP_LOG(DEBUG) << "ReadMetadata: Parsing cow file";
|
||||
|
|
@ -164,11 +162,7 @@ bool SnapshotHandler::ReadMetadata() {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!reader_->GetHeader(&header)) {
|
||||
SNAP_LOG(ERROR) << "Failed to get header";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& header = reader_->GetHeader();
|
||||
if (!(header.block_size == BLOCK_SZ)) {
|
||||
SNAP_LOG(ERROR) << "Invalid header block size found: " << header.block_size;
|
||||
return false;
|
||||
|
|
@ -191,7 +185,7 @@ bool SnapshotHandler::ReadMetadata() {
|
|||
|
||||
size_t copy_ops = 0, replace_ops = 0, zero_ops = 0, xor_ops = 0;
|
||||
|
||||
while (!cowop_iter->Done()) {
|
||||
while (!cowop_iter->AtEnd()) {
|
||||
const CowOperation* cow_op = &cowop_iter->Get();
|
||||
|
||||
if (cow_op->type == kCowCopyOp) {
|
||||
|
|
@ -244,8 +238,7 @@ bool SnapshotHandler::ReadMetadata() {
|
|||
}
|
||||
|
||||
bool SnapshotHandler::MmapMetadata() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
|
||||
total_mapped_addr_length_ = header.header_size + BUFFER_REGION_DEFAULT_SIZE;
|
||||
|
||||
|
|
@ -367,8 +360,7 @@ bool SnapshotHandler::Start() {
|
|||
}
|
||||
|
||||
uint64_t SnapshotHandler::GetBufferMetadataOffset() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
|
||||
return (header.header_size + sizeof(BufferState));
|
||||
}
|
||||
|
|
@ -383,8 +375,7 @@ uint64_t SnapshotHandler::GetBufferMetadataOffset() {
|
|||
*
|
||||
*/
|
||||
size_t SnapshotHandler::GetBufferMetadataSize() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
size_t buffer_size = header.buffer_size;
|
||||
|
||||
// If there is no scratch space, then just use the
|
||||
|
|
@ -397,8 +388,7 @@ size_t SnapshotHandler::GetBufferMetadataSize() {
|
|||
}
|
||||
|
||||
size_t SnapshotHandler::GetBufferDataOffset() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
|
||||
return (header.header_size + GetBufferMetadataSize());
|
||||
}
|
||||
|
|
@ -407,8 +397,7 @@ size_t SnapshotHandler::GetBufferDataOffset() {
|
|||
* (2MB - 8K = 2088960 bytes) will be the buffer region to hold the data.
|
||||
*/
|
||||
size_t SnapshotHandler::GetBufferDataSize() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
size_t buffer_size = header.buffer_size;
|
||||
|
||||
// If there is no scratch space, then just use the
|
||||
|
|
@ -421,8 +410,7 @@ size_t SnapshotHandler::GetBufferDataSize() {
|
|||
}
|
||||
|
||||
struct BufferState* SnapshotHandler::GetBufferState() {
|
||||
CowHeader header;
|
||||
reader_->GetHeader(&header);
|
||||
const auto& header = reader_->GetHeader();
|
||||
|
||||
struct BufferState* ra_state =
|
||||
reinterpret_cast<struct BufferState*>((char*)mapped_addr_ + header.header_size);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ int Worker::PrepareMerge(uint64_t* source_offset, int* pending_ops,
|
|||
bool checkOrderedOp = (replace_zero_vec == nullptr);
|
||||
|
||||
do {
|
||||
if (!cowop_iter_->Done() && num_ops) {
|
||||
if (!cowop_iter_->AtEnd() && num_ops) {
|
||||
const CowOperation* cow_op = &cowop_iter_->Get();
|
||||
if (checkOrderedOp && !IsOrderedOp(*cow_op)) {
|
||||
break;
|
||||
|
|
@ -45,7 +45,7 @@ int Worker::PrepareMerge(uint64_t* source_offset, int* pending_ops,
|
|||
num_ops -= 1;
|
||||
nr_consecutive = 1;
|
||||
|
||||
while (!cowop_iter_->Done() && num_ops) {
|
||||
while (!cowop_iter_->AtEnd() && num_ops) {
|
||||
const CowOperation* op = &cowop_iter_->Get();
|
||||
if (checkOrderedOp && !IsOrderedOp(*op)) {
|
||||
break;
|
||||
|
|
@ -85,7 +85,7 @@ bool Worker::MergeReplaceZeroOps() {
|
|||
|
||||
SNAP_LOG(INFO) << "MergeReplaceZeroOps started....";
|
||||
|
||||
while (!cowop_iter_->Done()) {
|
||||
while (!cowop_iter_->AtEnd()) {
|
||||
int num_ops = PAYLOAD_BUFFER_SZ / BLOCK_SZ;
|
||||
std::vector<const CowOperation*> replace_zero_vec;
|
||||
uint64_t source_offset;
|
||||
|
|
@ -93,7 +93,7 @@ bool Worker::MergeReplaceZeroOps() {
|
|||
int linear_blocks = PrepareMerge(&source_offset, &num_ops, &replace_zero_vec);
|
||||
if (linear_blocks == 0) {
|
||||
// Merge complete
|
||||
CHECK(cowop_iter_->Done());
|
||||
CHECK(cowop_iter_->AtEnd());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ bool Worker::MergeOrderedOpsAsync() {
|
|||
|
||||
SNAP_LOG(INFO) << "MergeOrderedOpsAsync started....";
|
||||
|
||||
while (!cowop_iter_->Done()) {
|
||||
while (!cowop_iter_->AtEnd()) {
|
||||
const CowOperation* cow_op = &cowop_iter_->Get();
|
||||
if (!IsOrderedOp(*cow_op)) {
|
||||
break;
|
||||
|
|
@ -361,7 +361,7 @@ bool Worker::MergeOrderedOps() {
|
|||
|
||||
SNAP_LOG(INFO) << "MergeOrderedOps started....";
|
||||
|
||||
while (!cowop_iter_->Done()) {
|
||||
while (!cowop_iter_->AtEnd()) {
|
||||
const CowOperation* cow_op = &cowop_iter_->Get();
|
||||
if (!IsOrderedOp(*cow_op)) {
|
||||
break;
|
||||
|
|
@ -443,7 +443,7 @@ bool Worker::AsyncMerge() {
|
|||
if (!MergeOrderedOpsAsync()) {
|
||||
SNAP_LOG(ERROR) << "MergeOrderedOpsAsync failed - Falling back to synchronous I/O";
|
||||
// Reset the iter so that we retry the merge
|
||||
while (blocks_merged_in_group_ && !cowop_iter_->RDone()) {
|
||||
while (blocks_merged_in_group_ && !cowop_iter_->AtBegin()) {
|
||||
cowop_iter_->Prev();
|
||||
blocks_merged_in_group_ -= 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -809,7 +809,7 @@ void ReadAhead::InitializeRAIter() {
|
|||
}
|
||||
|
||||
bool ReadAhead::RAIterDone() {
|
||||
if (cowop_iter_->Done()) {
|
||||
if (cowop_iter_->AtEnd()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -827,7 +827,7 @@ void ReadAhead::RAIterNext() {
|
|||
}
|
||||
|
||||
void ReadAhead::RAResetIter(uint64_t num_blocks) {
|
||||
while (num_blocks && !cowop_iter_->RDone()) {
|
||||
while (num_blocks && !cowop_iter_->AtBegin()) {
|
||||
cowop_iter_->Prev();
|
||||
num_blocks -= 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue