OSDN Git Service

Workaround a kernel race when loading dmcrypt table
authorKen Sumrall <ksumrall@android.com>
Sun, 30 Sep 2012 00:07:41 +0000 (17:07 -0700)
committerKen Sumrall <ksumrall@android.com>
Sun, 30 Sep 2012 00:24:46 +0000 (17:24 -0700)
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

cryptfs.c

index b66f1ac..b2499aa 100644 (file)
--- 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 @@ static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char
   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 @@ static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char
   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 */