apkdmverity: Using LOOP_CONFIGURE

apkdmverity can attach a file to a loop device using LOOP_CONFIGURE
instead of LOOP_SET_FD/LOOP_SET_STATUS64 because it's more efficient.
The reason we used the latter was that LOOP_CONFIGURE didn't work then,
but the problem was only for the idsig file when it's attached to a loop
device using LO_FLAGS_DIRECT_IO.

I still don't know the reason, but at least we can use LOOP_CONFIGURE
and explicitly do not turn on Direct IO when attaching IDSIG file to a
loop device.

This is a partial revert of 7ce2e5352866e44e9499cf4dfbdee8c72ab8a7a4.

Bug: 191344832
Test: atest MicrodroidTestApp
Test: atest apkdmverity.test
Change-Id: I53a9da6d1d981b0d64a75bd362b09063570e7a68
diff --git a/apkdmverity/src/main.rs b/apkdmverity/src/main.rs
index dbf3131..16dd480 100644
--- a/apkdmverity/src/main.rs
+++ b/apkdmverity/src/main.rs
@@ -94,7 +94,11 @@
         if apk_size % BLOCK_SIZE != 0 {
             bail!("The size of {:?} is not multiple of {}.", &apk, BLOCK_SIZE)
         }
-        (loopdevice::attach(&apk, 0, apk_size)?, apk_size)
+        (
+            loopdevice::attach(&apk, 0, apk_size, /*direct_io*/ true)
+                .context("Failed to attach APK to a loop device")?,
+            apk_size,
+        )
     };
 
     // Parse the idsig file to locate the merkle tree in it, then attach the file to a loop device
@@ -105,7 +109,11 @@
     )?;
     let offset = sig.merkle_tree_offset;
     let size = sig.merkle_tree_size as u64;
-    let hash_device = loopdevice::attach(&idsig, offset, size)?;
+    // Due to unknown reason(b/191344832), we can't enable "direct IO" for the IDSIG file (backing
+    // the hash). For now we don't use "direct IO" but it seems OK since the IDSIG file is very
+    // small and the benefit of direct-IO would be negliable.
+    let hash_device = loopdevice::attach(&idsig, offset, size, /*direct_io*/ false)
+        .context("Failed to attach idsig to a loop device")?;
 
     // Build a dm-verity target spec from the information from the idsig file. The apk and the
     // idsig files are used as the data device and the hash device, respectively.
@@ -318,11 +326,11 @@
         // already a block device, `enable_verity` uses the block device as it is. The detatching
         // of the data device is done in the scopeguard for the return value of `enable_verity`
         // below. Only the idsig_loop_device needs detatching.
-        let apk_loop_device = loopdevice::attach(&apk_path, 0, apk_size).unwrap();
-        let idsig_loop_device =
-            scopeguard::guard(loopdevice::attach(&idsig_path, 0, idsig_size).unwrap(), |dev| {
-                loopdevice::detach(dev).unwrap()
-            });
+        let apk_loop_device = loopdevice::attach(&apk_path, 0, apk_size, true).unwrap();
+        let idsig_loop_device = scopeguard::guard(
+            loopdevice::attach(&idsig_path, 0, idsig_size, false).unwrap(),
+            |dev| loopdevice::detach(dev).unwrap(),
+        );
 
         let name = "loop_as_input";
         // Run the program WITH the loop devices, not the regular files.