Merge "libsnapshot: Verify the ordering of COW operations." into main
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
index 489669a..f37aed1 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
@@ -310,9 +310,34 @@
 bool CowReader::VerifyMergeOps() {
     auto itr = GetMergeOpIter(true);
     std::unordered_map<uint64_t, const CowOperation*> overwritten_blocks;
+    bool non_ordered_op_found = false;
+
     while (!itr->AtEnd()) {
         const auto& op = itr->Get();
         uint64_t offset;
+
+        // Op should not be a metadata
+        if (IsMetadataOp(*op)) {
+            LOG(ERROR) << "Metadata op: " << op << " found during merge sequence";
+            return false;
+        }
+
+        // Sequence ops should contain all the ordered ops followed
+        // by Replace and Zero ops. If we find the first op which
+        // is not ordered, that means all ordered ops processing
+        // has been completed.
+        if (!IsOrderedOp(*op)) {
+            non_ordered_op_found = true;
+        }
+
+        // Since, all ordered ops processing has been completed,
+        // check that the subsequent ops are not ordered.
+        if (non_ordered_op_found && IsOrderedOp(*op)) {
+            LOG(ERROR) << "Invalid sequence - non-ordered and ordered ops"
+                       << " cannot be mixed during sequence generation";
+            return false;
+        }
+
         if (!GetSourceOffset(op, &offset)) {
             itr->Next();
             continue;