If the blocks are not overlapping, write
them in ascending order if userspace snapshots
are enabled.
Bug: 193863443
Test: OTA on pixel/CF
Signed-off-by: Akilesh Kailash <akailash@google.com>
Change-Id: Ic5719d1dc005ed88f739a642e4663fffccf7d795
diff --git a/payload_consumer/vabc_partition_writer.cc b/payload_consumer/vabc_partition_writer.cc
index ba0f484..a11bdf4 100644
--- a/payload_consumer/vabc_partition_writer.cc
+++ b/payload_consumer/vabc_partition_writer.cc
@@ -23,6 +23,7 @@
#include <utility>
#include <vector>
+#include <android-base/properties.h>
#include <brillo/secure_blob.h>
#include <libsnapshot/cow_writer.h>
@@ -167,20 +168,41 @@
merge_op.src_extent() == merge_op.dst_extent()) {
continue;
}
- // libsnapshot prefers blocks in reverse order, so if this isn't a self
- // overlapping OP, writing block in reverser order
+
+ const bool extent_overlap =
+ ExtentRanges::ExtentsOverlap(src_extent, dst_extent);
+ // TODO(193863443) Remove this check once this feature
+ // lands on all pixel devices.
+ const bool is_ascending = android::base::GetBoolProperty(
+ "ro.virtual_ab.userspace.snapshots.enabled", false);
+
// If this is a self-overlapping op and |dst_extent| comes after
// |src_extent|, we must write in reverse order for correctness.
+ //
// If this is self-overlapping op and |dst_extent| comes before
// |src_extent|, we must write in ascending order for correctness.
- if (ExtentRanges::ExtentsOverlap(src_extent, dst_extent) &&
- dst_extent.start_block() <= src_extent.start_block()) {
- for (size_t i = 0; i < dst_extent.num_blocks(); i++) {
- blocks_merge_order.push_back(dst_extent.start_block() + i);
+ //
+ // If this isn't a self overlapping op, write block in ascending order
+ // if userspace snapshots are enabled
+ if (extent_overlap) {
+ if (dst_extent.start_block() <= src_extent.start_block()) {
+ for (size_t i = 0; i < dst_extent.num_blocks(); i++) {
+ blocks_merge_order.push_back(dst_extent.start_block() + i);
+ }
+ } else {
+ for (int i = dst_extent.num_blocks() - 1; i >= 0; i--) {
+ blocks_merge_order.push_back(dst_extent.start_block() + i);
+ }
}
} else {
- for (int i = dst_extent.num_blocks() - 1; i >= 0; i--) {
- blocks_merge_order.push_back(dst_extent.start_block() + i);
+ if (is_ascending) {
+ for (size_t i = 0; i < dst_extent.num_blocks(); i++) {
+ blocks_merge_order.push_back(dst_extent.start_block() + i);
+ }
+ } else {
+ for (int i = dst_extent.num_blocks() - 1; i >= 0; i--) {
+ blocks_merge_order.push_back(dst_extent.start_block() + i);
+ }
}
}
}
diff --git a/payload_consumer/vabc_partition_writer_unittest.cc b/payload_consumer/vabc_partition_writer_unittest.cc
index fdfa0a6..f331091 100644
--- a/payload_consumer/vabc_partition_writer_unittest.cc
+++ b/payload_consumer/vabc_partition_writer_unittest.cc
@@ -18,6 +18,7 @@
#include <android-base/file.h>
#include <android-base/mapped_file.h>
+#include <android-base/properties.h>
#include <bsdiff/bsdiff.h>
#include <gtest/gtest.h>
#include <libsnapshot/cow_writer.h>
@@ -200,11 +201,20 @@
std::make_unique<android::snapshot::MockSnapshotWriter>(
android::snapshot::CowOptions{});
ON_CALL(*cow_writer, EmitLabel(_)).WillByDefault(Return(true));
- auto expected_merge_sequence = {11, 10, 14, 13};
+ auto expected_merge_sequence = {10, 11, 13, 14};
+ auto expected_merge_sequence_rev = {11, 10, 14, 13};
+ const bool is_ascending = android::base::GetBoolProperty(
+ "ro.virtual_ab.userspace.snapshots.enabled", false);
ON_CALL(*cow_writer, Initialize()).WillByDefault(Return(true));
- EXPECT_CALL(*cow_writer, EmitSequenceData(_, _))
- .With(Args<1, 0>(ElementsAreArray(expected_merge_sequence)))
- .WillOnce(Return(true));
+ if (!is_ascending) {
+ EXPECT_CALL(*cow_writer, EmitSequenceData(_, _))
+ .With(Args<1, 0>(ElementsAreArray(expected_merge_sequence_rev)))
+ .WillOnce(Return(true));
+ } else {
+ EXPECT_CALL(*cow_writer, EmitSequenceData(_, _))
+ .With(Args<1, 0>(ElementsAreArray(expected_merge_sequence)))
+ .WillOnce(Return(true));
+ }
EXPECT_CALL(*cow_writer, Initialize()).Times(1);
EXPECT_CALL(*cow_writer, EmitCopy(_, _)).Times(0);
EXPECT_CALL(*cow_writer, EmitRawBlocks(_, _, _)).WillOnce(Return(true));