Shove type into source_info
We can shove type into source info to save 8 bits in per cow operation.
We only need 4 bits inside of source_info to enumerate all the types of
Cow Operation:
static constexpr uint8_t kCowCopyOp = 1;
static constexpr uint8_t kCowReplaceOp = 2;
static constexpr uint8_t kCowZeroOp = 3;
static constexpr uint8_t kCowLabelOp = 4;
static constexpr uint8_t kCowClusterOp = 5;
static constexpr uint8_t kCowXorOp = 6;
static constexpr uint8_t kCowSequenceOp = 7;
static constexpr uint8_t kCowFooterOp = -1;
Test: critical ota paths on pixel
Change-Id: I22049db0b39a55bd8f863339f3751d3146d5c1e9
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h
index 2beeb9f..bfa8f6b 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h
@@ -149,9 +149,6 @@
// The on disk format of cow (currently == CowOperation)
struct CowOperationV3 {
- // The operation code (see the constants and structures below).
- uint8_t type;
-
// If this operation reads from the data section of the COW, this contains
// the length.
uint16_t data_length;
@@ -159,6 +156,10 @@
// The block of data in the new image that this operation modifies.
uint32_t new_block;
+ // source_info with have the following layout
+ // |---4 bits ---| ---12 bits---| --- 48 bits ---|
+ // |--- type --- | -- unused -- | --- source --- |
+ //
// The value of |source| depends on the operation code.
//
// CopyOp: a 32-bit block location in the source image.
@@ -167,8 +168,6 @@
// ZeroOp: unused
// LabelOp: a 64-bit opaque identifier.
//
- // For ops other than Label:
- // Bits 47-62 are reserved and must be zero.
// A block is compressed if it’s data is < block_sz
uint64_t source_info;
} __attribute__((packed));
@@ -200,9 +199,21 @@
static constexpr uint8_t kCowReadAheadInProgress = 1;
static constexpr uint8_t kCowReadAheadDone = 2;
-static constexpr uint64_t kCowOpSourceInfoDataMask = (1ULL << 48) - 1;
+// this is a mask to grab the last 48 bits of a 64 bit integer
+static constexpr uint64_t kCowOpSourceInfoDataMask = (0x1ULL << 48) - 1;
+// this is a mask to grab the first 4 bits of a 64 bit integer
+static constexpr uint64_t kCowOpSourceInfoTypeBit = 60;
+static constexpr uint64_t kCowOpSourceInfoTypeNumBits = 4;
+static constexpr uint64_t kCowOpSourceInfoTypeMask = (1 << kCowOpSourceInfoTypeNumBits) - 1;
-static inline uint64_t GetCowOpSourceInfoData(const CowOperation& op) {
+static constexpr void SetCowOpSourceInfoType(CowOperation* op, const uint8_t type) {
+ op->source_info |= uint64_t(type) << kCowOpSourceInfoTypeBit;
+}
+static constexpr uint64_t GetCowOpSourceInfoType(const CowOperation& op) {
+ return (op.source_info >> kCowOpSourceInfoTypeBit) & kCowOpSourceInfoTypeMask;
+}
+
+static constexpr uint64_t GetCowOpSourceInfoData(const CowOperation& op) {
return op.source_info & kCowOpSourceInfoDataMask;
}
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_format.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_format.cpp
index 5ab4f7a..1be592d 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_format.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_format.cpp
@@ -81,16 +81,19 @@
std::ostream& operator<<(std::ostream& os, CowOperation const& op) {
os << "CowOperation(";
- EmitCowTypeString(os, op.type);
- if (op.type == kCowReplaceOp || op.type == kCowXorOp || op.type == kCowSequenceOp) {
+ EmitCowTypeString(os, GetCowOpSourceInfoType(op));
+ if (GetCowOpSourceInfoType(op) == kCowReplaceOp || GetCowOpSourceInfoType(op) == kCowXorOp ||
+ GetCowOpSourceInfoType(op) == kCowSequenceOp) {
os << ", data_length:" << op.data_length;
}
- if (op.type != kCowClusterOp && op.type != kCowSequenceOp && op.type != kCowLabelOp) {
+ if (GetCowOpSourceInfoType(op) != kCowClusterOp &&
+ GetCowOpSourceInfoType(op) != kCowSequenceOp && GetCowOpSourceInfoType(op) != kCowLabelOp) {
os << ", new_block:" << op.new_block;
}
- if (op.type == kCowXorOp || op.type == kCowReplaceOp || op.type == kCowCopyOp) {
+ if (GetCowOpSourceInfoType(op) == kCowXorOp || GetCowOpSourceInfoType(op) == kCowReplaceOp ||
+ GetCowOpSourceInfoType(op) == kCowCopyOp) {
os << ", source:" << (op.source_info & kCowOpSourceInfoDataMask);
- } else if (op.type == kCowClusterOp) {
+ } else if (GetCowOpSourceInfoType(op) == kCowClusterOp) {
os << ", cluster_data:" << (op.source_info & kCowOpSourceInfoDataMask);
} else {
os << ", label:0x" << android::base::StringPrintf("%" PRIx64, op.source_info);
@@ -120,7 +123,7 @@
}
bool IsMetadataOp(const CowOperation& op) {
- switch (op.type) {
+ switch (GetCowOpSourceInfoType(op)) {
case kCowLabelOp:
case kCowClusterOp:
case kCowFooterOp:
@@ -132,7 +135,7 @@
}
bool IsOrderedOp(const CowOperation& op) {
- switch (op.type) {
+ switch (GetCowOpSourceInfoType(op)) {
case kCowCopyOp:
case kCowXorOp:
return true;
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
index 85fd4c3..c52705c 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
@@ -24,6 +24,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <libsnapshot/cow_format.h>
#include <libsnapshot/cow_reader.h>
#include <zlib.h>
@@ -110,7 +111,7 @@
const auto& v2_op = parser.ops()->at(i);
auto& new_op = ops_->at(i);
- new_op.type = v2_op.type;
+ SetCowOpSourceInfoType(&new_op, v2_op.type);
new_op.data_length = v2_op.data_length;
if (v2_op.new_block > std::numeric_limits<uint32_t>::max()) {
@@ -120,7 +121,7 @@
new_op.new_block = v2_op.new_block;
uint64_t source_info = v2_op.source;
- if (new_op.type != kCowLabelOp) {
+ if (GetCowOpSourceInfoType(new_op) != kCowLabelOp) {
source_info &= kCowOpSourceInfoDataMask;
if (source_info != v2_op.source) {
LOG(ERROR) << "Out-of-range source value in COW op: " << v2_op;
@@ -137,7 +138,7 @@
return false;
}
}
- new_op.source_info = source_info;
+ new_op.source_info |= source_info;
}
// If we're resuming a write, we're not ready to merge
@@ -260,7 +261,7 @@
for (size_t i = 0; i < ops_->size(); i++) {
auto& current_op = ops_->data()[i];
- if (current_op.type == kCowSequenceOp) {
+ if (GetCowOpSourceInfoType(current_op) == kCowSequenceOp) {
size_t seq_len = current_op.data_length / sizeof(uint32_t);
merge_op_blocks->resize(merge_op_blocks->size() + seq_len);
@@ -572,7 +573,7 @@
}
bool CowReader::GetRawBytes(const CowOperation* op, void* buffer, size_t len, size_t* read) {
- switch (op->type) {
+ switch (GetCowOpSourceInfoType(*op)) {
case kCowSequenceOp:
case kCowReplaceOp:
case kCowXorOp:
@@ -665,7 +666,7 @@
}
uint64_t offset;
- if (op->type == kCowXorOp) {
+ if (GetCowOpSourceInfoType(*op) == kCowXorOp) {
offset = data_loc_->at(op->new_block);
} else {
offset = GetCowOpSourceInfoData(*op);
@@ -682,7 +683,7 @@
}
bool CowReader::GetSourceOffset(const CowOperation* op, uint64_t* source_offset) {
- switch (op->type) {
+ switch (GetCowOpSourceInfoType(*op)) {
case kCowCopyOp:
*source_offset = GetCowOpSourceInfoData(*op) * header_.block_size;
return true;
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp
index 83b5a12..aaaf20c 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp
@@ -26,6 +26,7 @@
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <gflags/gflags.h>
+#include <libsnapshot/cow_format.h>
#include <libsnapshot/cow_reader.h>
#include "parser_v2.h"
@@ -198,7 +199,7 @@
if (!FLAGS_silent && FLAGS_show_ops) std::cout << *op << "\n";
- if ((FLAGS_decompress || extract_to >= 0) && op->type == kCowReplaceOp) {
+ if ((FLAGS_decompress || extract_to >= 0) && GetCowOpSourceInfoType(*op) == kCowReplaceOp) {
if (reader.ReadData(op, buffer.data(), buffer.size()) < 0) {
std::cerr << "Failed to decompress for :" << *op << "\n";
success = false;
@@ -212,12 +213,13 @@
return false;
}
}
- } else if (extract_to >= 0 && !IsMetadataOp(*op) && op->type != kCowZeroOp) {
+ } else if (extract_to >= 0 && !IsMetadataOp(*op) &&
+ GetCowOpSourceInfoType(*op) != kCowZeroOp) {
PLOG(ERROR) << "Cannot extract op yet: " << *op;
return false;
}
- if (op->type == kCowSequenceOp && FLAGS_show_merge_sequence) {
+ if (GetCowOpSourceInfoType(*op) == kCowSequenceOp && FLAGS_show_merge_sequence) {
size_t read;
std::vector<uint32_t> merge_op_blocks;
size_t seq_len = op->data_length / sizeof(uint32_t);
@@ -235,13 +237,13 @@
}
}
- if (op->type == kCowCopyOp) {
+ if (GetCowOpSourceInfoType(*op) == kCowCopyOp) {
copy_ops++;
- } else if (op->type == kCowReplaceOp) {
+ } else if (GetCowOpSourceInfoType(*op) == kCowReplaceOp) {
replace_ops++;
- } else if (op->type == kCowZeroOp) {
+ } else if (GetCowOpSourceInfoType(*op) == kCowZeroOp) {
zero_ops++;
- } else if (op->type == kCowXorOp) {
+ } else if (GetCowOpSourceInfoType(*op) == kCowXorOp) {
xor_ops++;
}
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/snapshot_reader.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/snapshot_reader.cpp
index a3e40d9..d7ee432 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/snapshot_reader.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/snapshot_reader.cpp
@@ -147,7 +147,7 @@
op = ops_[chunk];
}
- if (!op || op->type == kCowCopyOp) {
+ if (!op || GetCowOpSourceInfoType(*op) == kCowCopyOp) {
borrowed_fd fd = GetSourceFd();
if (fd < 0) {
// GetSourceFd sets errno.
@@ -169,15 +169,15 @@
// ReadFullyAtOffset sets errno.
return -1;
}
- } else if (op->type == kCowZeroOp) {
+ } else if (GetCowOpSourceInfoType(*op) == kCowZeroOp) {
memset(buffer, 0, bytes_to_read);
- } else if (op->type == kCowReplaceOp) {
+ } else if (GetCowOpSourceInfoType(*op) == kCowReplaceOp) {
if (cow_->ReadData(op, buffer, bytes_to_read, start_offset) < bytes_to_read) {
LOG(ERROR) << "CompressedSnapshotReader failed to read replace op";
errno = EIO;
return -1;
}
- } else if (op->type == kCowXorOp) {
+ } else if (GetCowOpSourceInfoType(*op) == kCowXorOp) {
borrowed_fd fd = GetSourceFd();
if (fd < 0) {
// GetSourceFd sets errno.
@@ -208,7 +208,8 @@
((char*)buffer)[i] ^= data[i];
}
} else {
- LOG(ERROR) << "CompressedSnapshotReader unknown op type: " << uint32_t(op->type);
+ LOG(ERROR) << "CompressedSnapshotReader unknown op type: "
+ << uint32_t(GetCowOpSourceInfoType(*op));
errno = EINVAL;
return -1;
}
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/test_v2.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/test_v2.cpp
index 35d74ba..d962875 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/test_v2.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/test_v2.cpp
@@ -25,6 +25,7 @@
#include <libsnapshot/cow_reader.h>
#include <libsnapshot/cow_writer.h>
#include "cow_decompress.h"
+#include "libsnapshot/cow_format.h"
#include "writer_v2.h"
using android::base::unique_fd;
@@ -85,7 +86,7 @@
size_t i = 0;
while (!iter->AtEnd()) {
auto op = iter->Get();
- ASSERT_EQ(op->type, kCowCopyOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowCopyOp);
ASSERT_EQ(op->data_length, 0);
ASSERT_EQ(op->new_block, 10 + i);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 1000 + i);
@@ -131,7 +132,7 @@
ASSERT_FALSE(iter->AtEnd());
auto op = iter->Get();
- ASSERT_EQ(op->type, kCowCopyOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowCopyOp);
ASSERT_EQ(op->data_length, 0);
ASSERT_EQ(op->new_block, 10);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 20);
@@ -142,7 +143,7 @@
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowReplaceOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowReplaceOp);
ASSERT_EQ(op->data_length, 4096);
ASSERT_EQ(op->new_block, 50);
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
@@ -153,7 +154,7 @@
op = iter->Get();
// Note: the zero operation gets split into two blocks.
- ASSERT_EQ(op->type, kCowZeroOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowZeroOp);
ASSERT_EQ(op->data_length, 0);
ASSERT_EQ(op->new_block, 51);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 0);
@@ -162,7 +163,7 @@
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowZeroOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowZeroOp);
ASSERT_EQ(op->data_length, 0);
ASSERT_EQ(op->new_block, 52);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 0);
@@ -206,7 +207,7 @@
ASSERT_FALSE(iter->AtEnd());
auto op = iter->Get();
- ASSERT_EQ(op->type, kCowCopyOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowCopyOp);
ASSERT_EQ(op->data_length, 0);
ASSERT_EQ(op->new_block, 10);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 20);
@@ -217,7 +218,7 @@
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowXorOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowXorOp);
ASSERT_EQ(op->data_length, 4096);
ASSERT_EQ(op->new_block, 50);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 98314); // 4096 * 24 + 10
@@ -229,7 +230,7 @@
op = iter->Get();
// Note: the zero operation gets split into two blocks.
- ASSERT_EQ(op->type, kCowZeroOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowZeroOp);
ASSERT_EQ(op->data_length, 0);
ASSERT_EQ(op->new_block, 51);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 0);
@@ -238,7 +239,7 @@
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowZeroOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowZeroOp);
ASSERT_EQ(op->data_length, 0);
ASSERT_EQ(op->new_block, 52);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 0);
@@ -273,7 +274,7 @@
std::string sink(data.size(), '\0');
- ASSERT_EQ(op->type, kCowReplaceOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowReplaceOp);
ASSERT_EQ(op->data_length, 56); // compressed!
ASSERT_EQ(op->new_block, 50);
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
@@ -325,7 +326,7 @@
while (!iter->AtEnd()) {
auto op = iter->Get();
- if (op->type == kCowXorOp) {
+ if (GetCowOpSourceInfoType(*op) == kCowXorOp) {
total_blocks += 1;
std::string sink(xor_data.size(), '\0');
ASSERT_EQ(op->new_block, 50);
@@ -334,7 +335,7 @@
ASSERT_EQ(sink, xor_data);
}
- if (op->type == kCowReplaceOp) {
+ if (GetCowOpSourceInfoType(*op) == kCowReplaceOp) {
total_blocks += 1;
if (op->new_block == 100) {
data.resize(options.block_size);
@@ -399,7 +400,7 @@
while (!iter->AtEnd()) {
auto op = iter->Get();
- if (op->type == kCowReplaceOp) {
+ if (GetCowOpSourceInfoType(*op) == kCowReplaceOp) {
total_blocks += 1;
if (op->new_block == 50) {
data.resize(options.block_size);
@@ -519,7 +520,7 @@
std::string sink(data.size(), '\0');
- ASSERT_EQ(op->type, kCowReplaceOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowReplaceOp);
ASSERT_EQ(op->data_length, 56); // compressed!
ASSERT_EQ(op->new_block, 50);
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
@@ -529,7 +530,7 @@
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowClusterOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowClusterOp);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
@@ -546,7 +547,7 @@
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowClusterOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowClusterOp);
iter->Next();
ASSERT_TRUE(iter->AtEnd());
@@ -580,7 +581,7 @@
std::string sink(options.block_size, '\0');
auto op = iter->Get();
- ASSERT_EQ(op->type, kCowReplaceOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowReplaceOp);
ASSERT_EQ(op->new_block, 51);
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
}
@@ -653,7 +654,7 @@
ASSERT_FALSE(iter->AtEnd());
auto op = iter->Get();
- ASSERT_EQ(op->type, kCowReplaceOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowReplaceOp);
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
ASSERT_EQ(sink, data);
@@ -663,14 +664,14 @@
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowLabelOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowLabelOp);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 3);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowReplaceOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowReplaceOp);
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
ASSERT_EQ(sink, data2);
@@ -716,14 +717,14 @@
ASSERT_FALSE(iter->AtEnd());
auto op = iter->Get();
- ASSERT_EQ(op->type, kCowLabelOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowLabelOp);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 0);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowZeroOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowZeroOp);
iter->Next();
@@ -774,7 +775,7 @@
ASSERT_FALSE(iter->AtEnd());
auto op = iter->Get();
- ASSERT_EQ(op->type, kCowLabelOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowLabelOp);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 5);
iter->Next();
@@ -825,7 +826,7 @@
ASSERT_FALSE(iter->AtEnd());
auto op = iter->Get();
- ASSERT_EQ(op->type, kCowReplaceOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowReplaceOp);
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
ASSERT_EQ(sink, data.substr(0, options.block_size));
@@ -835,7 +836,7 @@
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowReplaceOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowReplaceOp);
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
ASSERT_EQ(sink, data.substr(options.block_size, 2 * options.block_size));
@@ -843,25 +844,25 @@
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowLabelOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowLabelOp);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 4);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowZeroOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowZeroOp);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowZeroOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowZeroOp);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowLabelOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowLabelOp);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 5);
iter->Next();
@@ -906,7 +907,7 @@
ASSERT_FALSE(iter->AtEnd());
auto op = iter->Get();
- ASSERT_EQ(op->type, kCowReplaceOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowReplaceOp);
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
ASSERT_EQ(sink, data.substr(0, options.block_size));
@@ -914,51 +915,51 @@
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowLabelOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowLabelOp);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 4);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowZeroOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowZeroOp);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowClusterOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowClusterOp);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowZeroOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowZeroOp);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowLabelOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowLabelOp);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 5);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowCopyOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowCopyOp);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowClusterOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowClusterOp);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowLabelOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowLabelOp);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 6);
iter->Next();
@@ -1005,14 +1006,14 @@
ASSERT_FALSE(iter->AtEnd());
auto op = iter->Get();
- ASSERT_EQ(op->type, kCowLabelOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowLabelOp);
ASSERT_EQ(GetCowOpSourceInfoData(*op), 50);
iter->Next();
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowReplaceOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowReplaceOp);
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
ASSERT_EQ(sink, data2);
@@ -1020,7 +1021,7 @@
ASSERT_FALSE(iter->AtEnd());
op = iter->Get();
- ASSERT_EQ(op->type, kCowClusterOp);
+ ASSERT_EQ(GetCowOpSourceInfoType(*op), kCowClusterOp);
iter->Next();
@@ -1117,12 +1118,12 @@
num_in_cluster++;
max_in_cluster = std::max(max_in_cluster, num_in_cluster);
- if (op->type == kCowReplaceOp) {
+ if (GetCowOpSourceInfoType(*op) == kCowReplaceOp) {
num_replace++;
ASSERT_EQ(op->new_block, num_replace);
ASSERT_TRUE(CompareDataBlock(&reader, op, "Block " + std::to_string(num_replace)));
- } else if (op->type == kCowClusterOp) {
+ } else if (GetCowOpSourceInfoType(*op) == kCowClusterOp) {
num_in_cluster = 0;
num_clusters++;
}
@@ -1178,12 +1179,12 @@
num_in_cluster++;
max_in_cluster = std::max(max_in_cluster, num_in_cluster);
- if (op->type == kCowReplaceOp) {
+ if (GetCowOpSourceInfoType(*op) == kCowReplaceOp) {
num_replace++;
ASSERT_EQ(op->new_block, num_replace);
ASSERT_TRUE(CompareDataBlock(&reader, op, "Block " + std::to_string(num_replace)));
- } else if (op->type == kCowClusterOp) {
+ } else if (GetCowOpSourceInfoType(*op) == kCowClusterOp) {
num_in_cluster = 0;
num_clusters++;
}
@@ -1229,12 +1230,12 @@
num_in_cluster++;
max_in_cluster = std::max(max_in_cluster, num_in_cluster);
- if (op->type == kCowReplaceOp) {
+ if (GetCowOpSourceInfoType(*op) == kCowReplaceOp) {
num_replace++;
ASSERT_EQ(op->new_block, num_replace);
ASSERT_TRUE(CompareDataBlock(&reader, op, "Block " + std::to_string(num_replace)));
- } else if (op->type == kCowClusterOp) {
+ } else if (GetCowOpSourceInfoType(*op) == kCowClusterOp) {
num_in_cluster = 0;
num_clusters++;
}
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp
index 2373d4d..a4d617f 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp
@@ -49,5 +49,14 @@
std::unique_ptr<TemporaryFile> cow_;
};
+TEST_F(CowOperationV3Test, CowTypeTest) {
+ CowOperationV3 new_op;
+ CowOperationV2 old_op;
+ old_op.type = kCowReplaceOp;
+ ASSERT_NE(GetCowOpSourceInfoType(new_op), old_op.type);
+ SetCowOpSourceInfoType(&new_op, old_op.type);
+ ASSERT_EQ(GetCowOpSourceInfoType(new_op), old_op.type);
+}
+
} // namespace snapshot
} // namespace android
\ No newline at end of file
diff --git a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp
index 6dc082e..0be6ff5 100644
--- a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp
@@ -25,6 +25,7 @@
#include <csignal>
#include <optional>
#include <set>
+#include "libsnapshot/cow_format.h"
#include <android-base/file.h>
#include <android-base/logging.h>
@@ -406,9 +407,9 @@
break;
}
- if (cow_op->type == kCowReplaceOp) {
+ if (GetCowOpSourceInfoType(*cow_op) == kCowReplaceOp) {
replace_ops++;
- } else if (cow_op->type == kCowZeroOp) {
+ } else if (GetCowOpSourceInfoType(*cow_op) == kCowZeroOp) {
zero_ops++;
}
@@ -540,7 +541,7 @@
chunk_vec_.push_back(std::make_pair(ChunkToSector(data_chunk_id), cow_op));
offset += sizeof(struct disk_exception);
num_ops += 1;
- if (cow_op->type == kCowCopyOp) {
+ if (GetCowOpSourceInfoType(*cow_op) == kCowCopyOp) {
copy_ops++;
}
diff --git a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_readahead.cpp b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_readahead.cpp
index ab0b309..b2a4f2c 100644
--- a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_readahead.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_readahead.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "libsnapshot/cow_format.h"
#include "snapuserd.h"
#include <csignal>
@@ -192,7 +193,7 @@
const CowOperation* cow_op = GetRAOpIter();
CHECK_NE(cow_op, nullptr);
*source_offset = GetCowOpSourceInfoData(*cow_op);
- if (cow_op->type == kCowCopyOp) {
+ if (GetCowOpSourceInfoData(*cow_op) == kCowCopyOp) {
*source_offset *= BLOCK_SZ;
}
RAIterNext();
@@ -211,7 +212,7 @@
const CowOperation* op = GetRAOpIter();
CHECK_NE(op, nullptr);
uint64_t next_offset = GetCowOpSourceInfoData(*op);
- if (op->type == kCowCopyOp) {
+ if (GetCowOpSourceInfoData(*op) == kCowCopyOp) {
next_offset *= BLOCK_SZ;
}
if (next_offset + nr_consecutive * BLOCK_SZ != *source_offset) {
diff --git a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_worker.cpp b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_worker.cpp
index 571b352..0930a5d 100644
--- a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_worker.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_worker.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "libsnapshot/cow_format.h"
#include "snapuserd.h"
#include <csignal>
@@ -177,7 +178,7 @@
return false;
}
- switch (cow_op->type) {
+ switch (GetCowOpSourceInfoType(*cow_op)) {
case kCowReplaceOp: {
return ProcessReplaceOp(cow_op);
}
@@ -191,7 +192,8 @@
}
default: {
- SNAP_LOG(ERROR) << "Unsupported operation-type found: " << cow_op->type;
+ SNAP_LOG(ERROR) << "Unsupported operation-type found: "
+ << GetCowOpSourceInfoType(*cow_op);
}
}
return false;
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/merge_worker.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/merge_worker.cpp
index 11b8d7c..d06ba58 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/merge_worker.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/merge_worker.cpp
@@ -17,6 +17,7 @@
#include <pthread.h>
+#include "libsnapshot/cow_format.h"
#include "snapuserd_core.h"
#include "utility.h"
@@ -114,13 +115,13 @@
SNAP_LOG(ERROR) << "AcquireBuffer failed in MergeReplaceOps";
return false;
}
- if (cow_op->type == kCowReplaceOp) {
+ if (GetCowOpSourceInfoType(*cow_op) == kCowReplaceOp) {
if (!reader_->ReadData(cow_op, buffer, BLOCK_SZ)) {
SNAP_LOG(ERROR) << "Failed to read COW in merge";
return false;
}
} else {
- CHECK(cow_op->type == kCowZeroOp);
+ CHECK(GetCowOpSourceInfoType(*cow_op) == kCowZeroOp);
memset(buffer, 0, BLOCK_SZ);
}
}
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp
index 5cb13e8..ffa23ea 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp
@@ -18,6 +18,7 @@
#include <pthread.h>
+#include "libsnapshot/cow_format.h"
#include "snapuserd_core.h"
#include "utility.h"
@@ -63,7 +64,7 @@
<< " Op: " << *cow_op;
if (!android::base::ReadFullyAtOffset(backing_store_fd_, buffer, BLOCK_SZ, offset)) {
std::string op;
- if (cow_op->type == kCowCopyOp)
+ if (GetCowOpSourceInfoType(*cow_op) == kCowCopyOp)
op = "Copy-op";
else {
op = "Xor-op";
@@ -133,7 +134,7 @@
}
case MERGE_GROUP_STATE::GROUP_MERGE_PENDING: {
bool ret;
- if (cow_op->type == kCowCopyOp) {
+ if (GetCowOpSourceInfoType(*cow_op) == kCowCopyOp) {
ret = ProcessCopyOp(cow_op, buffer);
} else {
ret = ProcessXorOp(cow_op, buffer);
@@ -167,7 +168,7 @@
return false;
}
- switch (cow_op->type) {
+ switch (GetCowOpSourceInfoType(*cow_op)) {
case kCowReplaceOp: {
return ProcessReplaceOp(cow_op, buffer);
}
@@ -183,7 +184,7 @@
}
default: {
- SNAP_LOG(ERROR) << "Unknown operation-type found: " << cow_op->type;
+ SNAP_LOG(ERROR) << "Unknown operation-type found: " << GetCowOpSourceInfoType(*cow_op);
}
}
return false;
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
index e886ec3..536ff2f 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
@@ -24,6 +24,7 @@
#include <android-base/strings.h>
#include <snapuserd/dm_user_block_server.h>
+#include "libsnapshot/cow_format.h"
#include "merge_worker.h"
#include "read_worker.h"
@@ -196,13 +197,13 @@
while (!cowop_iter->AtEnd()) {
const CowOperation* cow_op = cowop_iter->Get();
- if (cow_op->type == kCowCopyOp) {
+ if (GetCowOpSourceInfoType(*cow_op) == kCowCopyOp) {
copy_ops += 1;
- } else if (cow_op->type == kCowReplaceOp) {
+ } else if (GetCowOpSourceInfoType(*cow_op) == kCowReplaceOp) {
replace_ops += 1;
- } else if (cow_op->type == kCowZeroOp) {
+ } else if (GetCowOpSourceInfoType(*cow_op) == kCowZeroOp) {
zero_ops += 1;
- } else if (cow_op->type == kCowXorOp) {
+ } else if (GetCowOpSourceInfoType(*cow_op) == kCowXorOp) {
xor_ops += 1;
}
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
index 998d233..d7d43a6 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
@@ -18,6 +18,7 @@
#include <pthread.h>
+#include "libsnapshot/cow_format.h"
#include "snapuserd_core.h"
#include "utility.h"
@@ -77,7 +78,7 @@
SNAP_LOG(ERROR) << "PrepareNextReadAhead operation has no source offset: " << *cow_op;
return nr_consecutive;
}
- if (cow_op->type == kCowXorOp) {
+ if (GetCowOpSourceInfoType(*cow_op) == kCowXorOp) {
xor_op_vec.push_back(cow_op);
}
@@ -106,7 +107,7 @@
break;
}
- if (op->type == kCowXorOp) {
+ if (GetCowOpSourceInfoType(*op) == kCowXorOp) {
xor_op_vec.push_back(op);
}