libsnapshot: Use pointers instead of references in ICowOpIter.

Most callers already converted the reference to a pointer, and pointers
will make it much easier to move around the op list.

Bug: 280529365
Test: builds
Change-Id: I7ec850b58a79c33e57b0e2602e1be953484daa46
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
index 73429e1..95a1270 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
@@ -63,7 +63,9 @@
     //
     // Partial reads are not possible unless |buffer_size| is less than the
     // operation block size.
-    virtual ssize_t ReadData(const CowOperation& op, void* buffer, size_t buffer_size,
+    //
+    // The operation pointer must derive from ICowOpIter::Get().
+    virtual ssize_t ReadData(const CowOperation* op, void* buffer, size_t buffer_size,
                              size_t ignore_bytes = 0) = 0;
 };
 
@@ -77,7 +79,7 @@
     virtual bool AtEnd() = 0;
 
     // Read the current operation.
-    virtual const CowOperation& Get() = 0;
+    virtual const CowOperation* Get() = 0;
 
     // Advance to the next item.
     virtual void Next() = 0;
@@ -121,7 +123,7 @@
     std::unique_ptr<ICowOpIter> GetRevMergeOpIter(bool ignore_progress = false) override;
     std::unique_ptr<ICowOpIter> GetMergeOpIter(bool ignore_progress = false) override;
 
-    ssize_t ReadData(const CowOperation& op, void* buffer, size_t buffer_size,
+    ssize_t ReadData(const CowOperation* op, void* buffer, size_t buffer_size,
                      size_t ignore_bytes = 0) override;
 
     CowHeader& GetHeader() override { return header_; }
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_api_test.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_api_test.cpp
index 7d1b7ba..edc9d65 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_api_test.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_api_test.cpp
@@ -46,7 +46,7 @@
 };
 
 // Helper to check read sizes.
