libfiemap: Disable loop mapping code.

On devices without metadata encryption, we use loop devices rather than
device-mapper + dm-linear + FIEMAP. Devices without metadata encryption
should not exist, since libfiemap was introduced with Android R, which
requires metadata encryption.

It is possible to retrofit an Android Q device with Virtual A/B, which
is what Pixel 4 did. However those devices can only upgrade to
Android T, and they had metadata encryption anyway.

If there are any Android Q devices that retrofitted Virtual A/B in R,
didn't have metadata encryption, and need to upgrade all the way to V,
then we can recommend they make WrapUserdataIfNeeded() unconditional.

Bug: N/A
Test: fiemap_image_test, vts_libsnapshot_test
Change-Id: I7be0507527b967166676c8b136b8758f5e69ba6b
diff --git a/fs_mgr/libfiemap/image_manager.cpp b/fs_mgr/libfiemap/image_manager.cpp
index c416f4d..a5da6e3 100644
--- a/fs_mgr/libfiemap/image_manager.cpp
+++ b/fs_mgr/libfiemap/image_manager.cpp
@@ -531,11 +531,16 @@
     // If there is no intermediate device-mapper node, then partitions cannot be
     // opened writable due to sepolicy and exclusivity of having a mounted
     // filesystem. This should only happen on devices with no encryption, or
-    // devices with FBE and no metadata encryption. For these cases it suffices
-    // to perform normal file writes to /data/gsi (which is unencrypted).
+    // devices with FBE and no metadata encryption. For these cases we COULD
+    // perform normal writes to /data/gsi (which is unencrypted), but given that
+    // metadata encryption has been mandated since Android R, we don't actually
+    // support or test this.
     //
-    // Note: this is not gated on DeviceInfo, because the recovery-specific path
-    // must only be used in actual recovery.
+    // So, we validate here that /data is backed by device-mapper. This code
+    // isn't needed in recovery since there is no /data.
+    //
+    // If this logic sticks for a release, we can remove MapWithLoopDevice, as
+    // well as WrapUserdataIfNeeded in fs_mgr.
     std::string block_device;
     bool can_use_devicemapper;
     if (!FiemapWriter::GetBlockDeviceForFile(image_header, &block_device, &can_use_devicemapper)) {
@@ -543,21 +548,16 @@
         return false;
     }
 
-    if (can_use_devicemapper) {
-        if (!MapWithDmLinear(*partition_opener_.get(), name, timeout_ms, path)) {
-            return false;
-        }
-    } else if (!MapWithLoopDevice(name, timeout_ms, path)) {
-        return false;
-    }
-#else
-    // In recovery, we can *only* use device-mapper, since partitions aren't
-    // mounted. That also means we cannot call GetBlockDeviceForFile.
-    if (!MapWithDmLinear(*partition_opener_.get(), name, timeout_ms, path)) {
+    if (!can_use_devicemapper) {
+        LOG(ERROR) << "Cannot map image: /data must be mounted on top of device-mapper.";
         return false;
     }
 #endif
 
+    if (!MapWithDmLinear(*partition_opener_.get(), name, timeout_ms, path)) {
+        return false;
+    }
+
     // Set a property so we remember this is mapped.
     auto prop_name = GetStatusPropertyName(name);
     if (!android::base::SetProperty(prop_name, *path)) {