Add support for creating ext4 images with mke2fs

We are investigating replacing make_ext4fs with the upstream tool mke2fs.
See b/23686092 for more informations.

To mitigate the trouble that may arise if the new tool behave differently
compared to the old one, there will be a transition period where both mke2fs
and make_ext4fs will be supported.

This patch does 3 things:
  - add the necessary code to use mke2fs to format an ext4 partition;
  - add a dependency to the binary used by vold.

Test: m -j32 with TARGET_USES_MKE2FS={,false,true}
                  TARGET_USERIMAGES_USE_EXT4={,true}

Change-Id: I89222642fe1d11a035155c8224b84b2e3719938b
diff --git a/Android.mk b/Android.mk
index 59a7ef4..d9f8753 100644
--- a/Android.mk
+++ b/Android.mk
@@ -71,6 +71,16 @@
 vold_conlyflags := -std=c11
 vold_cflags := -Werror -Wall -Wno-missing-field-initializers -Wno-unused-variable -Wno-unused-parameter
 
+required_modules :=
+ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
+  ifeq ($(TARGET_USES_MKE2FS), true)
+    vold_cflags += -DTARGET_USES_MKE2FS
+    required_modules += mke2fs
+  else
+    required_modules += make_ext4fs
+  endif
+endif
+
 include $(CLEAR_VARS)
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
@@ -83,6 +93,7 @@
 LOCAL_MODULE_TAGS := eng tests
 LOCAL_CFLAGS := $(vold_cflags)
 LOCAL_CONLYFLAGS := $(vold_conlyflags)
+LOCAL_REQUIRED_MODULES := $(required_modules)
 
 include $(BUILD_STATIC_LIBRARY)
 
@@ -109,6 +120,7 @@
 
 LOCAL_SHARED_LIBRARIES := $(common_shared_libraries)
 LOCAL_STATIC_LIBRARIES := $(common_static_libraries)
+LOCAL_REQUIRED_MODULES := $(required_modules)
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/cryptfs.c b/cryptfs.c
index a3ab2b9..4baa2db 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -2185,6 +2185,19 @@
     int rc = -1;
 
     if (type == EXT4_FS) {
+#ifdef TARGET_USES_MKE2FS
+        args[0] = "/system/bin/mke2fs";
+        args[1] = "-M";
+        args[2] = "/data";
+        args[3] = "-b";
+        args[4] = "4096";
+        args[5] = "-t";
+        args[6] = "ext4";
+        args[7] = crypto_blkdev;
+        snprintf(size_str, sizeof(size_str), "%" PRId64, size / (4096 / 512));
+        args[8] = size_str;
+        num_args = 9;
+#else
         args[0] = "/system/bin/make_ext4fs";
         args[1] = "-a";
         args[2] = "/data";
@@ -2193,6 +2206,7 @@
         args[4] = size_str;
         args[5] = crypto_blkdev;
         num_args = 6;
+#endif
         SLOGI("Making empty filesystem with command %s %s %s %s %s %s\n",
               args[0], args[1], args[2], args[3], args[4], args[5]);
     } else if (type == F2FS_FS) {
diff --git a/fs/Ext4.cpp b/fs/Ext4.cpp
index 0bd5b0c..0670bb5 100644
--- a/fs/Ext4.cpp
+++ b/fs/Ext4.cpp
@@ -55,7 +55,11 @@
 namespace ext4 {
 
 static const char* kResizefsPath = "/system/bin/resize2fs";
+#ifdef TARGET_USES_MKE2FS
+static const char* kMkfsPath = "/system/bin/mke2fs";
+#else
 static const char* kMkfsPath = "/system/bin/make_ext4fs";
+#endif
 static const char* kFsckPath = "/system/bin/e2fsck";
 
 bool IsSupported() {
@@ -165,6 +169,25 @@
         const std::string& target) {
     std::vector<std::string> cmd;
     cmd.push_back(kMkfsPath);
+
+#ifdef TARGET_USES_MKE2FS
+    cmd.push_back("-b");
+    cmd.push_back("4096");
+
+    cmd.push_back("-t");
+    cmd.push_back("ext4");
+
+    cmd.push_back("-M");
+    cmd.push_back(target);
+
+    cmd.push_back("-O");
+    cmd.push_back("^has_journal");
+
+    cmd.push_back(source);
+
+    if (numSectors)
+        cmd.push_back(StringPrintf("%lu", numSectors * (4096 / 512)));
+#else
     cmd.push_back("-J");
 
     cmd.push_back("-a");
@@ -178,6 +201,7 @@
     // Always generate a real UUID
     cmd.push_back("-u");
     cmd.push_back(source);
+#endif
 
     return ForkExecvp(cmd);
 }