-static inline bool ReadData(CowReader& reader, const CowOperation& op, void* buffer, size_t size) {
+static inline bool ReadData(CowReader& reader, const CowOperation* op, void* buffer, size_t size) {
     return reader.ReadData(op, buffer, size) == size;
 }
 
@@ -80,7 +80,7 @@
 
     size_t i = 0;
     while (!iter->AtEnd()) {
-        auto op = &iter->Get();
+        auto op = iter->Get();
         ASSERT_EQ(op->type, kCowCopyOp);
         ASSERT_EQ(op->compression, kCowCompressNone);
         ASSERT_EQ(op->data_length, 0);
@@ -126,7 +126,7 @@
     auto iter = reader.GetOpIter();
     ASSERT_NE(iter, nullptr);
     ASSERT_FALSE(iter->AtEnd());
-    auto op = &iter->Get();
+    auto op = iter->Get();
 
     ASSERT_EQ(op->type, kCowCopyOp);
     ASSERT_EQ(op->compression, kCowCompressNone);
@@ -138,18 +138,18 @@
 
     iter->Next();
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
 
     ASSERT_EQ(op->type, kCowReplaceOp);
     ASSERT_EQ(op->compression, kCowCompressNone);
     ASSERT_EQ(op->data_length, 4096);
     ASSERT_EQ(op->new_block, 50);
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
     ASSERT_EQ(sink, data);
 
     iter->Next();
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
 
     // Note: the zero operation gets split into two blocks.
     ASSERT_EQ(op->type, kCowZeroOp);
@@ -160,7 +160,7 @@
 
     iter->Next();
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
 
     ASSERT_EQ(op->type, kCowZeroOp);
     ASSERT_EQ(op->compression, kCowCompressNone);
@@ -205,7 +205,7 @@
     auto iter = reader.GetOpIter();
     ASSERT_NE(iter, nullptr);
     ASSERT_FALSE(iter->AtEnd());
-    auto op = &iter->Get();
+    auto op = iter->Get();
 
     ASSERT_EQ(op->type, kCowCopyOp);
     ASSERT_EQ(op->compression, kCowCompressNone);
@@ -217,19 +217,19 @@
 
     iter->Next();
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
 
     ASSERT_EQ(op->type, kCowXorOp);
     ASSERT_EQ(op->compression, kCowCompressNone);
     ASSERT_EQ(op->data_length, 4096);
     ASSERT_EQ(op->new_block, 50);
     ASSERT_EQ(op->source, 98314);  // 4096 * 24 + 10
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
     ASSERT_EQ(sink, data);
 
     iter->Next();
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
 
     // Note: the zero operation gets split into two blocks.
     ASSERT_EQ(op->type, kCowZeroOp);
@@ -240,7 +240,7 @@
 
     iter->Next();
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
 
     ASSERT_EQ(op->type, kCowZeroOp);
     ASSERT_EQ(op->compression, kCowCompressNone);
@@ -274,7 +274,7 @@
     auto iter = reader.GetOpIter();
     ASSERT_NE(iter, nullptr);
     ASSERT_FALSE(iter->AtEnd());
-    auto op = &iter->Get();
+    auto op = iter->Get();
 
     std::string sink(data.size(), '\0');
 
@@ -282,7 +282,7 @@
     ASSERT_EQ(op->compression, kCowCompressGz);
     ASSERT_EQ(op->data_length, 56);  // compressed!
     ASSERT_EQ(op->new_block, 50);
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
     ASSERT_EQ(sink, data);
 
     iter->Next();
@@ -329,14 +329,14 @@
 
     int total_blocks = 0;
     while (!iter->AtEnd()) {
-        auto op = &iter->Get();
+        auto op = iter->Get();
 
         if (op->type == kCowXorOp) {
             total_blocks += 1;
             std::string sink(xor_data.size(), '\0');
             ASSERT_EQ(op->new_block, 50);
             ASSERT_EQ(op->source, 98314);  // 4096 * 24 + 10
-            ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+            ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
             ASSERT_EQ(sink, xor_data);
         }
 
@@ -345,19 +345,19 @@
             if (op->new_block == 100) {
                 data.resize(options.block_size);
                 std::string sink(data.size(), '\0');
-                ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+                ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
                 ASSERT_EQ(sink.size(), data.size());
                 ASSERT_EQ(sink, data);
             }
             if (op->new_block == 6000) {
                 data2.resize(options.block_size);
                 std::string sink(data2.size(), '\0');
-                ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+                ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
                 ASSERT_EQ(sink, data2);
             }
             if (op->new_block == 9000) {
                 std::string sink(data3.size(), '\0');
-                ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+                ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
                 ASSERT_EQ(sink, data3);
             }
         }
@@ -403,25 +403,25 @@
 
     int total_blocks = 0;
     while (!iter->AtEnd()) {
-        auto op = &iter->Get();
+        auto op = iter->Get();
 
         if (op->type == kCowReplaceOp) {
             total_blocks += 1;
             if (op->new_block == 50) {
                 data.resize(options.block_size);
                 std::string sink(data.size(), '\0');
-                ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+                ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
                 ASSERT_EQ(sink, data);
             }
             if (op->new_block == 3000) {
                 data2.resize(options.block_size);
                 std::string sink(data2.size(), '\0');
-                ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+                ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
                 ASSERT_EQ(sink, data2);
             }
             if (op->new_block == 5000) {
                 std::string sink(data3.size(), '\0');
-                ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+                ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
                 ASSERT_EQ(sink, data3);
             }
         }
@@ -519,7 +519,7 @@
     auto iter = reader.GetOpIter();
     ASSERT_NE(iter, nullptr);
     ASSERT_FALSE(iter->AtEnd());
-    auto op = &iter->Get();
+    auto op = iter->Get();
 
     std::string sink(data.size(), '\0');
 
@@ -527,30 +527,30 @@
     ASSERT_EQ(op->compression, kCowCompressGz);
     ASSERT_EQ(op->data_length, 56);  // compressed!
     ASSERT_EQ(op->new_block, 50);
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
     ASSERT_EQ(sink, data);
 
     iter->Next();
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
 
     ASSERT_EQ(op->type, kCowClusterOp);
 
     iter->Next();
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
 
     sink = {};
     sink.resize(data2.size(), '\0');
     ASSERT_EQ(op->compression, kCowCompressGz);
     ASSERT_EQ(op->data_length, 41);  // compressed!
     ASSERT_EQ(op->new_block, 51);
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
     ASSERT_EQ(sink, data2);
 
     iter->Next();
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
 
     ASSERT_EQ(op->type, kCowClusterOp);
 
@@ -585,11 +585,11 @@
 
     std::string sink(options.block_size, '\0');
 
-    auto op = &iter->Get();
+    auto op = iter->Get();
     ASSERT_EQ(op->type, kCowReplaceOp);
     ASSERT_EQ(op->compression, kCowCompressGz);
     ASSERT_EQ(op->new_block, 51);
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
 }
 
 TEST_F(CowTest, GetSize) {
@@ -659,9 +659,9 @@
     ASSERT_NE(iter, nullptr);
 
     ASSERT_FALSE(iter->AtEnd());
-    auto op = &iter->Get();
+    auto op = iter->Get();
     ASSERT_EQ(op->type, kCowReplaceOp);
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
     ASSERT_EQ(sink, data);
 
     iter->Next();
@@ -669,16 +669,16 @@
     sink.resize(data2.size(), '\0');
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowLabelOp);
     ASSERT_EQ(op->source, 3);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowReplaceOp);
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
     ASSERT_EQ(sink, data2);
 
     iter->Next();
@@ -722,14 +722,14 @@
     ASSERT_NE(iter, nullptr);
 
     ASSERT_FALSE(iter->AtEnd());
-    auto op = &iter->Get();
+    auto op = iter->Get();
     ASSERT_EQ(op->type, kCowLabelOp);
     ASSERT_EQ(op->source, 0);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowZeroOp);
 
     iter->Next();
