Merge "SOURCE_COPY operation: implement src == dst" am: 8b8ffbb2df
am: 9528b20788
Change-Id: I029c3414eb9fa2b06088599d0691f4eea3bfb837
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index 7411e5a..8e3875f 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -72,6 +72,8 @@
static constexpr const std::string_view kCowGroupName = "cow";
+bool SourceCopyOperationIsClone(const chromeos_update_engine::InstallOperation& operation);
+
enum class UpdateState : unsigned int {
// No update or merge is in progress.
None,
diff --git a/fs_mgr/libsnapshot/partition_cow_creator.cpp b/fs_mgr/libsnapshot/partition_cow_creator.cpp
index 0ba2a88..61f5c0c 100644
--- a/fs_mgr/libsnapshot/partition_cow_creator.cpp
+++ b/fs_mgr/libsnapshot/partition_cow_creator.cpp
@@ -62,6 +62,19 @@
return false;
}
+bool SourceCopyOperationIsClone(const InstallOperation& operation) {
+ using ChromeOSExtent = chromeos_update_engine::Extent;
+ if (operation.src_extents().size() != operation.dst_extents().size()) {
+ return false;
+ }
+ return std::equal(operation.src_extents().begin(), operation.src_extents().end(),
+ operation.dst_extents().begin(),
+ [](const ChromeOSExtent& src, const ChromeOSExtent& dst) {
+ return src.start_block() == dst.start_block() &&
+ src.num_blocks() == dst.num_blocks();
+ });
+}
+
void WriteExtent(DmSnapCowSizeCalculator* sc, const chromeos_update_engine::Extent& de,
unsigned int sectors_per_block) {
const auto block_boundary = de.start_block() + de.num_blocks();
@@ -88,6 +101,11 @@
if (operations == nullptr) return sc.cow_size_bytes();
for (const auto& iop : *operations) {
+ // Do not allocate space for operations that are going to be skipped
+ // during OTA application.
+ if (iop.type() == InstallOperation::SOURCE_COPY && SourceCopyOperationIsClone(iop))
+ continue;
+
for (const auto& de : iop.dst_extents()) {
WriteExtent(&sc, de, sectors_per_block);
}