Workaround a kernel race when loading dmcrypt table

The kernel seems to return from umount(2) sometimes before it has
released the underlying block device.  So until the kernel is fixed,
try up to 10 times to load the crypto mapping table, waiting 500 ms
between tries.

bug: 7220345

Change-Id: Iad3bbef37cbe2e01613bb8a8c4886babdecb8328
diff --git a/cryptfs.c b/cryptfs.c
index b66f1ac..b2499aa 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -59,6 +59,8 @@
 #define EXT4_FS 1
 #define FAT_FS 2
 
+#define TABLE_LOAD_RETRIES 10
+
 char *me = "cryptfs";
 
 static unsigned char saved_master_key[KEY_LEN_BYTES];
@@ -385,6 +387,7 @@
   struct dm_target_spec *tgt;
   unsigned int minor;
   int fd;
+  int i;
   int retval = -1;
 
   if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
@@ -427,9 +430,18 @@
   crypt_params = (char *) (((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */
   tgt->next = crypt_params - buffer;
 
-  if (ioctl(fd, DM_TABLE_LOAD, io)) {
+  for (i = 0; i < TABLE_LOAD_RETRIES; i++) {
+    if (! ioctl(fd, DM_TABLE_LOAD, io)) {
+      break;
+    }
+    usleep(500000);
+  }
+
+  if (i == TABLE_LOAD_RETRIES) {
       SLOGE("Cannot load dm-crypt mapping table.\n");
       goto errout;
+  } else if (i) {
+      SLOGI("Took %d tries to load dmcrypt table.\n", i + 1);
   }
 
   /* Resume this device to activate it */