@@ -780,7 +780,7 @@
     ASSERT_NE(iter, nullptr);
 
     ASSERT_FALSE(iter->AtEnd());
-    auto op = &iter->Get();
+    auto op = iter->Get();
     ASSERT_EQ(op->type, kCowLabelOp);
     ASSERT_EQ(op->source, 5);
 
@@ -831,9 +831,9 @@
     ASSERT_NE(iter, nullptr);
 
     ASSERT_FALSE(iter->AtEnd());
-    auto op = &iter->Get();
+    auto op = iter->Get();
     ASSERT_EQ(op->type, kCowReplaceOp);
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
     ASSERT_EQ(sink, data.substr(0, options.block_size));
 
     iter->Next();
@@ -841,33 +841,33 @@
     sink.resize(options.block_size, '\0');
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowReplaceOp);
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
     ASSERT_EQ(sink, data.substr(options.block_size, 2 * options.block_size));
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowLabelOp);
     ASSERT_EQ(op->source, 4);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowZeroOp);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowZeroOp);
 
     iter->Next();
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowLabelOp);
     ASSERT_EQ(op->source, 5);
 
@@ -912,59 +912,59 @@
     ASSERT_NE(iter, nullptr);
 
     ASSERT_FALSE(iter->AtEnd());
-    auto op = &iter->Get();
+    auto op = iter->Get();
     ASSERT_EQ(op->type, kCowReplaceOp);
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
     ASSERT_EQ(sink, data.substr(0, options.block_size));
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowLabelOp);
     ASSERT_EQ(op->source, 4);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowZeroOp);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowClusterOp);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowZeroOp);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowLabelOp);
     ASSERT_EQ(op->source, 5);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowCopyOp);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowClusterOp);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowLabelOp);
     ASSERT_EQ(op->source, 6);
 
@@ -1011,22 +1011,22 @@
     ASSERT_NE(iter, nullptr);
 
     ASSERT_FALSE(iter->AtEnd());
-    auto op = &iter->Get();
+    auto op = iter->Get();
     ASSERT_EQ(op->type, kCowLabelOp);
     ASSERT_EQ(op->source, 50);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowReplaceOp);
-    ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
+    ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
     ASSERT_EQ(sink, data2);
 
     iter->Next();
 
     ASSERT_FALSE(iter->AtEnd());
-    op = &iter->Get();
+    op = iter->Get();
     ASSERT_EQ(op->type, kCowClusterOp);
 
     iter->Next();
