Merge "Label keys with all the possible FBE prefixes that might apply"
diff --git a/Disk.cpp b/Disk.cpp
index b424aba..9c22400 100644
--- a/Disk.cpp
+++ b/Disk.cpp
@@ -24,6 +24,7 @@
 #include "Ext4Crypt.h"
 
 #include <android-base/file.h>
+#include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/logging.h>
 #include <diskconfig/diskconfig.h>
@@ -446,7 +447,8 @@
 status_t Disk::partitionMixed(int8_t ratio) {
     int res;
 
-    if (e4crypt_is_native()) {
+    if (e4crypt_is_native()
+            && !android::base::GetBoolProperty("persist.sys.adoptable_fbe", false)) {
         LOG(ERROR) << "Private volumes not yet supported on FBE devices";
         return -EINVAL;
     }
@@ -469,9 +471,14 @@
     // We've had some success above, so generate both the private partition
     // GUID and encryption key and persist them.
     std::string partGuidRaw;
+    if (GenerateRandomUuid(partGuidRaw) != OK) {
+        LOG(ERROR) << "Failed to generate GUID";
+        return -EIO;
+    }
+
     std::string keyRaw;
-    if (ReadRandomBytes(16, partGuidRaw) || ReadRandomBytes(16, keyRaw)) {
-        LOG(ERROR) << "Failed to generate GUID or key";
+    if (ReadRandomBytes(16, keyRaw) != OK) {
+        LOG(ERROR) << "Failed to generate key";
         return -EIO;
     }
 
diff --git a/MoveTask.cpp b/MoveTask.cpp
index ea64a1c..c565752 100644
--- a/MoveTask.cpp
+++ b/MoveTask.cpp
@@ -62,7 +62,8 @@
             StringPrintf("%d", progress).c_str(), false);
 }
 
-static status_t pushBackContents(const std::string& path, std::vector<std::string>& cmd) {
+static status_t pushBackContents(const std::string& path, std::vector<std::string>& cmd,
+        bool addWildcard) {
     DIR* dir = opendir(path.c_str());
     if (dir == NULL) {
         return -1;
@@ -73,7 +74,11 @@
         if ((!strcmp(ent->d_name, ".")) || (!strcmp(ent->d_name, ".."))) {
             continue;
         }
-        cmd.push_back(StringPrintf("%s/%s", path.c_str(), ent->d_name));
+        if (addWildcard) {
+            cmd.push_back(StringPrintf("%s/%s/*", path.c_str(), ent->d_name));
+        } else {
+            cmd.push_back(StringPrintf("%s/%s", path.c_str(), ent->d_name));
+        }
         found = true;
     }
     closedir(dir);
@@ -90,7 +95,7 @@
     cmd.push_back(kRmPath);
     cmd.push_back("-f"); /* force: remove without confirmation, no error if it doesn't exist */
     cmd.push_back("-R"); /* recursive: remove directory contents */
-    if (pushBackContents(path, cmd) != OK) {
+    if (pushBackContents(path, cmd, true) != OK) {
         LOG(WARNING) << "No contents in " << path;
         return OK;
     }
@@ -140,7 +145,7 @@
     cmd.push_back("-R"); /* recurse into subdirectories (DEST must be a directory) */
     cmd.push_back("-P"); /* Do not follow symlinks [default] */
     cmd.push_back("-d"); /* don't dereference symlinks */
-    if (pushBackContents(fromPath, cmd) != OK) {
+    if (pushBackContents(fromPath, cmd, false) != OK) {
         LOG(WARNING) << "No contents in " << fromPath;
         return OK;
     }
diff --git a/Utils.cpp b/Utils.cpp
index 529cfb2..9699777 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -372,6 +372,17 @@
     }
 }
 
+status_t GenerateRandomUuid(std::string& out) {
+    status_t res = ReadRandomBytes(16, out);
+    if (res == OK) {
+        out[6] &= 0x0f;  /* clear version        */
+        out[6] |= 0x40;  /* set to version 4     */
+        out[8] &= 0x3f;  /* clear variant        */
+        out[8] |= 0x80;  /* set to IETF variant  */
+    }
+    return res;
+}
+
 status_t HexToStr(const std::string& hex, std::string& str) {
     str.clear();
     bool even = true;
diff --git a/Utils.h b/Utils.h
index 813ffac..7272fe1 100644
--- a/Utils.h
+++ b/Utils.h
@@ -78,6 +78,7 @@
 pid_t ForkExecvpAsync(const std::vector<std::string>& args);
 
 status_t ReadRandomBytes(size_t bytes, std::string& out);
+status_t GenerateRandomUuid(std::string& out);
 
 /* Converts hex string to raw bytes, ignoring [ :-] */
 status_t HexToStr(const std::string& hex, std::string& str);
diff --git a/cryptfs.cpp b/cryptfs.cpp
index 484a107..43c8177 100644
--- a/cryptfs.cpp
+++ b/cryptfs.cpp
@@ -1938,15 +1938,17 @@
         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) {
-        args[0] = "/system/bin/mkfs.f2fs";
+        args[0] = "/system/bin/make_f2fs";
         args[1] = "-t";
         args[2] = "-d1";
-        args[3] = crypto_blkdev;
+        args[3] = "-f";
+        args[4] = "-O encrypt";
+        args[5] = crypto_blkdev;
         snprintf(size_str, sizeof(size_str), "%" PRId64, size);
-        args[4] = size_str;
-        num_args = 5;
-        SLOGI("Making empty filesystem with command %s %s %s %s %s\n",
-              args[0], args[1], args[2], args[3], args[4]);
+        args[6] = size_str;
+        num_args = 7;
+        SLOGI("Making empty filesystem with command %s %s %s %s %s %s %s\n",
+              args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
     } else {
         SLOGE("cryptfs_enable_wipe(): unknown filesystem type %d\n", type);
         return -1;
diff --git a/fs/Ext4.cpp b/fs/Ext4.cpp
index 0670bb5..041ce90 100644
--- a/fs/Ext4.cpp
+++ b/fs/Ext4.cpp
@@ -45,6 +45,7 @@
 #include <selinux/selinux.h>
 
 #include "Ext4.h"
+#include "Ext4Crypt.h"
 #include "Utils.h"
 #include "VoldUtil.h"
 
@@ -180,8 +181,13 @@
     cmd.push_back("-M");
     cmd.push_back(target);
 
+    std::string options("has_journal,quota");
+    if (e4crypt_is_native()) {
+        options += ",encrypt";
+    }
+
     cmd.push_back("-O");
-    cmd.push_back("^has_journal");
+    cmd.push_back(options);
 
     cmd.push_back(source);