@@ -1066,7 +1066,7 @@
     return AssertionSuccess();
 }
 
-AssertionResult CompareDataBlock(CowReader* reader, const CowOperation& op,
+AssertionResult CompareDataBlock(CowReader* reader, const CowOperation* op,
                                  const std::string& data) {
     const auto& header = reader->GetHeader();
 
@@ -1124,12 +1124,12 @@
         num_in_cluster++;
         max_in_cluster = std::max(max_in_cluster, num_in_cluster);
 
-        if (op.type == kCowReplaceOp) {
+        if (op->type == kCowReplaceOp) {
             num_replace++;
 
-            ASSERT_EQ(op.new_block, 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 (op->type == kCowClusterOp) {
             num_in_cluster = 0;
             num_clusters++;
         }
@@ -1185,12 +1185,12 @@
         num_in_cluster++;
         max_in_cluster = std::max(max_in_cluster, num_in_cluster);
 
-        if (op.type == kCowReplaceOp) {
+        if (op->type == kCowReplaceOp) {
             num_replace++;
 
-            ASSERT_EQ(op.new_block, 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 (op->type == kCowClusterOp) {
             num_in_cluster = 0;
             num_clusters++;
         }
@@ -1236,12 +1236,12 @@
 
         num_in_cluster++;
         max_in_cluster = std::max(max_in_cluster, num_in_cluster);
-        if (op.type == kCowReplaceOp) {
+        if (op->type == kCowReplaceOp) {
             num_replace++;
 
-            ASSERT_EQ(op.new_block, 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 (op->type == kCowClusterOp) {
             num_in_cluster = 0;
             num_clusters++;
         }
@@ -1278,7 +1278,7 @@
         ASSERT_TRUE(!iter->AtEnd());
         const auto& op = iter->Get();
 
-        ASSERT_EQ(op.new_block, seq_len - i);
+        ASSERT_EQ(op->new_block, seq_len - i);
 
         iter->Next();
     }
@@ -1345,7 +1345,7 @@
         ASSERT_FALSE(iter->AtEnd());
         const auto& op = iter->Get();
 
-        ASSERT_EQ(op.new_block, expected_block);
+        ASSERT_EQ(op->new_block, expected_block);
 
         iter->Next();
         expected_block--;
@@ -1395,7 +1395,7 @@
     while (!iter->AtEnd() && expected_new_block != revMergeOpSequence.end()) {
         const auto& op = iter->Get();
 
-        ASSERT_EQ(op.new_block, *expected_new_block);
+        ASSERT_EQ(op->new_block, *expected_new_block);
 
         iter->Next();
         expected_new_block++;
@@ -1444,7 +1444,7 @@
     while (!iter->AtEnd() && expected_new_block != revMergeOpSequence.end()) {
         const auto& op = iter->Get();
 
-        ASSERT_EQ(op.new_block, *expected_new_block);
+        ASSERT_EQ(op->new_block, *expected_new_block);
 
         iter->Next();
         expected_new_block++;
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
index bc65285..4c5a8bf 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
@@ -508,37 +508,37 @@
 
 bool CowReader::VerifyMergeOps() {
     auto itr = GetMergeOpIter(true);
-    std::unordered_map<uint64_t, CowOperation> overwritten_blocks;
+    std::unordered_map<uint64_t, const CowOperation*> overwritten_blocks;
     while (!itr->AtEnd()) {
-        CowOperation op = itr->Get();
+        const auto& op = itr->Get();
         uint64_t block;
         bool offset;
-        if (op.type == kCowCopyOp) {
-            block = op.source;
+        if (op->type == kCowCopyOp) {
+            block = op->source;
             offset = false;
-        } else if (op.type == kCowXorOp) {
-            block = op.source / header_.block_size;
-            offset = (op.source % header_.block_size) != 0;
+        } else if (op->type == kCowXorOp) {
+            block = op->source / header_.block_size;
+            offset = (op->source % header_.block_size) != 0;
         } else {
             itr->Next();
             continue;
         }
 
-        CowOperation* overwrite = nullptr;
+        const CowOperation* overwrite = nullptr;
         if (overwritten_blocks.count(block)) {
-            overwrite = &overwritten_blocks[block];
+            overwrite = overwritten_blocks[block];
             LOG(ERROR) << "Invalid Sequence! Block needed for op:\n"
                        << op << "\noverwritten by previously merged op:\n"
                        << *overwrite;
         }
         if (offset && overwritten_blocks.count(block + 1)) {
-            overwrite = &overwritten_blocks[block + 1];
+            overwrite = overwritten_blocks[block + 1];
             LOG(ERROR) << "Invalid Sequence! Block needed for op:\n"
                        << op << "\noverwritten by previously merged op:\n"
                        << *overwrite;
         }
         if (overwrite != nullptr) return false;
-        overwritten_blocks[op.new_block] = op;
+        overwritten_blocks[op->new_block] = op;
         itr->Next();
     }
     return true;
@@ -561,7 +561,7 @@
     CowOpIter(std::shared_ptr<std::vector<CowOperation>>& ops, uint64_t start);
 
     bool AtEnd() override;
-    const CowOperation& Get() override;
+    const CowOperation* Get() override;
     void Next() override;
 
     void Prev() override;
@@ -595,9 +595,9 @@
     op_iter_++;
 }
 
-const CowOperation& CowOpIter::Get() {
+const CowOperation* CowOpIter::Get() {
     CHECK(!AtEnd());
-    return (*op_iter_);
+    return &(*op_iter_);
 }
 
 class CowRevMergeOpIter final : public ICowOpIter {
@@ -606,7 +606,7 @@
                                std::shared_ptr<std::vector<int>> block_pos_index, uint64_t start);
 
     bool AtEnd() override;
-    const CowOperation& Get() override;
+    const CowOperation* Get() override;
     void Next() override;
 
     void Prev() override;
@@ -625,7 +625,7 @@
                             std::shared_ptr<std::vector<int>> block_pos_index, uint64_t start);
 
     bool AtEnd() override;
-    const CowOperation& Get() override;
+    const CowOperation* Get() override;
     void Next() override;
 
     void Prev() override;
@@ -664,9 +664,9 @@
     block_iter_++;
 }
 
-const CowOperation& CowMergeOpIter::Get() {
+const CowOperation* CowMergeOpIter::Get() {
     CHECK(!AtEnd());
-    return ops_->data()[*block_iter_];
+    return &ops_->data()[*block_iter_];
 }
 
 CowRevMergeOpIter::CowRevMergeOpIter(std::shared_ptr<std::vector<CowOperation>> ops,
@@ -696,9 +696,9 @@
     block_riter_++;
 }
 
-const CowOperation& CowRevMergeOpIter::Get() {
+const CowOperation* CowRevMergeOpIter::Get() {
     CHECK(!AtEnd());
-    return ops_->data()[*block_riter_];
+    return &ops_->data()[*block_riter_];
 }
 
 std::unique_ptr<ICowOpIter> CowReader::GetOpIter(bool merge_progress) {
@@ -765,10 +765,10 @@
     size_t remaining_;
 };
 
-ssize_t CowReader::ReadData(const CowOperation& op, void* buffer, size_t buffer_size,
+ssize_t CowReader::ReadData(const CowOperation* op, void* buffer, size_t buffer_size,
                             size_t ignore_bytes) {
     std::unique_ptr<IDecompressor> decompressor;
-    switch (op.compression) {
+    switch (op->compression) {
         case kCowCompressNone:
             break;
         case kCowCompressGz:
@@ -778,28 +778,28 @@
             decompressor = IDecompressor::Brotli();
             break;
         case kCowCompressLz4:
-            if (header_.block_size != op.data_length) {
+            if (header_.block_size != op->data_length) {
                 decompressor = IDecompressor::Lz4();
             }
             break;
         default:
-            LOG(ERROR) << "Unknown compression type: " << op.compression;
+            LOG(ERROR) << "Unknown compression type: " << op->compression;
             return -1;
     }
 
     uint64_t offset;
-    if (op.type == kCowXorOp) {
-        offset = data_loc_->at(op.new_block);
+    if (op->type == kCowXorOp) {
+        offset = data_loc_->at(op->new_block);
     } else {
-        offset = op.source;
+        offset = op->source;
     }
 
     if (!decompressor) {
-        CowDataStream stream(this, offset + ignore_bytes, op.data_length - ignore_bytes);
+        CowDataStream stream(this, offset + ignore_bytes, op->data_length - ignore_bytes);
         return stream.ReadFully(buffer, buffer_size);
     }
 
-    CowDataStream stream(this, offset, op.data_length);
+    CowDataStream stream(this, offset, op->data_length);
     decompressor->set_stream(&stream);
     return decompressor->Decompress(buffer, buffer_size, header_.block_size, ignore_bytes);
 }
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp
index cb20c6f..0e18979 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp
@@ -407,7 +407,7 @@
     auto iter = reader->GetOpIter();
 
     while (!iter->AtEnd()) {
-        AddOperation(iter->Get());
+        AddOperation(*iter->Get());
         iter->Next();
     }
 
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp
index 4090162..917cec4 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp
@@ -64,19 +64,19 @@
     bool include_merged;
 };
 
-static void ShowBad(CowReader& reader, const struct CowOperation& op) {
+static void ShowBad(CowReader& reader, const struct CowOperation* op) {
     size_t count;
-    auto buffer = std::make_unique<uint8_t[]>(op.data_length);
+    auto buffer = std::make_unique<uint8_t[]>(op->data_length);
 
-    if (!reader.GetRawBytes(op.source, buffer.get(), op.data_length, &count)) {
+    if (!reader.GetRawBytes(op->source, buffer.get(), op->data_length, &count)) {
         std::cerr << "Failed to read at all!\n";
     } else {
         std::cout << "The Block data is:\n";
-        for (int i = 0; i < op.data_length; i++) {
+        for (int i = 0; i < op->data_length; i++) {
             std::cout << std::hex << (int)buffer[i];
         }
         std::cout << std::dec << "\n\n";
-        if (op.data_length >= sizeof(CowOperation)) {
+        if (op->data_length >= sizeof(CowOperation)) {
             std::cout << "The start, as an op, would be " << *(CowOperation*)buffer.get() << "\n";
         }
     }
@@ -145,29 +145,29 @@
     bool success = true;
     uint64_t xor_ops = 0, copy_ops = 0, replace_ops = 0, zero_ops = 0;
     while (!iter->AtEnd()) {
-        const CowOperation& op = iter->Get();
+        const CowOperation* op = iter->Get();
 
-        if (!opt.silent && opt.show_ops) std::cout << op << "\n";
+        if (!opt.silent && opt.show_ops) std::cout << *op << "\n";
 
-        if (opt.decompress && op.type == kCowReplaceOp && op.compression != kCowCompressNone) {
+        if (opt.decompress && op->type == kCowReplaceOp && op->compression != kCowCompressNone) {
             if (reader.ReadData(op, buffer.data(), buffer.size()) < 0) {
-                std::cerr << "Failed to decompress for :" << op << "\n";
+                std::cerr << "Failed to decompress for :" << *op << "\n";
                 success = false;
                 if (opt.show_bad) ShowBad(reader, op);
             }
         }
 
-        if (op.type == kCowSequenceOp && opt.show_seq) {
+        if (op->type == kCowSequenceOp && opt.show_seq) {
             size_t read;
             std::vector<uint32_t> merge_op_blocks;
-            size_t seq_len = op.data_length / sizeof(uint32_t);
+            size_t seq_len = op->data_length / sizeof(uint32_t);
             merge_op_blocks.resize(seq_len);
-            if (!reader.GetRawBytes(op.source, merge_op_blocks.data(), op.data_length, &read)) {
+            if (!reader.GetRawBytes(op->source, merge_op_blocks.data(), op->data_length, &read)) {
                 PLOG(ERROR) << "Failed to read sequence op!";
                 return false;
             }
             if (!opt.silent) {
-                std::cout << "Sequence for " << op << " is :\n";
+                std::cout << "Sequence for " << *op << " is :\n";
                 for (size_t i = 0; i < seq_len; i++) {
                     std::cout << std::setfill('0') << std::setw(6) << merge_op_blocks[i] << ", ";
                     if ((i + 1) % 10 == 0 || i + 1 == seq_len) std::cout << "\n";
@@ -175,13 +175,13 @@
             }
         }
 
-        if (op.type == kCowCopyOp) {
+        if (op->type == kCowCopyOp) {
             copy_ops++;
-        } else if (op.type == kCowReplaceOp) {
+        } else if (op->type == kCowReplaceOp) {
             replace_ops++;
-        } else if (op.type == kCowZeroOp) {
+        } else if (op->type == kCowZeroOp) {
             zero_ops++;
-        } else if (op.type == kCowXorOp) {
+        } else if (op->type == kCowXorOp) {
             xor_ops++;
         }
 
diff --git a/fs_mgr/libsnapshot/snapshot_reader.cpp b/fs_mgr/libsnapshot/snapshot_reader.cpp
index 48efae0..4e75ba7 100644
--- a/fs_mgr/libsnapshot/snapshot_reader.cpp
+++ b/fs_mgr/libsnapshot/snapshot_reader.cpp
@@ -86,7 +86,7 @@
     // Populate the operation map.
     op_iter_ = cow_->GetOpIter();
     while (!op_iter_->AtEnd()) {
-        const CowOperation* op = &op_iter_->Get();
+        const CowOperation* op = op_iter_->Get();
         if (IsMetadataOp(*op)) {
             op_iter_->Next();
             continue;
@@ -205,7 +205,7 @@
     } else if (op->type == kCowZeroOp) {
         memset(buffer, 0, bytes_to_read);
     } else if (op->type == kCowReplaceOp) {
-        if (cow_->ReadData(*op, buffer, bytes_to_read, start_offset) < bytes_to_read) {
+        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;
@@ -226,7 +226,7 @@
             return -1;
         }
 
-        if (cow_->ReadData(*op, buffer, bytes_to_read, start_offset) < bytes_to_read) {
+        if (cow_->ReadData(op, buffer, bytes_to_read, start_offset) < bytes_to_read) {
             LOG(ERROR) << "CompressedSnapshotReader failed to read xor op";
             errno = EIO;
             return -1;
diff --git a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp
index b6e00ea..1fa4144 100644
--- a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp
@@ -391,7 +391,7 @@
     memset(de_ptr.get(), 0, (exceptions_per_area_ * sizeof(struct disk_exception)));
 
     while (!cowop_rm_iter->AtEnd()) {
-        const CowOperation* cow_op = &cowop_rm_iter->Get();
+        const CowOperation* cow_op = cowop_rm_iter->Get();
         struct disk_exception* de =
                 reinterpret_cast<struct disk_exception*>((char*)de_ptr.get() + offset);
 
@@ -459,7 +459,7 @@
 
     while (!cowop_rm_iter->AtEnd()) {
         do {
-            const CowOperation* cow_op = &cowop_rm_iter->Get();
+            const CowOperation* cow_op = cowop_rm_iter->Get();
 
             // We have two cases specific cases:
             //
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 31a80a3..922df34 100644
--- a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_worker.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_worker.cpp
@@ -100,7 +100,7 @@
         SNAP_LOG(ERROR) << "No space in buffer sink";
         return false;
     }
-    ssize_t rv = reader_->ReadData(*cow_op, buffer, BLOCK_SZ);
+    ssize_t rv = reader_->ReadData(cow_op, buffer, BLOCK_SZ);
     if (rv != BLOCK_SZ) {
         SNAP_LOG(ERROR) << "ProcessReplaceOp failed for block " << cow_op->new_block
                         << ", return = " << rv;
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 9df8cf9..a519639 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
@@ -186,7 +186,7 @@
     size_t copy_ops = 0, replace_ops = 0, zero_ops = 0, xor_ops = 0;
 
     while (!cowop_iter->AtEnd()) {
-        const CowOperation* cow_op = &cowop_iter->Get();
+        const CowOperation* cow_op = cowop_iter->Get();
 
         if (cow_op->type == kCowCopyOp) {
             copy_ops += 1;
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_dm_user.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_dm_user.cpp
index 3bc02d4..7858216 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_dm_user.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_dm_user.cpp
@@ -81,7 +81,7 @@
         SNAP_LOG(ERROR) << "ProcessReplaceOp failed to allocate buffer";
         return false;
     }
-    if (!reader_->ReadData(*cow_op, buffer, BLOCK_SZ)) {
+    if (!reader_->ReadData(cow_op, buffer, BLOCK_SZ)) {
         SNAP_LOG(ERROR) << "ProcessReplaceOp failed for block " << cow_op->new_block;
         return false;
     }
@@ -139,7 +139,7 @@
                         << actual;
         return false;
     }
-    ssize_t size = reader_->ReadData(*cow_op, buffer, BLOCK_SZ);
+    ssize_t size = reader_->ReadData(cow_op, buffer, BLOCK_SZ);
     if (size != BLOCK_SZ) {
         SNAP_LOG(ERROR) << "ProcessXorOp failed for block " << cow_op->new_block
                         << ", return value: " << size;
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
index 4d91ff3..ce95b76 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
@@ -31,7 +31,7 @@
 
     do {
         if (!cowop_iter_->AtEnd() && num_ops) {
-            const CowOperation* cow_op = &cowop_iter_->Get();
+            const CowOperation* cow_op = cowop_iter_->Get();
             if (checkOrderedOp && !IsOrderedOp(*cow_op)) {
                 break;
             }
@@ -46,7 +46,7 @@
             nr_consecutive = 1;
 
             while (!cowop_iter_->AtEnd() && num_ops) {
-                const CowOperation* op = &cowop_iter_->Get();
+                const CowOperation* op = cowop_iter_->Get();
                 if (checkOrderedOp && !IsOrderedOp(*op)) {
                     break;
                 }
@@ -181,7 +181,7 @@
     SNAP_LOG(INFO) << "MergeOrderedOpsAsync started....";
 
     while (!cowop_iter_->AtEnd()) {
-        const CowOperation* cow_op = &cowop_iter_->Get();
+        const CowOperation* cow_op = cowop_iter_->Get();
         if (!IsOrderedOp(*cow_op)) {
             break;
         }
@@ -362,7 +362,7 @@
     SNAP_LOG(INFO) << "MergeOrderedOps started....";
 
     while (!cowop_iter_->AtEnd()) {
-        const CowOperation* cow_op = &cowop_iter_->Get();
+        const CowOperation* cow_op = cowop_iter_->Get();
         if (!IsOrderedOp(*cow_op)) {
             break;
         }
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 4aad7a6..17f1f0e 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
@@ -492,7 +492,7 @@
                                     << xor_op->new_block;
                     return false;
                 }
-                if (ssize_t rv = reader_->ReadData(*xor_op, buffer, BLOCK_SZ); rv != BLOCK_SZ) {
+                if (ssize_t rv = reader_->ReadData(xor_op, buffer, BLOCK_SZ); rv != BLOCK_SZ) {
                     SNAP_LOG(ERROR)
                             << " ReadAhead - XorOp Read failed for block: " << xor_op->new_block
                             << ", return value: " << rv;
@@ -592,7 +592,7 @@
                     SNAP_LOG(ERROR) << "ReadAhead - failed to allocate buffer";
                     return false;
                 }
-                if (ssize_t rv = reader_->ReadData(*xor_op, buffer, BLOCK_SZ); rv != BLOCK_SZ) {
+                if (ssize_t rv = reader_->ReadData(xor_op, buffer, BLOCK_SZ); rv != BLOCK_SZ) {
                     SNAP_LOG(ERROR)
                             << " ReadAhead - XorOp Read failed for block: " << xor_op->new_block
                             << ", return value: " << rv;
@@ -834,8 +834,7 @@
 }
 
 const CowOperation* ReadAhead::GetRAOpIter() {
-    const CowOperation* cow_op = &cowop_iter_->Get();
-    return cow_op;
+    return cowop_iter_->Get();
 }
 
 void ReadAhead::InitializeBuffer() {