diff --git a/Android.bp b/Android.bp
index d2c6ffc..1550264 100644
--- a/Android.bp
+++ b/Android.bp
@@ -41,7 +41,6 @@
         "libfec_rs",
         "libfs_avb",
         "libfs_mgr",
-        "libscrypt_static",
         "libsquashfs_utils",
         "libvold_binder",
     ],
@@ -108,6 +107,7 @@
     defaults: [
         "vold_default_flags",
         "vold_default_libs",
+        "keystore2_use_latest_aidl_ndk_shared",
     ],
 
     srcs: [
@@ -123,14 +123,13 @@
         "KeyBuffer.cpp",
         "KeyStorage.cpp",
         "KeyUtil.cpp",
-        "Keymaster.cpp",
+        "Keystore.cpp",
         "Loop.cpp",
         "MetadataCrypt.cpp",
         "MoveStorage.cpp",
         "NetlinkHandler.cpp",
         "NetlinkManager.cpp",
         "Process.cpp",
-        "ScryptParameters.cpp",
         "Utils.cpp",
         "VoldNativeService.cpp",
         "VoldNativeServiceValidation.cpp",
@@ -165,9 +164,8 @@
     },
     shared_libs: [
         "android.hardware.health.storage@1.0",
-        "android.hardware.health.storage-V1-ndk_platform",
-        "android.system.keystore2-V1-ndk_platform",
-        "android.security.maintenance-ndk_platform",
+        "android.hardware.health.storage-V1-ndk",
+        "android.security.maintenance-ndk",
         "libbinder_ndk",
         "libkeymint_support",
     ],
@@ -182,26 +180,25 @@
     defaults: [
         "vold_default_flags",
         "vold_default_libs",
+        "keystore2_use_latest_aidl_ndk_shared",
     ],
 
     srcs: ["main.cpp"],
     static_libs: ["libvold"],
     init_rc: [
         "vold.rc",
-        "wait_for_keymaster.rc",
     ],
 
     required: [
         "mke2fs",
         "vold_prepare_subdirs",
-        "wait_for_keymaster",
+        "fuse_media.o",
     ],
 
     shared_libs: [
         "android.hardware.health.storage@1.0",
-        "android.hardware.health.storage-V1-ndk_platform",
-        "android.system.keystore2-V1-ndk_platform",
-        "android.security.maintenance-ndk_platform",
+        "android.hardware.health.storage-V1-ndk",
+        "android.security.maintenance-ndk",
         "libbinder_ndk",
         "libkeymint_support",
     ],
@@ -237,30 +234,6 @@
     static_libs: [
         "libvold_binder",
     ],
-    init_rc: ["vdc.rc"],
-}
-
-cc_binary {
-    name: "wait_for_keymaster",
-    defaults: ["vold_default_flags"],
-
-    srcs: [
-        "wait_for_keymaster.cpp",
-        "Keymaster.cpp",
-    ],
-    shared_libs: [
-        "libbase",
-        "libbinder",
-        "libbinder_ndk",
-
-        "android.system.keystore2-V1-ndk_platform",
-        "android.security.maintenance-ndk_platform",
-        "libhardware",
-        "libhardware_legacy",
-        "libhidlbase",
-        "libkeymint_support",
-        "libutils",
-    ],
 }
 
 cc_binary {
diff --git a/Devmapper.cpp b/Devmapper.cpp
index d55d92d..00fb4b3 100644
--- a/Devmapper.cpp
+++ b/Devmapper.cpp
@@ -94,8 +94,6 @@
                     PLOG(WARNING) << "Failed to destroy dm device named " << device.name();
                 }
             }
-        } else {
-            LOG(DEBUG) << "Found unmanaged dm device named " << device.name();
         }
     }
     return 0;
diff --git a/FsCrypt.cpp b/FsCrypt.cpp
index 04def5c..be68222 100644
--- a/FsCrypt.cpp
+++ b/FsCrypt.cpp
@@ -186,10 +186,7 @@
     auto const current_path = get_ce_key_current_path(directory_path);
     if (to_fix != current_path) {
         LOG(DEBUG) << "Renaming " << to_fix << " to " << current_path;
-        if (rename(to_fix.c_str(), current_path.c_str()) != 0) {
-            PLOG(WARNING) << "Unable to rename " << to_fix << " to " << current_path;
-            return;
-        }
+        if (!android::vold::RenameKeyDir(to_fix, current_path)) return;
     }
     android::vold::FsyncDirectory(directory_path);
 }
@@ -211,7 +208,7 @@
     return false;
 }
 
-static bool IsEmmcStorage(const std::string& blk_device) {
+static bool MightBeEmmcStorage(const std::string& blk_device) {
     // Handle symlinks.
     std::string real_path;
     if (!Realpath(blk_device, &real_path)) {
@@ -227,8 +224,15 @@
     }
 
     // Now we should have the "real" block device.
-    LOG(DEBUG) << "IsEmmcStorage(): blk_device = " << blk_device << ", real_path=" << real_path;
-    return StartsWith(Basename(real_path), "mmcblk");
+    LOG(DEBUG) << "MightBeEmmcStorage(): blk_device = " << blk_device
+               << ", real_path=" << real_path;
+    std::string name = Basename(real_path);
+    return StartsWith(name, "mmcblk") ||
+           // virtio devices may provide inline encryption support that is
+           // backed by eMMC inline encryption on the host, thus inheriting the
+           // DUN size limitation.  So virtio devices must be allowed here too.
+           // TODO(b/207390665): check the maximum DUN size directly instead.
+           StartsWith(name, "vd");
 }
 
 // Retrieve the options to use for encryption policies on the /data filesystem.
@@ -244,7 +248,7 @@
         return false;
     }
     if ((options->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) &&
-        !IsEmmcStorage(entry->blk_device)) {
+        !MightBeEmmcStorage(entry->blk_device)) {
         LOG(ERROR) << "The emmc_optimized encryption flag is only allowed on eMMC storage.  Remove "
                       "this flag from the device's fstab";
         return false;
@@ -569,9 +573,12 @@
     if (it != s_ephemeral_users.end()) {
         s_ephemeral_users.erase(it);
     } else {
-        for (auto const path : get_ce_key_paths(get_ce_key_directory_path(user_id))) {
+        auto ce_path = get_ce_key_directory_path(user_id);
+        for (auto const path : get_ce_key_paths(ce_path)) {
             success &= android::vold::destroyKey(path);
         }
+        success &= destroy_dir(ce_path);
+
         auto de_key_path = get_de_key_path(user_id);
         if (android::vold::pathExists(de_key_path)) {
             success &= android::vold::destroyKey(de_key_path);
diff --git a/IdleMaint.cpp b/IdleMaint.cpp
index 8005cf4..769d7a5 100644
--- a/IdleMaint.cpp
+++ b/IdleMaint.cpp
@@ -85,6 +85,13 @@
  */
 static const int GC_TIMEOUT_SEC = 420;
 static const int DEVGC_TIMEOUT_SEC = 120;
+static const int KBYTES_IN_SEGMENT = 2048;
+static const int MIN_GC_URGENT_SLEEP_TIME = 500;
+static const int ONE_HOUR_IN_MS = 3600000;
+static const int GC_NORMAL_MODE = 0;
+static const int GC_URGENT_HIGH_MODE = 1;
+
+static int32_t previousSegmentWrite = 0;
 
 static IdleMaintStats idle_maint_stat(IdleMaintStats::kStopped);
 static std::condition_variable cv_abort, cv_stop;
@@ -111,7 +118,7 @@
     }
 }
 
-static void addFromFstab(std::list<std::string>* paths, PathTypes path_type) {
+static void addFromFstab(std::list<std::string>* paths, PathTypes path_type, bool only_data_part) {
     std::string previous_mount_point;
     for (const auto& entry : fstab_default) {
         // Skip raw partitions and swap space.
@@ -133,6 +140,10 @@
             continue;
         }
 
+        if (only_data_part && entry.mount_point != "/data") {
+            continue;
+        }
+
         // Skip the multi-type partitions, which are required to be following each other.
         // See fs_mgr.c's mount_with_alternatives().
         if (entry.mount_point == previous_mount_point) {
@@ -142,10 +153,10 @@
         if (path_type == PathTypes::kMountPoint) {
             paths->push_back(entry.mount_point);
         } else if (path_type == PathTypes::kBlkDevice) {
-            std::string gc_path;
+            std::string path;
             if (entry.fs_type == "f2fs" &&
-                Realpath(android::vold::BlockDeviceForPath(entry.mount_point + "/"), &gc_path)) {
-                paths->push_back("/sys/fs/" + entry.fs_type + "/" + Basename(gc_path));
+                Realpath(android::vold::BlockDeviceForPath(entry.mount_point + "/"), &path)) {
+                paths->push_back("/sys/fs/" + entry.fs_type + "/" + Basename(path));
             }
         }
 
@@ -161,7 +172,7 @@
 
     // Collect both fstab and vold volumes
     std::list<std::string> paths;
-    addFromFstab(&paths, PathTypes::kMountPoint);
+    addFromFstab(&paths, PathTypes::kMountPoint, false);
     addFromVolumeManager(&paths, PathTypes::kMountPoint);
 
     for (const auto& path : paths) {
@@ -264,15 +275,18 @@
     return android::OK;
 }
 
-static void runDevGcFstab(void) {
-    std::string path;
+static std::string getDevSysfsPath() {
     for (const auto& entry : fstab_default) {
         if (!entry.sysfs_path.empty()) {
-            path = entry.sysfs_path;
-            break;
+            return entry.sysfs_path;
         }
     }
+    LOG(WARNING) << "Cannot find dev sysfs path";
+    return "";
+}
 
+static void runDevGcFstab(void) {
+    std::string path = getDevSysfsPath();
     if (path.empty()) {
         return;
     }
@@ -402,8 +416,10 @@
     runDevGcFstab();
 }
 
-int RunIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener) {
+int RunIdleMaint(bool needGC, const android::sp<android::os::IVoldTaskListener>& listener) {
     std::unique_lock<std::mutex> lk(cv_m);
+    bool gc_aborted = false;
+
     if (idle_maint_stat != IdleMaintStats::kStopped) {
         LOG(DEBUG) << "idle maintenance is already running";
         if (listener) {
@@ -422,15 +438,17 @@
         return android::UNEXPECTED_NULL;
     }
 
-    std::list<std::string> paths;
-    addFromFstab(&paths, PathTypes::kBlkDevice);
-    addFromVolumeManager(&paths, PathTypes::kBlkDevice);
+    if (needGC) {
+        std::list<std::string> paths;
+        addFromFstab(&paths, PathTypes::kBlkDevice, false);
+        addFromVolumeManager(&paths, PathTypes::kBlkDevice);
 
-    startGc(paths);
+        startGc(paths);
 
-    bool gc_aborted = waitForGc(paths);
+        gc_aborted = waitForGc(paths);
 
-    stopGc(paths);
+        stopGc(paths);
+    }
 
     lk.lock();
     idle_maint_stat = IdleMaintStats::kStopped;
@@ -480,5 +498,150 @@
     return android::OK;
 }
 
+int getLifeTime(const std::string& path) {
+    std::string result;
+
+    if (!ReadFileToString(path, &result)) {
+        PLOG(WARNING) << "Reading lifetime estimation failed for " << path;
+        return -1;
+    }
+    return std::stoi(result, 0, 16);
+}
+
+int32_t GetStorageLifeTime() {
+    std::string path = getDevSysfsPath();
+    if (path.empty()) {
+        return -1;
+    }
+
+    std::string lifeTimeBasePath = path + "/health_descriptor/life_time_estimation_";
+
+    int32_t lifeTime = getLifeTime(lifeTimeBasePath + "c");
+    if (lifeTime != -1) {
+        return lifeTime;
+    }
+
+    int32_t lifeTimeA = getLifeTime(lifeTimeBasePath + "a");
+    int32_t lifeTimeB = getLifeTime(lifeTimeBasePath + "b");
+    lifeTime = std::max(lifeTimeA, lifeTimeB);
+    if (lifeTime != -1) {
+        return lifeTime == 0 ? -1 : lifeTime * 10;
+    }
+    return -1;
+}
+
+void SetGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, float dirtyReclaimRate,
+                     float reclaimWeight) {
+    std::list<std::string> paths;
+    bool needGC = true;
+
+    addFromFstab(&paths, PathTypes::kBlkDevice, true);
+    if (paths.empty()) {
+        LOG(WARNING) << "There is no valid blk device path for data partition";
+        return;
+    }
+
+    std::string f2fsSysfsPath = paths.front();
+    std::string freeSegmentsPath = f2fsSysfsPath + "/free_segments";
+    std::string dirtySegmentsPath = f2fsSysfsPath + "/dirty_segments";
+    std::string gcSleepTimePath = f2fsSysfsPath + "/gc_urgent_sleep_time";
+    std::string gcUrgentModePath = f2fsSysfsPath + "/gc_urgent";
+    std::string freeSegmentsStr, dirtySegmentsStr;
+
+    if (!ReadFileToString(freeSegmentsPath, &freeSegmentsStr)) {
+        PLOG(WARNING) << "Reading failed in " << freeSegmentsPath;
+        return;
+    }
+
+    if (!ReadFileToString(dirtySegmentsPath, &dirtySegmentsStr)) {
+        PLOG(WARNING) << "Reading failed in " << dirtySegmentsPath;
+        return;
+    }
+
+    int32_t freeSegments = std::stoi(freeSegmentsStr);
+    int32_t dirtySegments = std::stoi(dirtySegmentsStr);
+
+    neededSegments *= reclaimWeight;
+    if (freeSegments >= neededSegments) {
+        LOG(INFO) << "Enough free segments: " << freeSegments
+                   << ", needed segments: " << neededSegments;
+        needGC = false;
+    } else if (freeSegments + dirtySegments < minSegmentThreshold) {
+        LOG(INFO) << "The sum of free segments: " << freeSegments
+                   << ", dirty segments: " << dirtySegments << " is under " << minSegmentThreshold;
+        needGC = false;
+    }
+
+    if (!needGC) {
+        if (!WriteStringToFile(std::to_string(GC_NORMAL_MODE), gcUrgentModePath)) {
+            PLOG(WARNING) << "Writing failed in " << gcUrgentModePath;
+        }
+        return;
+    }
+
+    int32_t sleepTime;
+
+    neededSegments -= freeSegments;
+    neededSegments = std::min(neededSegments, (int32_t)(dirtySegments * dirtyReclaimRate));
+    if (neededSegments == 0) {
+        sleepTime = MIN_GC_URGENT_SLEEP_TIME;
+    } else {
+        sleepTime = ONE_HOUR_IN_MS / neededSegments;
+        if (sleepTime < MIN_GC_URGENT_SLEEP_TIME) {
+            sleepTime = MIN_GC_URGENT_SLEEP_TIME;
+        }
+    }
+    if (!WriteStringToFile(std::to_string(sleepTime), gcSleepTimePath)) {
+        PLOG(WARNING) << "Writing failed in " << gcSleepTimePath;
+        return;
+    }
+
+    if (!WriteStringToFile(std::to_string(GC_URGENT_HIGH_MODE), gcUrgentModePath)) {
+        PLOG(WARNING) << "Writing failed in " << gcUrgentModePath;
+        return;
+    }
+
+    LOG(INFO) << "Successfully set gc urgent mode: "
+               << "free segments: " << freeSegments << ", reclaim target: " << neededSegments
+               << ", sleep time: " << sleepTime;
+}
+
+static int32_t getLifeTimeWrite() {
+    std::list<std::string> paths;
+    addFromFstab(&paths, PathTypes::kBlkDevice, true);
+    if (paths.empty()) {
+        LOG(WARNING) << "There is no valid blk device path for data partition";
+        return -1;
+    }
+
+    std::string writeKbytesPath = paths.front() + "/lifetime_write_kbytes";
+    std::string writeKbytesStr;
+    if (!ReadFileToString(writeKbytesPath, &writeKbytesStr)) {
+        PLOG(WARNING) << "Reading failed in " << writeKbytesPath;
+        return -1;
+    }
+
+    long long writeBytes = std::stoll(writeKbytesStr);
+    return writeBytes / KBYTES_IN_SEGMENT;
+}
+
+void RefreshLatestWrite() {
+    int32_t segmentWrite = getLifeTimeWrite();
+    if (segmentWrite != -1) {
+        previousSegmentWrite = segmentWrite;
+    }
+}
+
+int32_t GetWriteAmount() {
+    int32_t currentSegmentWrite = getLifeTimeWrite();
+    if (currentSegmentWrite == -1) {
+        return -1;
+    }
+
+    int32_t writeAmount = currentSegmentWrite - previousSegmentWrite;
+    previousSegmentWrite = currentSegmentWrite;
+    return writeAmount;
+}
+
 }  // namespace vold
 }  // namespace android
diff --git a/IdleMaint.h b/IdleMaint.h
index e043db4..ae70b63 100644
--- a/IdleMaint.h
+++ b/IdleMaint.h
@@ -23,8 +23,13 @@
 namespace vold {
 
 void Trim(const android::sp<android::os::IVoldTaskListener>& listener);
-int RunIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener);
+int RunIdleMaint(bool needGC, const android::sp<android::os::IVoldTaskListener>& listener);
 int AbortIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener);
+int32_t GetStorageLifeTime();
+void SetGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, float dirtyReclaimRate,
+                     float reclaimWeight);
+void RefreshLatestWrite();
+int32_t GetWriteAmount();
 
 }  // namespace vold
 }  // namespace android
diff --git a/KeyStorage.cpp b/KeyStorage.cpp
index 11045a4..3ede67e 100644
--- a/KeyStorage.cpp
+++ b/KeyStorage.cpp
@@ -17,8 +17,7 @@
 #include "KeyStorage.h"
 
 #include "Checkpoint.h"
-#include "Keymaster.h"
-#include "ScryptParameters.h"
+#include "Keystore.h"
 #include "Utils.h"
 
 #include <algorithm>
@@ -45,11 +44,6 @@
 
 #include <cutils/properties.h>
 
-extern "C" {
-
-#include "crypto_scrypt.h"
-}
-
 namespace android {
 namespace vold {
 
@@ -123,51 +117,49 @@
     SHA512_Final(reinterpret_cast<uint8_t*>(&(*res)[0]), &c);
 }
 
-// Generates a keymaster key, using rollback resistance if supported.
-static bool generateKeymasterKey(Keymaster& keymaster,
-                                 const km::AuthorizationSetBuilder& paramBuilder,
-                                 std::string* key) {
+// Generates a keystore key, using rollback resistance if supported.
+static bool generateKeystoreKey(Keystore& keystore, const km::AuthorizationSetBuilder& paramBuilder,
+                                std::string* key) {
     auto paramsWithRollback = paramBuilder;
     paramsWithRollback.Authorization(km::TAG_ROLLBACK_RESISTANCE);
 
-    if (!keymaster.generateKey(paramsWithRollback, key)) {
-        LOG(WARNING) << "Failed to generate rollback-resistant key.  This is expected if keymaster "
+    if (!keystore.generateKey(paramsWithRollback, key)) {
+        LOG(WARNING) << "Failed to generate rollback-resistant key.  This is expected if keystore "
                         "doesn't support rollback resistance.  Falling back to "
                         "non-rollback-resistant key.";
-        if (!keymaster.generateKey(paramBuilder, key)) return false;
+        if (!keystore.generateKey(paramBuilder, key)) return false;
     }
     return true;
 }
 
-static bool generateKeyStorageKey(Keymaster& keymaster, const std::string& appId,
-                                  std::string* key) {
+static bool generateKeyStorageKey(Keystore& keystore, const std::string& appId, std::string* key) {
     auto paramBuilder = km::AuthorizationSetBuilder()
                                 .AesEncryptionKey(AES_KEY_BYTES * 8)
                                 .GcmModeMinMacLen(GCM_MAC_BYTES * 8)
                                 .Authorization(km::TAG_APPLICATION_ID, appId)
                                 .Authorization(km::TAG_NO_AUTH_REQUIRED);
     LOG(DEBUG) << "Generating \"key storage\" key";
-    return generateKeymasterKey(keymaster, paramBuilder, key);
+    return generateKeystoreKey(keystore, paramBuilder, key);
 }
 
 bool generateWrappedStorageKey(KeyBuffer* key) {
-    Keymaster keymaster;
-    if (!keymaster) return false;
+    Keystore keystore;
+    if (!keystore) return false;
     std::string key_temp;
     auto paramBuilder = km::AuthorizationSetBuilder().AesEncryptionKey(AES_KEY_BYTES * 8);
     paramBuilder.Authorization(km::TAG_STORAGE_KEY);
-    if (!generateKeymasterKey(keymaster, paramBuilder, &key_temp)) return false;
+    if (!generateKeystoreKey(keystore, paramBuilder, &key_temp)) return false;
     *key = KeyBuffer(key_temp.size());
     memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
     return true;
 }
 
-bool exportWrappedStorageKey(const KeyBuffer& kmKey, KeyBuffer* key) {
-    Keymaster keymaster;
-    if (!keymaster) return false;
+bool exportWrappedStorageKey(const KeyBuffer& ksKey, KeyBuffer* key) {
+    Keystore keystore;
+    if (!keystore) return false;
     std::string key_temp;
 
-    if (!keymaster.exportKey(kmKey, &key_temp)) return false;
+    if (!keystore.exportKey(ksKey, &key_temp)) return false;
     *key = KeyBuffer(key_temp.size());
     memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
     return true;
@@ -213,14 +205,15 @@
 
 static std::mutex key_upgrade_lock;
 
-// List of key directories that have had their Keymaster key upgraded during
+// List of key directories that have had their Keystore key upgraded during
 // this boot and written to "keymaster_key_blob_upgraded", but replacing the old
 // key was delayed due to an active checkpoint.  Protected by key_upgrade_lock.
+// A directory can be in this list at most once.
 static std::vector<std::string> key_dirs_to_commit;
 
 // Replaces |dir|/keymaster_key_blob with |dir|/keymaster_key_blob_upgraded and
-// deletes the old key from Keymaster.
-static bool CommitUpgradedKey(Keymaster& keymaster, const std::string& dir) {
+// deletes the old key from Keystore.
+static bool CommitUpgradedKey(Keystore& keystore, const std::string& dir) {
     auto blob_file = dir + "/" + kFn_keymaster_key_blob;
     auto upgraded_blob_file = dir + "/" + kFn_keymaster_key_blob_upgraded;
 
@@ -231,13 +224,13 @@
         PLOG(ERROR) << "Failed to rename " << upgraded_blob_file << " to " << blob_file;
         return false;
     }
-    // Ensure that the rename is persisted before deleting the Keymaster key.
+    // Ensure that the rename is persisted before deleting the Keystore key.
     if (!FsyncDirectory(dir)) return false;
 
-    if (!keymaster || !keymaster.deleteKey(blob)) {
+    if (!keystore || !keystore.deleteKey(blob)) {
         LOG(WARNING) << "Failed to delete old key " << blob_file
-                     << " from Keymaster; continuing anyway";
-        // Continue on, but the space in Keymaster used by the old key won't be freed.
+                     << " from Keystore; continuing anyway";
+        // Continue on, but the space in Keystore used by the old key won't be freed.
     }
     return true;
 }
@@ -245,20 +238,20 @@
 static void DeferredCommitKeys() {
     android::base::WaitForProperty("vold.checkpoint_committed", "1");
     LOG(INFO) << "Committing upgraded keys";
-    Keymaster keymaster;
-    if (!keymaster) {
-        LOG(ERROR) << "Failed to open Keymaster; old keys won't be deleted from Keymaster";
-        // Continue on, but the space in Keymaster used by the old keys won't be freed.
+    Keystore keystore;
+    if (!keystore) {
+        LOG(ERROR) << "Failed to open Keystore; old keys won't be deleted from Keystore";
+        // Continue on, but the space in Keystore used by the old keys won't be freed.
     }
     std::lock_guard<std::mutex> lock(key_upgrade_lock);
     for (auto& dir : key_dirs_to_commit) {
         LOG(INFO) << "Committing upgraded key " << dir;
-        CommitUpgradedKey(keymaster, dir);
+        CommitUpgradedKey(keystore, dir);
     }
     key_dirs_to_commit.clear();
 }
 
-// Returns true if the Keymaster key in |dir| has already been upgraded and is
+// Returns true if the Keystore key in |dir| has already been upgraded and is
 // pending being committed.  Assumes that key_upgrade_lock is held.
 static bool IsKeyCommitPending(const std::string& dir) {
     for (const auto& dir_to_commit : key_dirs_to_commit) {
@@ -267,8 +260,9 @@
     return false;
 }
 
-// Schedules the upgraded Keymaster key in |dir| to be committed later.
-// Assumes that key_upgrade_lock is held.
+// Schedules the upgraded Keystore key in |dir| to be committed later.  Assumes
+// that key_upgrade_lock is held and that a commit isn't already pending for the
+// directory.
 static void ScheduleKeyCommit(const std::string& dir) {
     if (key_dirs_to_commit.empty()) std::thread(DeferredCommitKeys).detach();
     key_dirs_to_commit.push_back(dir);
@@ -286,37 +280,41 @@
     }
 }
 
-// Renames a key directory. Also updates the deferred commit vector
-// (key_dirs_to_commit) appropriately.
-//
-// However, @old_name must be the path to the directory that was used to put that
-// directory into the deferred commit list in the first place (since this function
-// directly compares paths instead of using IsSameFile()).
-static bool RenameKeyDir(const std::string& old_name, const std::string& new_name) {
+bool RenameKeyDir(const std::string& old_name, const std::string& new_name) {
     std::lock_guard<std::mutex> lock(key_upgrade_lock);
 
-    if (rename(old_name.c_str(), new_name.c_str()) != 0) return false;
-
-    // IsSameFile() doesn't work here since we just renamed @old_name.
-    for (auto it = key_dirs_to_commit.begin(); it != key_dirs_to_commit.end(); it++) {
-        if (*it == old_name) *it = new_name;
+    // Find the entry in key_dirs_to_commit (if any) for this directory so that
+    // we can update it if the rename succeeds.  We don't allow duplicates in
+    // this list, so there can be at most one such entry.
+    auto it = key_dirs_to_commit.begin();
+    for (; it != key_dirs_to_commit.end(); it++) {
+        if (IsSameFile(old_name, *it)) break;
     }
+
+    if (rename(old_name.c_str(), new_name.c_str()) != 0) {
+        PLOG(ERROR) << "Failed to rename key directory \"" << old_name << "\" to \"" << new_name
+                    << "\"";
+        return false;
+    }
+
+    if (it != key_dirs_to_commit.end()) *it = new_name;
+
     return true;
 }
 
 // Deletes a leftover upgraded key, if present.  An upgraded key can be left
 // over if an update failed, or if we rebooted before committing the key in a
 // freak accident.  Either way, we can re-upgrade the key if we need to.
-static void DeleteUpgradedKey(Keymaster& keymaster, const std::string& path) {
+static void DeleteUpgradedKey(Keystore& keystore, const std::string& path) {
     if (pathExists(path)) {
         LOG(DEBUG) << "Deleting leftover upgraded key " << path;
         std::string blob;
         if (!android::base::ReadFileToString(path, &blob)) {
             LOG(WARNING) << "Failed to read leftover upgraded key " << path
                          << "; continuing anyway";
-        } else if (!keymaster.deleteKey(blob)) {
+        } else if (!keystore.deleteKey(blob)) {
             LOG(WARNING) << "Failed to delete leftover upgraded key " << path
-                         << " from Keymaster; continuing anyway";
+                         << " from Keystore; continuing anyway";
         }
         if (unlink(path.c_str()) != 0) {
             LOG(WARNING) << "Failed to unlink leftover upgraded key " << path
@@ -325,11 +323,11 @@
     }
 }
 
-// Begins a Keymaster operation using the key stored in |dir|.
-static KeymasterOperation BeginKeymasterOp(Keymaster& keymaster, const std::string& dir,
-                                           const km::AuthorizationSet& keyParams,
-                                           const km::AuthorizationSet& opParams,
-                                           km::AuthorizationSet* outParams) {
+// Begins a Keystore operation using the key stored in |dir|.
+static KeystoreOperation BeginKeystoreOp(Keystore& keystore, const std::string& dir,
+                                         const km::AuthorizationSet& keyParams,
+                                         const km::AuthorizationSet& opParams,
+                                         km::AuthorizationSet* outParams) {
     km::AuthorizationSet inParams(keyParams);
     inParams.append(opParams.begin(), opParams.end());
 
@@ -344,13 +342,13 @@
         LOG(DEBUG)
                 << blob_file
                 << " was already upgraded and is waiting to be committed; using the upgraded blob";
-        if (!readFileToString(upgraded_blob_file, &blob)) return KeymasterOperation();
+        if (!readFileToString(upgraded_blob_file, &blob)) return KeystoreOperation();
     } else {
-        DeleteUpgradedKey(keymaster, upgraded_blob_file);
-        if (!readFileToString(blob_file, &blob)) return KeymasterOperation();
+        DeleteUpgradedKey(keystore, upgraded_blob_file);
+        if (!readFileToString(blob_file, &blob)) return KeystoreOperation();
     }
 
-    auto opHandle = keymaster.begin(blob, inParams, outParams);
+    auto opHandle = keystore.begin(blob, inParams, outParams);
     if (!opHandle) return opHandle;
 
     // If key blob wasn't upgraded, nothing left to do.
@@ -359,29 +357,29 @@
     if (already_upgraded) {
         LOG(ERROR) << "Unexpected case; already-upgraded key " << upgraded_blob_file
                    << " still requires upgrade";
-        return KeymasterOperation();
+        return KeystoreOperation();
     }
     LOG(INFO) << "Upgrading key: " << blob_file;
     if (!writeStringToFile(*opHandle.getUpgradedBlob(), upgraded_blob_file))
-        return KeymasterOperation();
+        return KeystoreOperation();
     if (cp_needsCheckpoint()) {
         LOG(INFO) << "Wrote upgraded key to " << upgraded_blob_file
                   << "; delaying commit due to checkpoint";
         ScheduleKeyCommit(dir);
     } else {
-        if (!CommitUpgradedKey(keymaster, dir)) return KeymasterOperation();
+        if (!CommitUpgradedKey(keystore, dir)) return KeystoreOperation();
         LOG(INFO) << "Key upgraded: " << blob_file;
     }
     return opHandle;
 }
 
-static bool encryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir,
-                                    const km::AuthorizationSet& keyParams,
-                                    const KeyBuffer& message, std::string* ciphertext) {
+static bool encryptWithKeystoreKey(Keystore& keystore, const std::string& dir,
+                                   const km::AuthorizationSet& keyParams, const KeyBuffer& message,
+                                   std::string* ciphertext) {
     km::AuthorizationSet opParams =
             km::AuthorizationSetBuilder().Authorization(km::TAG_PURPOSE, km::KeyPurpose::ENCRYPT);
     km::AuthorizationSet outParams;
-    auto opHandle = BeginKeymasterOp(keymaster, dir, keyParams, opParams, &outParams);
+    auto opHandle = BeginKeystoreOp(keystore, dir, keyParams, opParams, &outParams);
     if (!opHandle) return false;
     auto nonceBlob = outParams.GetTagValue(km::TAG_NONCE);
     if (!nonceBlob) {
@@ -401,15 +399,15 @@
     return true;
 }
 
-static bool decryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir,
-                                    const km::AuthorizationSet& keyParams,
-                                    const std::string& ciphertext, KeyBuffer* message) {
+static bool decryptWithKeystoreKey(Keystore& keystore, const std::string& dir,
+                                   const km::AuthorizationSet& keyParams,
+                                   const std::string& ciphertext, KeyBuffer* message) {
     const std::string nonce = ciphertext.substr(0, GCM_NONCE_BYTES);
     auto bodyAndMac = ciphertext.substr(GCM_NONCE_BYTES);
     auto opParams = km::AuthorizationSetBuilder()
                             .Authorization(km::TAG_NONCE, nonce)
                             .Authorization(km::TAG_PURPOSE, km::KeyPurpose::DECRYPT);
-    auto opHandle = BeginKeymasterOp(keymaster, dir, keyParams, opParams, nullptr);
+    auto opHandle = BeginKeystoreOp(keystore, dir, keyParams, opParams, nullptr);
     if (!opHandle) return false;
     if (!opHandle.updateCompletely(bodyAndMac, message)) return false;
     if (!opHandle.finish(nullptr)) return false;
@@ -417,7 +415,7 @@
 }
 
 static std::string getStretching(const KeyAuthentication& auth) {
-    if (auth.usesKeymaster()) {
+    if (auth.usesKeystore()) {
         return kStretch_nopassword;
     } else {
         return kStretch_none;
@@ -467,8 +465,8 @@
     LOG(ERROR) << "Openssl error: " << ERR_get_error();
 }
 
-static bool encryptWithoutKeymaster(const std::string& preKey, const KeyBuffer& plaintext,
-                                    std::string* ciphertext) {
+static bool encryptWithoutKeystore(const std::string& preKey, const KeyBuffer& plaintext,
+                                   std::string* ciphertext) {
     std::string key;
     hashWithPrefix(kHashPrefix_keygen, preKey, &key);
     key.resize(AES_KEY_BYTES);
@@ -517,8 +515,8 @@
     return true;
 }
 
-static bool decryptWithoutKeymaster(const std::string& preKey, const std::string& ciphertext,
-                                    KeyBuffer* plaintext) {
+static bool decryptWithoutKeystore(const std::string& preKey, const std::string& ciphertext,
+                                   KeyBuffer* plaintext) {
     if (ciphertext.size() < GCM_NONCE_BYTES + GCM_MAC_BYTES) {
         LOG(ERROR) << "GCM ciphertext too small: " << ciphertext.size();
         return false;
@@ -569,7 +567,12 @@
     return true;
 }
 
-bool storeKey(const std::string& dir, const KeyAuthentication& auth, const KeyBuffer& key) {
+// Creates a directory at the given path |dir| and stores |key| in it, in such a
+// way that it can only be retrieved via Keystore (if no secret is given in
+// |auth|) or with the given secret (if a secret is given in |auth|), and can be
+// securely deleted.  If a storage binding seed has been set, then the storage
+// binding seed will be required to retrieve the key as well.
+static bool storeKey(const std::string& dir, const KeyAuthentication& auth, const KeyBuffer& key) {
     if (TEMP_FAILURE_RETRY(mkdir(dir.c_str(), 0700)) == -1) {
         PLOG(ERROR) << "key mkdir " << dir;
         return false;
@@ -582,16 +585,22 @@
     std::string appId;
     if (!generateAppId(auth, stretching, secdiscardable_hash, &appId)) return false;
     std::string encryptedKey;
-    if (auth.usesKeymaster()) {
-        Keymaster keymaster;
-        if (!keymaster) return false;
-        std::string kmKey;
-        if (!generateKeyStorageKey(keymaster, appId, &kmKey)) return false;
-        if (!writeStringToFile(kmKey, dir + "/" + kFn_keymaster_key_blob)) return false;
+    if (auth.usesKeystore()) {
+        Keystore keystore;
+        if (!keystore) return false;
+        std::string ksKey;
+        if (!generateKeyStorageKey(keystore, appId, &ksKey)) return false;
+        if (!writeStringToFile(ksKey, dir + "/" + kFn_keymaster_key_blob)) return false;
         km::AuthorizationSet keyParams = beginParams(appId);
-        if (!encryptWithKeymasterKey(keymaster, dir, keyParams, key, &encryptedKey)) return false;
+        if (!encryptWithKeystoreKey(keystore, dir, keyParams, key, &encryptedKey)) {
+            LOG(ERROR) << "encryptWithKeystoreKey failed";
+            return false;
+        }
     } else {
-        if (!encryptWithoutKeymaster(appId, key, &encryptedKey)) return false;
+        if (!encryptWithoutKeystore(appId, key, &encryptedKey)) {
+            LOG(ERROR) << "encryptWithoutKeystore failed";
+            return false;
+        }
     }
     if (!writeStringToFile(encryptedKey, dir + "/" + kFn_encrypted_key)) return false;
     if (!FsyncDirectory(dir)) return false;
@@ -610,10 +619,8 @@
     }
     if (!storeKey(tmp_path, auth, key)) return false;
 
-    if (!RenameKeyDir(tmp_path, key_path)) {
-        PLOG(ERROR) << "Unable to move new key to location: " << key_path;
-        return false;
-    }
+    if (!RenameKeyDir(tmp_path, key_path)) return false;
+
     if (!FsyncParentDirectory(key_path)) return false;
     LOG(DEBUG) << "Created key: " << key_path;
     return true;
@@ -634,25 +641,30 @@
     if (!generateAppId(auth, stretching, secdiscardable_hash, &appId)) return false;
     std::string encryptedMessage;
     if (!readFileToString(dir + "/" + kFn_encrypted_key, &encryptedMessage)) return false;
-    if (auth.usesKeymaster()) {
-        Keymaster keymaster;
-        if (!keymaster) return false;
+    if (auth.usesKeystore()) {
+        Keystore keystore;
+        if (!keystore) return false;
         km::AuthorizationSet keyParams = beginParams(appId);
-        if (!decryptWithKeymasterKey(keymaster, dir, keyParams, encryptedMessage, key))
+        if (!decryptWithKeystoreKey(keystore, dir, keyParams, encryptedMessage, key)) {
+            LOG(ERROR) << "decryptWithKeystoreKey failed";
             return false;
+        }
     } else {
-        if (!decryptWithoutKeymaster(appId, encryptedMessage, key)) return false;
+        if (!decryptWithoutKeystore(appId, encryptedMessage, key)) {
+            LOG(ERROR) << "decryptWithoutKeystore failed";
+            return false;
+        }
     }
     return true;
 }
 
-static bool DeleteKeymasterKey(const std::string& blob_file) {
+static bool DeleteKeystoreKey(const std::string& blob_file) {
     std::string blob;
     if (!readFileToString(blob_file, &blob)) return false;
-    Keymaster keymaster;
-    if (!keymaster) return false;
-    LOG(DEBUG) << "Deleting key " << blob_file << " from Keymaster";
-    if (!keymaster.deleteKey(blob)) return false;
+    Keystore keystore;
+    if (!keystore) return false;
+    LOG(DEBUG) << "Deleting key " << blob_file << " from Keystore";
+    if (!keystore.deleteKey(blob)) return false;
     return true;
 }
 
@@ -688,7 +700,7 @@
     for (auto& fn : {kFn_keymaster_key_blob, kFn_keymaster_key_blob_upgraded}) {
         auto blob_file = dir + "/" + fn;
         if (pathExists(blob_file)) {
-            success &= DeleteKeymasterKey(blob_file);
+            success &= DeleteKeystoreKey(blob_file);
             secdiscard_cmd.push_back(blob_file);
         }
     }
diff --git a/KeyStorage.h b/KeyStorage.h
index e318959..cc2f549 100644
--- a/KeyStorage.h
+++ b/KeyStorage.h
@@ -31,7 +31,7 @@
   public:
     KeyAuthentication(const std::string& s) : secret{s} {};
 
-    bool usesKeymaster() const { return secret.empty(); };
+    bool usesKeystore() const { return secret.empty(); };
 
     const std::string secret;
 };
@@ -41,11 +41,9 @@
 bool createSecdiscardable(const std::string& path, std::string* hash);
 bool readSecdiscardable(const std::string& path, std::string* hash);
 
-// Create a directory at the named path, and store "key" in it,
-// in such a way that it can only be retrieved via Keymaster and
-// can be securely deleted.
-// It's safe to move/rename the directory after creation.
-bool storeKey(const std::string& dir, const KeyAuthentication& auth, const KeyBuffer& key);
+// Renames a key directory while also managing deferred commits appropriately.
+// This method should be used whenever a key directory needs to be moved/renamed.
+bool RenameKeyDir(const std::string& old_name, const std::string& new_name);
 
 // Create a directory at the named path, and store "key" in it as storeKey
 // This version creates the key in "tmp_path" then atomically renames "tmp_path"
@@ -63,10 +61,10 @@
 
 bool runSecdiscardSingle(const std::string& file);
 
-// Generate wrapped storage key using keymaster. Uses STORAGE_KEY tag in keymaster.
+// Generate wrapped storage key using keystore. Uses STORAGE_KEY tag in keystore.
 bool generateWrappedStorageKey(KeyBuffer* key);
-// Export the per-boot boot wrapped storage key using keymaster.
-bool exportWrappedStorageKey(const KeyBuffer& kmKey, KeyBuffer* key);
+// Export the per-boot boot wrapped storage key using keystore.
+bool exportWrappedStorageKey(const KeyBuffer& ksKey, KeyBuffer* key);
 
 // Set a seed to be mixed into all key storage encryption keys.
 bool setKeyStorageBindingSeed(const std::vector<uint8_t>& seed);
diff --git a/KeyUtil.cpp b/KeyUtil.cpp
index 886054e..25d5af3 100644
--- a/KeyUtil.cpp
+++ b/KeyUtil.cpp
@@ -36,6 +36,9 @@
 namespace android {
 namespace vold {
 
+using android::fscrypt::EncryptionOptions;
+using android::fscrypt::EncryptionPolicy;
+
 const KeyGeneration neverGen() {
     return KeyGeneration{0, false, false};
 }
@@ -51,7 +54,10 @@
 }
 
 bool generateStorageKey(const KeyGeneration& gen, KeyBuffer* key) {
-    if (!gen.allow_gen) return false;
+    if (!gen.allow_gen) {
+        LOG(ERROR) << "Generating storage key not allowed";
+        return false;
+    }
     if (gen.use_hw_wrapped_key) {
         if (gen.keysize != FSCRYPT_MAX_KEY_SIZE) {
             LOG(ERROR) << "Cannot generate a wrapped key " << gen.keysize << " bytes long";
diff --git a/KeyUtil.h b/KeyUtil.h
index 73255a3..5940b8a 100644
--- a/KeyUtil.h
+++ b/KeyUtil.h
@@ -28,8 +28,6 @@
 namespace android {
 namespace vold {
 
-using namespace android::fscrypt;
-
 // Description of how to generate a key when needed.
 struct KeyGeneration {
     size_t keysize;
@@ -63,8 +61,8 @@
 //
 // Returns %true on success, %false on failure.  On success also sets *policy
 // to the EncryptionPolicy used to refer to this key.
-bool installKey(const std::string& mountpoint, const EncryptionOptions& options,
-                const KeyBuffer& key, EncryptionPolicy* policy);
+bool installKey(const std::string& mountpoint, const android::fscrypt::EncryptionOptions& options,
+                const KeyBuffer& key, android::fscrypt::EncryptionPolicy* policy);
 
 // Evict a file-based encryption key from the kernel.
 //
@@ -72,7 +70,7 @@
 //
 // If the kernel doesn't support the filesystem-level keyring, the caller is
 // responsible for dropping caches.
-bool evictKey(const std::string& mountpoint, const EncryptionPolicy& policy);
+bool evictKey(const std::string& mountpoint, const android::fscrypt::EncryptionPolicy& policy);
 
 // Retrieves the key from the named directory, or generates it if it doesn't
 // exist.
@@ -82,7 +80,8 @@
 
 // Re-installs a file-based encryption key of fscrypt-provisioning type from the
 // global session keyring back into fs keyring of the mountpoint.
-bool reloadKeyFromSessionKeyring(const std::string& mountpoint, const EncryptionPolicy& policy);
+bool reloadKeyFromSessionKeyring(const std::string& mountpoint,
+                                 const android::fscrypt::EncryptionPolicy& policy);
 
 }  // namespace vold
 }  // namespace android
diff --git a/Keymaster.cpp b/Keystore.cpp
similarity index 88%
rename from Keymaster.cpp
rename to Keystore.cpp
index 2314550..a017d68 100644
--- a/Keymaster.cpp
+++ b/Keystore.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "Keymaster.h"
+#include "Keystore.h"
 
 #include <android-base/logging.h>
 
@@ -43,7 +43,7 @@
 
 namespace ks2_maint = ::aidl::android::security::maintenance;
 
-KeymasterOperation::~KeymasterOperation() {
+KeystoreOperation::~KeystoreOperation() {
     if (ks2Operation) ks2Operation->abort();
 }
 
@@ -65,8 +65,8 @@
     return true;
 }
 
-bool KeymasterOperation::updateCompletely(const char* input, size_t inputLen,
-                                          const std::function<void(const char*, size_t)> consumer) {
+bool KeystoreOperation::updateCompletely(const char* input, size_t inputLen,
+                                         const std::function<void(const char*, size_t)> consumer) {
     if (!ks2Operation) return false;
 
     while (inputLen != 0) {
@@ -87,7 +87,7 @@
     return true;
 }
 
-bool KeymasterOperation::finish(std::string* output) {
+bool KeystoreOperation::finish(std::string* output) {
     std::optional<std::vector<uint8_t>> out_vec;
 
     if (!ks2Operation) return false;
@@ -103,7 +103,7 @@
     return true;
 }
 
-Keymaster::Keymaster() {
+Keystore::Keystore() {
     ::ndk::SpAIBinder binder(AServiceManager_waitForService(keystore2_service_name));
     auto keystore2Service = ks2::IKeystoreService::fromBinder(binder);
 
@@ -127,7 +127,7 @@
         LOG(ERROR) << "Vold unable to get security level from keystore2.";
 }
 
-bool Keymaster::generateKey(const km::AuthorizationSet& inParams, std::string* key) {
+bool Keystore::generateKey(const km::AuthorizationSet& inParams, std::string* key) {
     ks2::KeyDescriptor in_key = {
             .domain = ks2::Domain::BLOB,
             .alias = std::nullopt,
@@ -150,14 +150,14 @@
     return true;
 }
 
-bool Keymaster::exportKey(const KeyBuffer& kmKey, std::string* key) {
+bool Keystore::exportKey(const KeyBuffer& ksKey, std::string* key) {
     bool ret = false;
     ks2::KeyDescriptor storageKey = {
             .domain = ks2::Domain::BLOB,
             .alias = std::nullopt,
             .nspace = VOLD_NAMESPACE,
     };
-    storageKey.blob = std::make_optional<std::vector<uint8_t>>(kmKey.begin(), kmKey.end());
+    storageKey.blob = std::make_optional<std::vector<uint8_t>>(ksKey.begin(), ksKey.end());
     ks2::EphemeralStorageKeyResponse ephemeral_key_response;
     auto rc = securityLevel->convertStorageKeyToEphemeral(storageKey, &ephemeral_key_response);
 
@@ -175,7 +175,7 @@
     return ret;
 }
 
-bool Keymaster::deleteKey(const std::string& key) {
+bool Keystore::deleteKey(const std::string& key) {
     ks2::KeyDescriptor keyDesc = {
             .domain = ks2::Domain::BLOB,
             .alias = std::nullopt,
@@ -188,8 +188,8 @@
     return !logKeystore2ExceptionIfPresent(rc, "deleteKey");
 }
 
-KeymasterOperation Keymaster::begin(const std::string& key, const km::AuthorizationSet& inParams,
-                                    km::AuthorizationSet* outParams) {
+KeystoreOperation Keystore::begin(const std::string& key, const km::AuthorizationSet& inParams,
+                                  km::AuthorizationSet* outParams) {
     ks2::KeyDescriptor keyDesc = {
             .domain = ks2::Domain::BLOB,
             .alias = std::nullopt,
@@ -202,22 +202,22 @@
     auto rc = securityLevel->createOperation(keyDesc, inParams.vector_data(), true, &cor);
     if (logKeystore2ExceptionIfPresent(rc, "createOperation")) {
         if (rc.getExceptionCode() == EX_SERVICE_SPECIFIC)
-            return KeymasterOperation((km::ErrorCode)rc.getServiceSpecificError());
+            return KeystoreOperation((km::ErrorCode)rc.getServiceSpecificError());
         else
-            return KeymasterOperation();
+            return KeystoreOperation();
     }
 
     if (!cor.iOperation) {
         LOG(ERROR) << "keystore2 createOperation didn't return an operation";
-        return KeymasterOperation();
+        return KeystoreOperation();
     }
 
     if (outParams && cor.parameters) *outParams = cor.parameters->keyParameter;
 
-    return KeymasterOperation(cor.iOperation, cor.upgradedBlob);
+    return KeystoreOperation(cor.iOperation, cor.upgradedBlob);
 }
 
-void Keymaster::earlyBootEnded() {
+void Keystore::earlyBootEnded() {
     ::ndk::SpAIBinder binder(AServiceManager_getService(maintenance_service_name));
     auto maint_service = ks2_maint::IKeystoreMaintenance::fromBinder(binder);
 
@@ -230,7 +230,7 @@
     logKeystore2ExceptionIfPresent(rc, "earlyBootEnded");
 }
 
-void Keymaster::deleteAllKeys() {
+void Keystore::deleteAllKeys() {
     ::ndk::SpAIBinder binder(AServiceManager_getService(maintenance_service_name));
     auto maint_service = ks2_maint::IKeystoreMaintenance::fromBinder(binder);
 
diff --git a/Keymaster.h b/Keystore.h
similarity index 81%
rename from Keymaster.h
rename to Keystore.h
index 47bf4a2..d8c488e 100644
--- a/Keymaster.h
+++ b/Keystore.h
@@ -13,9 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// TODO: Maybe "Keymaster" should be replaced with Keystore2 everywhere?
-#ifndef ANDROID_VOLD_KEYMASTER_H
-#define ANDROID_VOLD_KEYMASTER_H
+#ifndef ANDROID_VOLD_KEYSTORE_H
+#define ANDROID_VOLD_KEYSTORE_H
 
 #include "KeyBuffer.h"
 
@@ -45,9 +44,9 @@
 // ongoing Keystore2 operation.  Aborts the operation
 // in the destructor if it is unfinished. Methods log failures
 // to LOG(ERROR).
-class KeymasterOperation {
+class KeystoreOperation {
   public:
-    ~KeymasterOperation();
+    ~KeystoreOperation();
     // Is this instance valid? This is false if creation fails, and becomes
     // false on finish or if an update fails.
     explicit operator bool() const { return (bool)ks2Operation; }
@@ -66,11 +65,11 @@
     // Finish and write the output to this string, unless pointer is null.
     bool finish(std::string* output);
     // Move constructor
-    KeymasterOperation(KeymasterOperation&& rhs) { *this = std::move(rhs); }
+    KeystoreOperation(KeystoreOperation&& rhs) { *this = std::move(rhs); }
     // Construct an object in an error state for error returns
-    KeymasterOperation() { errorCode = km::ErrorCode::UNKNOWN_ERROR; }
+    KeystoreOperation() { errorCode = km::ErrorCode::UNKNOWN_ERROR; }
     // Move Assignment
-    KeymasterOperation& operator=(KeymasterOperation&& rhs) {
+    KeystoreOperation& operator=(KeystoreOperation&& rhs) {
         ks2Operation = rhs.ks2Operation;
         rhs.ks2Operation = nullptr;
 
@@ -84,8 +83,8 @@
     }
 
   private:
-    KeymasterOperation(std::shared_ptr<ks2::IKeystoreOperation> ks2Op,
-                       std::optional<std::vector<uint8_t>> blob)
+    KeystoreOperation(std::shared_ptr<ks2::IKeystoreOperation> ks2Op,
+                      std::optional<std::vector<uint8_t>> blob)
         : ks2Operation{ks2Op}, errorCode{km::ErrorCode::OK} {
         if (blob)
             upgradedBlob = std::optional(std::string(blob->begin(), blob->end()));
@@ -93,7 +92,7 @@
             upgradedBlob = std::nullopt;
     }
 
-    KeymasterOperation(km::ErrorCode errCode) : errorCode{errCode} {}
+    KeystoreOperation(km::ErrorCode errCode) : errorCode{errCode} {}
 
     bool updateCompletely(const char* input, size_t inputLen,
                           const std::function<void(const char*, size_t)> consumer);
@@ -101,27 +100,27 @@
     std::shared_ptr<ks2::IKeystoreOperation> ks2Operation;
     std::optional<std::string> upgradedBlob;
     km::ErrorCode errorCode;
-    DISALLOW_COPY_AND_ASSIGN(KeymasterOperation);
-    friend class Keymaster;
+    DISALLOW_COPY_AND_ASSIGN(KeystoreOperation);
+    friend class Keystore;
 };
 
 // Wrapper for keystore2 methods that vold uses.
-class Keymaster {
+class Keystore {
   public:
-    Keymaster();
+    Keystore();
     // false if we failed to get a keystore2 security level.
     explicit operator bool() { return (bool)securityLevel; }
     // Generate a key using keystore2 from the given params.
     bool generateKey(const km::AuthorizationSet& inParams, std::string* key);
     // Exports a keystore2 key with STORAGE_KEY tag wrapped with a per-boot ephemeral key
-    bool exportKey(const KeyBuffer& kmKey, std::string* key);
+    bool exportKey(const KeyBuffer& ksKey, std::string* key);
     // If supported, permanently delete a key from the keymint device it belongs to.
     bool deleteKey(const std::string& key);
     // Begin a new cryptographic operation, collecting output parameters if pointer is non-null
-    // If the key was upgraded as a result of a call to this method, the returned KeymasterOperation
+    // If the key was upgraded as a result of a call to this method, the returned KeystoreOperation
     // also stores the upgraded key blob.
-    KeymasterOperation begin(const std::string& key, const km::AuthorizationSet& inParams,
-                             km::AuthorizationSet* outParams);
+    KeystoreOperation begin(const std::string& key, const km::AuthorizationSet& inParams,
+                            km::AuthorizationSet* outParams);
 
     // Tell all Keymint devices that early boot has ended and early boot-only keys can no longer
     // be created or used.
@@ -132,7 +131,7 @@
 
   private:
     std::shared_ptr<ks2::IKeystoreSecurityLevel> securityLevel;
-    DISALLOW_COPY_AND_ASSIGN(Keymaster);
+    DISALLOW_COPY_AND_ASSIGN(Keystore);
 };
 
 }  // namespace vold
diff --git a/Loop.cpp b/Loop.cpp
index 87f105d..4c86788 100644
--- a/Loop.cpp
+++ b/Loop.cpp
@@ -163,8 +163,6 @@
             if (ioctl(fd.get(), LOOP_CLR_FD, 0) < 0) {
                 PLOG(WARNING) << "Failed to LOOP_CLR_FD " << path;
             }
-        } else {
-            LOG(DEBUG) << "Found unmanaged loop device at " << path << " named " << id;
         }
     }
 
diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp
index 9038e8d..6550be4 100644
--- a/MetadataCrypt.cpp
+++ b/MetadataCrypt.cpp
@@ -38,7 +38,7 @@
 #include "EncryptInplace.h"
 #include "KeyStorage.h"
 #include "KeyUtil.h"
-#include "Keymaster.h"
+#include "Keystore.h"
 #include "Utils.h"
 #include "VoldUtil.h"
 #include "fs/Ext4.h"
@@ -49,8 +49,10 @@
 
 using android::fs_mgr::FstabEntry;
 using android::fs_mgr::GetEntryForMountPoint;
+using android::fscrypt::GetFirstApiLevel;
 using android::vold::KeyBuffer;
 using namespace android::dm;
+using namespace std::chrono_literals;
 
 // Parsed from metadata options
 struct CryptoOptions {
@@ -80,6 +82,17 @@
     return KeyGeneration{options.cipher.get_keysize(), true, options.use_hw_wrapped_key};
 }
 
+void defaultkey_precreate_dm_device() {
+    auto& dm = DeviceMapper::Instance();
+    if (dm.GetState(kDmNameUserdata) != DmDeviceState::INVALID) {
+        LOG(INFO) << "Not pre-creating userdata encryption device; device already exists";
+        return;
+    }
+    if (!dm.CreateEmptyDevice(kDmNameUserdata)) {
+        LOG(ERROR) << "Failed to pre-create userdata metadata encryption device";
+    }
+}
+
 static bool mount_via_fs_mgr(const char* mount_point, const char* blk_device) {
     // fs_mgr_do_mount runs fsck. Use setexeccon to run trusted
     // partitions in the fsck domain.
@@ -112,12 +125,14 @@
     auto dir = metadata_key_dir + "/key";
     LOG(DEBUG) << "metadata_key_dir/key: " << dir;
     if (!MkdirsSync(dir, 0700)) return false;
-    if (!pathExists(dir)) {
+    auto in_dsu = android::base::GetBoolProperty("ro.gsid.image_running", false);
+    // !pathExists(dir) does not imply there's a factory reset when in DSU mode.
+    if (!pathExists(dir) && !in_dsu) {
         auto delete_all = android::base::GetBoolProperty(
                 "ro.crypto.metadata_init_delete_all_keys.enabled", false);
         if (delete_all) {
             LOG(INFO) << "Metadata key does not exist, calling deleteAllKeys";
-            Keymaster::deleteAllKeys();
+            Keystore::deleteAllKeys();
         } else {
             LOG(DEBUG) << "Metadata key does not exist but "
                           "ro.crypto.metadata_init_delete_all_keys.enabled is false";
@@ -170,8 +185,18 @@
     table.AddTarget(std::move(target));
 
     auto& dm = DeviceMapper::Instance();
-    if (!dm.CreateDevice(dm_name, table, crypto_blkdev, std::chrono::seconds(5))) {
-        PLOG(ERROR) << "Could not create default-key device " << dm_name;
+    if (dm_name == kDmNameUserdata && dm.GetState(dm_name) == DmDeviceState::SUSPENDED) {
+        // The device was created in advance, populate it now.
+        if (!dm.LoadTableAndActivate(dm_name, table)) {
+            LOG(ERROR) << "Failed to populate default-key device " << dm_name;
+            return false;
+        }
+        if (!dm.WaitForDevice(dm_name, 5s, crypto_blkdev)) {
+            LOG(ERROR) << "Failed to wait for default-key device " << dm_name;
+            return false;
+        }
+    } else if (!dm.CreateDevice(dm_name, table, crypto_blkdev, 5s)) {
+        LOG(ERROR) << "Could not create default-key device " << dm_name;
         return false;
     }
     return true;
@@ -219,7 +244,8 @@
                << fs_type;
     auto encrypted_state = android::base::GetProperty("ro.crypto.state", "");
     if (encrypted_state != "" && encrypted_state != "encrypted") {
-        LOG(DEBUG) << "fscrypt_enable_crypto got unexpected starting state: " << encrypted_state;
+        LOG(ERROR) << "fscrypt_mount_metadata_encrypted got unexpected starting state: "
+                   << encrypted_state;
         return false;
     }
 
@@ -256,12 +282,18 @@
 
     auto gen = needs_encrypt ? makeGen(options) : neverGen();
     KeyBuffer key;
-    if (!read_key(data_rec->metadata_key_dir, gen, &key)) return false;
+    if (!read_key(data_rec->metadata_key_dir, gen, &key)) {
+        LOG(ERROR) << "read_key failed in mountFstab";
+        return false;
+    }
 
     std::string crypto_blkdev;
     uint64_t nr_sec;
-    if (!create_crypto_blk_dev(kDmNameUserdata, blk_device, key, options, &crypto_blkdev, &nr_sec))
+    if (!create_crypto_blk_dev(kDmNameUserdata, blk_device, key, options, &crypto_blkdev,
+                               &nr_sec)) {
+        LOG(ERROR) << "create_crypto_blk_dev failed in mountFstab";
         return false;
+    }
 
     if (needs_encrypt) {
         if (should_format) {
@@ -275,10 +307,17 @@
                 LOG(ERROR) << "Unknown filesystem type: " << fs_type;
                 return false;
             }
-            LOG(DEBUG) << "Format (err=" << error << ") " << crypto_blkdev << " on " << mount_point;
-            if (error != 0) return false;
+            if (error != 0) {
+                LOG(ERROR) << "Format of " << crypto_blkdev << " for " << mount_point
+                           << " failed (err=" << error << ").";
+                return false;
+            }
+            LOG(DEBUG) << "Format of " << crypto_blkdev << " for " << mount_point << " succeeded.";
         } else {
-            if (!encrypt_inplace(crypto_blkdev, blk_device, nr_sec, false)) return false;
+            if (!encrypt_inplace(crypto_blkdev, blk_device, nr_sec, false)) {
+                LOG(ERROR) << "encrypt_inplace failed in mountFstab";
+                return false;
+            }
         }
     }
 
diff --git a/MetadataCrypt.h b/MetadataCrypt.h
index e482765..06131ad 100644
--- a/MetadataCrypt.h
+++ b/MetadataCrypt.h
@@ -25,6 +25,7 @@
 namespace android {
 namespace vold {
 
+void defaultkey_precreate_dm_device();
 bool fscrypt_mount_metadata_encrypted(const std::string& block_device,
                                       const std::string& mount_point, bool needs_encrypt,
                                       bool should_format, const std::string& fs_type);
diff --git a/ScryptParameters.cpp b/ScryptParameters.cpp
deleted file mode 100644
index f5a964f..0000000
--- a/ScryptParameters.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "ScryptParameters.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-bool parse_scrypt_parameters(const char* paramstr, int* Nf, int* rf, int* pf) {
-    int params[3] = {};
-    char* token;
-    char* saveptr;
-    int i;
-
-    /*
-     * The token we're looking for should be three integers separated by
-     * colons (e.g., "12:8:1"). Scan the property to make sure it matches.
-     */
-    for (i = 0, token = strtok_r(const_cast<char*>(paramstr), ":", &saveptr);
-         token != nullptr && i < 3; i++, token = strtok_r(nullptr, ":", &saveptr)) {
-        char* endptr;
-        params[i] = strtol(token, &endptr, 10);
-
-        /*
-         * Check that there was a valid number and it's 8-bit.
-         */
-        if ((*token == '\0') || (*endptr != '\0') || params[i] < 0 || params[i] > 255) {
-            return false;
-        }
-    }
-    if (token != nullptr) {
-        return false;
-    }
-    *Nf = params[0];
-    *rf = params[1];
-    *pf = params[2];
-    return true;
-}
diff --git a/ScryptParameters.h b/ScryptParameters.h
deleted file mode 100644
index edb80cc..0000000
--- a/ScryptParameters.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_VOLD_SCRYPT_PARAMETERS_H
-#define ANDROID_VOLD_SCRYPT_PARAMETERS_H
-
-#include <stdbool.h>
-#include <sys/cdefs.h>
-
-#define SCRYPT_PROP "ro.crypto.scrypt_params"
-#define SCRYPT_DEFAULTS "15:3:1"
-
-bool parse_scrypt_parameters(const char* paramstr, int* Nf, int* rf, int* pf);
-
-#endif
diff --git a/Utils.cpp b/Utils.cpp
index 2144a3a..864cbf8 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -68,10 +68,10 @@
 namespace android {
 namespace vold {
 
-security_context_t sBlkidContext = nullptr;
-security_context_t sBlkidUntrustedContext = nullptr;
-security_context_t sFsckContext = nullptr;
-security_context_t sFsckUntrustedContext = nullptr;
+char* sBlkidContext = nullptr;
+char* sBlkidUntrustedContext = nullptr;
+char* sFsckContext = nullptr;
+char* sFsckUntrustedContext = nullptr;
 
 bool sSleepOnUnmount = true;
 
@@ -702,7 +702,7 @@
 }
 
 status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>* output,
-                    security_context_t context) {
+                    char* context) {
     auto argv = ConvertToArgv(args);
 
     android::base::unique_fd pipe_read, pipe_write;
@@ -754,7 +754,53 @@
     return OK;
 }
 
-pid_t ForkExecvpAsync(const std::vector<std::string>& args) {
+status_t ForkExecvpTimeout(const std::vector<std::string>& args, std::chrono::seconds timeout,
+                           char* context) {
+    int status;
+
+    pid_t wait_timeout_pid = fork();
+    if (wait_timeout_pid == 0) {
+        pid_t pid = ForkExecvpAsync(args, context);
+        if (pid == -1) {
+            _exit(EXIT_FAILURE);
+        }
+        pid_t timer_pid = fork();
+        if (timer_pid == 0) {
+            sleep(timeout.count());
+            _exit(ETIMEDOUT);
+        }
+        if (timer_pid == -1) {
+            PLOG(ERROR) << "fork in ForkExecvpAsync_timeout";
+            kill(pid, SIGTERM);
+            _exit(EXIT_FAILURE);
+        }
+        pid_t finished = wait(&status);
+        if (finished == pid) {
+            kill(timer_pid, SIGTERM);
+        } else {
+            kill(pid, SIGTERM);
+        }
+        if (!WIFEXITED(status)) {
+            _exit(ECHILD);
+        }
+        _exit(WEXITSTATUS(status));
+    }
+    if (waitpid(wait_timeout_pid, &status, 0) == -1) {
+        PLOG(ERROR) << "waitpid in ForkExecvpAsync_timeout";
+        return -errno;
+    }
+    if (!WIFEXITED(status)) {
+        LOG(ERROR) << "Process did not exit normally, status: " << status;
+        return -ECHILD;
+    }
+    if (WEXITSTATUS(status)) {
+        LOG(ERROR) << "Process exited with code: " << WEXITSTATUS(status);
+        return WEXITSTATUS(status);
+    }
+    return OK;
+}
+
+pid_t ForkExecvpAsync(const std::vector<std::string>& args, char* context) {
     auto argv = ConvertToArgv(args);
 
     pid_t pid = fork();
@@ -762,6 +808,12 @@
         close(STDIN_FILENO);
         close(STDOUT_FILENO);
         close(STDERR_FILENO);
+        if (context) {
+            if (setexeccon(context)) {
+                LOG(ERROR) << "Failed to setexeccon in ForkExecvpAsync";
+                abort();
+            }
+        }
 
         execvp(argv[0], const_cast<char**>(argv.data()));
         PLOG(ERROR) << "exec in ForkExecvpAsync";
@@ -1442,6 +1494,17 @@
     namespace fs = std::filesystem;
 
     for (const auto& itEntry : fs::directory_iterator("/sys/fs/fuse/connections")) {
+        std::string fsPath = itEntry.path().string() + "/filesystem";
+        std::string fs;
+
+        // Virtiofs is on top of fuse and there isn't any user space daemon.
+        // Android user space doesn't manage it.
+        if (android::base::ReadFileToString(fsPath, &fs, false) &&
+            android::base::Trim(fs) == "virtiofs") {
+            LOG(INFO) << "Ignore virtiofs connection entry " << itEntry.path().string();
+            continue;
+        }
+
         std::string abortPath = itEntry.path().string() + "/abort";
         LOG(DEBUG) << "Aborting fuse connection entry " << abortPath;
         bool ret = writeStringToFile("1", abortPath);
diff --git a/Utils.h b/Utils.h
index 54578b4..2d54639 100644
--- a/Utils.h
+++ b/Utils.h
@@ -37,12 +37,15 @@
 
 static const char* kVoldAppDataIsolationEnabled = "persist.sys.vold_app_data_isolation_enabled";
 static const char* kExternalStorageSdcardfs = "external_storage.sdcardfs.enabled";
+static const char* kFuseBpfEnabled = "persist.sys.fuse.bpf.enable";
+
+static constexpr std::chrono::seconds kUntrustedFsckSleepTime(45);
 
 /* SELinux contexts used depending on the block device type */
-extern security_context_t sBlkidContext;
-extern security_context_t sBlkidUntrustedContext;
-extern security_context_t sFsckContext;
-extern security_context_t sFsckUntrustedContext;
+extern char* sBlkidContext;
+extern char* sBlkidUntrustedContext;
+extern char* sFsckContext;
+extern char* sFsckUntrustedContext;
 
 // TODO remove this with better solution, b/64143519
 extern bool sSleepOnUnmount;
@@ -105,10 +108,12 @@
                                std::string* fsLabel);
 
 /* Returns either WEXITSTATUS() status, or a negative errno */
-status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>* output = nullptr,
-                    security_context_t context = nullptr);
+status_t ForkExecvp(const std::vector<std::string>& args,
+                    std::vector<std::string>* output = nullptr, char* context = nullptr);
+status_t ForkExecvpTimeout(const std::vector<std::string>& args, std::chrono::seconds timeout,
+                           char* context = nullptr);
 
-pid_t ForkExecvpAsync(const std::vector<std::string>& args);
+pid_t ForkExecvpAsync(const std::vector<std::string>& args, char* context = nullptr);
 
 /* Gets block device size in bytes */
 status_t GetBlockDevSize(int fd, uint64_t* size);
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index 4817ff1..1033af9 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -19,14 +19,13 @@
 #include "VoldNativeService.h"
 
 #include <android-base/logging.h>
-#include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <fs_mgr.h>
 #include <fscrypt/fscrypt.h>
 #include <private/android_filesystem_config.h>
 #include <utils/Trace.h>
 
-#include <sys/vfs.h>
+#include <stdio.h>
 #include <fstream>
 #include <thread>
 
@@ -35,18 +34,15 @@
 #include "FsCrypt.h"
 #include "IdleMaint.h"
 #include "KeyStorage.h"
-#include "Keymaster.h"
+#include "Keystore.h"
 #include "MetadataCrypt.h"
 #include "MoveStorage.h"
-#include "Process.h"
 #include "VoldNativeServiceValidation.h"
 #include "VoldUtil.h"
 #include "VolumeManager.h"
 #include "cryptfs.h"
 #include "incfs.h"
 
-using android::base::StringPrintf;
-using std::endl;
 using namespace std::literals;
 
 namespace android {
@@ -133,15 +129,14 @@
 }
 
 status_t VoldNativeService::dump(int fd, const Vector<String16>& /* args */) {
-    auto out = std::fstream(StringPrintf("/proc/self/fd/%d", fd));
     const binder::Status dump_permission = CheckPermission(kDump);
     if (!dump_permission.isOk()) {
-        out << dump_permission.toString8() << endl;
+        dprintf(fd, "%s\n", dump_permission.toString8().c_str());
         return PERMISSION_DENIED;
     }
 
     ACQUIRE_LOCK;
-    out << "vold is happy!" << endl;
+    dprintf(fd, "vold is happy!\n");
     return NO_ERROR;
 }
 
@@ -475,11 +470,11 @@
 }
 
 binder::Status VoldNativeService::runIdleMaint(
-        const android::sp<android::os::IVoldTaskListener>& listener) {
+        bool needGC, const android::sp<android::os::IVoldTaskListener>& listener) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_LOCK;
 
-    std::thread([=]() { android::vold::RunIdleMaint(listener); }).detach();
+    std::thread([=]() { android::vold::RunIdleMaint(needGC, listener); }).detach();
     return Ok();
 }
 
@@ -492,6 +487,40 @@
     return Ok();
 }
 
+binder::Status VoldNativeService::getStorageLifeTime(int32_t* _aidl_return) {
+    ENFORCE_SYSTEM_OR_ROOT;
+    ACQUIRE_LOCK;
+
+    *_aidl_return = GetStorageLifeTime();
+    return Ok();
+}
+
+binder::Status VoldNativeService::setGCUrgentPace(int32_t neededSegments,
+                                                  int32_t minSegmentThreshold,
+                                                  float dirtyReclaimRate, float reclaimWeight) {
+    ENFORCE_SYSTEM_OR_ROOT;
+    ACQUIRE_LOCK;
+
+    SetGCUrgentPace(neededSegments, minSegmentThreshold, dirtyReclaimRate, reclaimWeight);
+    return Ok();
+}
+
+binder::Status VoldNativeService::refreshLatestWrite() {
+    ENFORCE_SYSTEM_OR_ROOT;
+    ACQUIRE_LOCK;
+
+    RefreshLatestWrite();
+    return Ok();
+}
+
+binder::Status VoldNativeService::getWriteAmount(int32_t* _aidl_return) {
+    ENFORCE_SYSTEM_OR_ROOT;
+    ACQUIRE_LOCK;
+
+    *_aidl_return = GetWriteAmount();
+    return Ok();
+}
+
 binder::Status VoldNativeService::mountAppFuse(int32_t uid, int32_t mountId,
                                                android::base::unique_fd* _aidl_return) {
     ENFORCE_SYSTEM_OR_ROOT;
@@ -524,130 +553,107 @@
     return Ok();
 }
 
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::fdeCheckPassword(const std::string& password) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    return translate(cryptfs_check_passwd(password.c_str()));
+    SLOGE("fdeCheckPassword is no longer supported");
+    return translate(-1);
 }
 
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::fdeRestart() {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    // Spawn as thread so init can issue commands back to vold without
-    // causing deadlock, usually as a result of prep_data_fs.
-    std::thread(&cryptfs_restart).detach();
+    SLOGE("fdeRestart is no longer supported");
     return Ok();
 }
 
+// TODO(b/191796797) remove this once caller is removed
+#define CRYPTO_COMPLETE_NOT_ENCRYPTED 1
 binder::Status VoldNativeService::fdeComplete(int32_t* _aidl_return) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    *_aidl_return = cryptfs_crypto_complete();
+    SLOGE("fdeComplete is no longer supported");
+    *_aidl_return = CRYPTO_COMPLETE_NOT_ENCRYPTED;
     return Ok();
 }
 
-static int fdeEnableInternal(int32_t passwordType, const std::string& password,
-                             int32_t encryptionFlags) {
-    bool noUi = (encryptionFlags & VoldNativeService::ENCRYPTION_FLAG_NO_UI) != 0;
-
-    for (int tries = 0; tries < 2; ++tries) {
-        int rc;
-        if (passwordType == VoldNativeService::PASSWORD_TYPE_DEFAULT) {
-            rc = cryptfs_enable_default(noUi);
-        } else {
-            rc = cryptfs_enable(passwordType, password.c_str(), noUi);
-        }
-
-        if (rc == 0) {
-            return 0;
-        } else if (tries == 0) {
-            KillProcessesWithOpenFiles(DATA_MNT_POINT, SIGKILL);
-        }
-    }
-
-    return -1;
-}
-
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::fdeEnable(int32_t passwordType, const std::string& password,
                                             int32_t encryptionFlags) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    LOG(DEBUG) << "fdeEnable(" << passwordType << ", *, " << encryptionFlags << ")";
-    if (fscrypt_is_native()) {
-        LOG(ERROR) << "fscrypt_is_native, fdeEnable invalid";
-        return error("fscrypt_is_native, fdeEnable invalid");
-    }
-    LOG(DEBUG) << "!fscrypt_is_native, spawning fdeEnableInternal";
-
-    // Spawn as thread so init can issue commands back to vold without
-    // causing deadlock, usually as a result of prep_data_fs.
-    std::thread(&fdeEnableInternal, passwordType, password, encryptionFlags).detach();
-    return Ok();
+    SLOGE("fdeEnable is no longer supported");
+    return translate(-1);
 }
 
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::fdeChangePassword(int32_t passwordType,
                                                     const std::string& password) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    return translate(cryptfs_changepw(passwordType, password.c_str()));
+    SLOGE("fdeChangePassword is no longer supported");
+    return translate(-1);
 }
 
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::fdeVerifyPassword(const std::string& password) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    return translate(cryptfs_verify_passwd(password.c_str()));
+    SLOGE("fdeVerifyPassword is no longer supported");
+    return translate(-1);
 }
 
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::fdeGetField(const std::string& key, std::string* _aidl_return) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    char buf[PROPERTY_VALUE_MAX];
-    if (cryptfs_getfield(key.c_str(), buf, sizeof(buf)) != CRYPTO_GETFIELD_OK) {
-        return error(StringPrintf("Failed to read field %s", key.c_str()));
-    } else {
-        *_aidl_return = buf;
-        return Ok();
-    }
+    SLOGE("fdeGetField is no longer supported");
+    return translate(-1);
 }
 
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::fdeSetField(const std::string& key, const std::string& value) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    return translate(cryptfs_setfield(key.c_str(), value.c_str()));
+    SLOGE("fdeSetField is no longer supported");
+    return translate(-1);
 }
 
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::fdeGetPasswordType(int32_t* _aidl_return) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    *_aidl_return = cryptfs_get_password_type();
+    SLOGE("fdeGetPasswordType is no longer supported");
+    *_aidl_return = -1;
     return Ok();
 }
 
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::fdeGetPassword(std::string* _aidl_return) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    const char* res = cryptfs_get_password();
-    if (res != nullptr) {
-        *_aidl_return = res;
-    }
+    SLOGE("fdeGetPassword is no longer supported");
     return Ok();
 }
 
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::fdeClearPassword() {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    cryptfs_clear_password();
+    SLOGE("fdeClearPassword is no longer supported");
     return Ok();
 }
 
@@ -658,15 +664,12 @@
     return translateBool(fscrypt_initialize_systemwide_keys());
 }
 
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::mountDefaultEncrypted() {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    if (!fscrypt_is_native()) {
-        // Spawn as thread so init can issue commands back to vold without
-        // causing deadlock, usually as a result of prep_data_fs.
-        std::thread(&cryptfs_mount_default_encrypted).detach();
-    }
+    SLOGE("mountDefaultEncrypted is no longer supported");
     return Ok();
 }
 
@@ -677,11 +680,13 @@
     return translateBool(fscrypt_init_user0());
 }
 
+// TODO(b/191796797) remove this once caller is removed
 binder::Status VoldNativeService::isConvertibleToFbe(bool* _aidl_return) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    *_aidl_return = cryptfs_isConvertibleToFBE() != 0;
+    SLOGE("isConvertibleToFbe is no longer supported");
+    *_aidl_return = false;
     return Ok();
 }
 
@@ -940,44 +945,12 @@
     incfs::features();
 }
 
-// This is missing from the kernel UAPI headers.
-#define ST_RDONLY 0x0001
-
-// FDE devices run the post-fs-data trigger (and hence also earlyBootEnded)
-// multiple times, sometimes prior to the real /data being mounted.  That causes
-// keystore2 to try to open a file in /data, causing it to panic or have to be
-// killed by vold later, causing problems (vold failing to connect to keystore2,
-// or keystore2 operations erroring out later).  As a workaround to keep FDE
-// working, ignore these too-early calls to earlyBootEnded.
-//
-// This can be removed when support for FDE is removed.
-static bool IgnoreEarlyBootEnded() {
-    // The statfs("/data") below should be sufficient by itself, but to be safe
-    // we also explicitly return false on FBE devices.  (This really should be
-    // ro.crypto.type != "block" for "non-FDE devices", but on FDE devices this
-    // is sometimes called before ro.crypto.type gets set.)
-    if (fscrypt_is_native()) return false;
-
-    struct statfs buf;
-    if (statfs(DATA_MNT_POINT, &buf) != 0) {
-        PLOG(ERROR) << "statfs(\"/data\") failed";
-        return false;
-    }
-    if (buf.f_type == TMPFS_MAGIC || (buf.f_flags & ST_RDONLY)) {
-        LOG(INFO) << "Ignoring earlyBootEnded since real /data isn't mounted yet";
-        return true;
-    }
-    return false;
-}
-
 binder::Status VoldNativeService::earlyBootEnded() {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_LOCK;
 
-    if (IgnoreEarlyBootEnded()) return Ok();
-
     initializeIncFs();
-    Keymaster::earlyBootEnded();
+    Keystore::earlyBootEnded();
     return Ok();
 }
 
diff --git a/VoldNativeService.h b/VoldNativeService.h
index 5fa04f5..49bcbaa 100644
--- a/VoldNativeService.h
+++ b/VoldNativeService.h
@@ -85,8 +85,14 @@
 
     binder::Status fstrim(int32_t fstrimFlags,
                           const android::sp<android::os::IVoldTaskListener>& listener);
-    binder::Status runIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener);
+    binder::Status runIdleMaint(bool needGC,
+                                const android::sp<android::os::IVoldTaskListener>& listener);
     binder::Status abortIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener);
+    binder::Status getStorageLifeTime(int32_t* _aidl_return);
+    binder::Status setGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold,
+                                   float dirtyReclaimRate, float reclaimWeight);
+    binder::Status refreshLatestWrite();
+    binder::Status getWriteAmount(int32_t* _aidl_return);
 
     binder::Status mountAppFuse(int32_t uid, int32_t mountId,
                                 android::base::unique_fd* _aidl_return);
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 2697f67..9311321 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -239,7 +239,7 @@
             break;
         }
         case NetlinkEvent::Action::kChange: {
-            LOG(DEBUG) << "Disk at " << major << ":" << minor << " changed";
+            LOG(VERBOSE) << "Disk at " << major << ":" << minor << " changed";
             handleDiskChanged(device);
             break;
         }
@@ -899,10 +899,21 @@
     }
     mInternalEmulatedVolumes.clear();
 
+    // Destroy and recreate all disks except that StubVolume disks are just
+    // destroyed and removed from both mDisks and mPendingDisks.
+    // StubVolumes are managed from outside Android (e.g. from Chrome OS) and
+    // their disk recreation on reset events should be handled from outside by
+    // calling createStubVolume() again.
     for (const auto& disk : mDisks) {
         disk->destroy();
-        disk->create();
+        if (!disk->isStub()) {
+            disk->create();
+        }
     }
+    const auto isStub = [](const auto& disk) { return disk->isStub(); };
+    mDisks.remove_if(isStub);
+    mPendingDisks.remove_if(isStub);
+
     updateVirtualDisk();
     mAddedUsers.clear();
     mStartedUsers.clear();
@@ -1002,8 +1013,8 @@
             // The volume must be mounted
             return false;
         }
-        if ((vol.getMountFlags() & VolumeBase::MountFlags::kVisible) == 0) {
-            // and visible
+        if (!vol.isVisibleForWrite()) {
+            // App dirs should only be created for writable volumes.
             return false;
         }
         if (vol.getInternalPath().empty()) {
@@ -1077,8 +1088,8 @@
                 // The volume must be mounted
                 return false;
             }
-            if ((vol.getMountFlags() & VolumeBase::MountFlags::kVisible) == 0) {
-                // and visible
+            if (!vol.isVisibleForWrite()) {
+                // Obb volume should only be created for writable volumes.
                 return false;
             }
             if (vol.getInternalPath().empty()) {
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index 606f473..c72ceea 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -65,8 +65,13 @@
     void destroyObb(@utf8InCpp String volId);
 
     void fstrim(int fstrimFlags, IVoldTaskListener listener);
-    void runIdleMaint(IVoldTaskListener listener);
+    void runIdleMaint(boolean needGC, IVoldTaskListener listener);
     void abortIdleMaint(IVoldTaskListener listener);
+    int getStorageLifeTime();
+    void setGCUrgentPace(int neededSegments, int minSegmentThreshold,
+                         float dirtyReclaimRate, float reclaimWeight);
+    void refreshLatestWrite();
+    int getWriteAmount();
 
     FileDescriptor mountAppFuse(int uid, int mountId);
     void unmountAppFuse(int uid, int mountId);
@@ -159,7 +164,8 @@
     const int FSTRIM_FLAG_DEEP_TRIM = 1;
 
     const int MOUNT_FLAG_PRIMARY = 1;
-    const int MOUNT_FLAG_VISIBLE = 2;
+    const int MOUNT_FLAG_VISIBLE_FOR_READ = 2;
+    const int MOUNT_FLAG_VISIBLE_FOR_WRITE = 4;
 
     const int PARTITION_TYPE_PUBLIC = 0;
     const int PARTITION_TYPE_PRIVATE = 1;
diff --git a/cryptfs.cpp b/cryptfs.cpp
index 91235d2..ab8f3ec 100644
--- a/cryptfs.cpp
+++ b/cryptfs.cpp
@@ -14,292 +14,40 @@
  * limitations under the License.
  */
 
+//
+// This file contains the implementation of the dm-crypt volume metadata
+// encryption method, which is deprecated.  Devices that launched with Android
+// 11 or higher use a different method instead.  For details, see
+// https://source.android.com/security/encryption/metadata#configuration-on-adoptable-storage
+//
+
 #define LOG_TAG "Cryptfs"
 
 #include "cryptfs.h"
 
-#include "Checkpoint.h"
 #include "CryptoType.h"
-#include "EncryptInplace.h"
-#include "FsCrypt.h"
-#include "Keymaster.h"
-#include "Process.h"
-#include "ScryptParameters.h"
 #include "Utils.h"
-#include "VoldUtil.h"
-#include "VolumeManager.h"
 
-#include <android-base/logging.h>
 #include <android-base/parseint.h>
 #include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <bootloader_message/bootloader_message.h>
-#include <cutils/android_reboot.h>
 #include <cutils/properties.h>
-#include <ext4_utils/ext4_utils.h>
-#include <f2fs_sparseblock.h>
-#include <fs_mgr.h>
-#include <fscrypt/fscrypt.h>
 #include <libdm/dm.h>
 #include <log/log.h>
-#include <logwrap/logwrap.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-#include <selinux/selinux.h>
-#include <wakelock/wakelock.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <libgen.h>
-#include <linux/kdev_t.h>
-#include <math.h>
-#include <mntent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <time.h>
-#include <unistd.h>
 
 #include <chrono>
-#include <thread>
-
-extern "C" {
-#include <crypto_scrypt.h>
-}
 
 using android::base::ParseUint;
-using android::base::StringPrintf;
-using android::fs_mgr::GetEntryForMountPoint;
 using android::vold::CryptoType;
 using android::vold::KeyBuffer;
 using android::vold::KeyGeneration;
-using namespace android::vold;
 using namespace android::dm;
+using namespace android::vold;
 using namespace std::chrono_literals;
 
-/* The current cryptfs version */
-#define CURRENT_MAJOR_VERSION 1
-#define CURRENT_MINOR_VERSION 3
-
-#define CRYPT_FOOTER_TO_PERSIST_OFFSET 0x1000
-#define CRYPT_PERSIST_DATA_SIZE 0x1000
-
-#define CRYPT_SECTOR_SIZE 512
-
-#define MAX_CRYPTO_TYPE_NAME_LEN 64
-
 #define MAX_KEY_LEN 48
-#define SALT_LEN 16
-#define SCRYPT_LEN 32
-
-/* definitions of flags in the structure below */
-#define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */
-#define CRYPT_ENCRYPTION_IN_PROGRESS 0x2 /* no longer used */
-#define CRYPT_INCONSISTENT_STATE                    \
-    0x4 /* Set when starting encryption, clear when \
-           exit cleanly, either through success or  \
-           correctly marked partial encryption */
-#define CRYPT_DATA_CORRUPT                      \
-    0x8 /* Set when encryption is fine, but the \
-           underlying volume is corrupt */
-#define CRYPT_FORCE_ENCRYPTION                        \
-    0x10 /* Set when it is time to encrypt this       \
-            volume on boot. Everything in this        \
-            structure is set up correctly as          \
-            though device is encrypted except         \
-            that the master key is encrypted with the \
-            default password. */
-#define CRYPT_FORCE_COMPLETE                           \
-    0x20 /* Set when the above encryption cycle is     \
-            complete. On next cryptkeeper entry, match \
-            the password. If it matches fix the master \
-            key and remove this flag. */
-
-/* Allowed values for type in the structure below */
-#define CRYPT_TYPE_PASSWORD                       \
-    0 /* master_key is encrypted with a password  \
-       * Must be zero to be compatible with pre-L \
-       * devices where type is always password.*/
-#define CRYPT_TYPE_DEFAULT                                            \
-    1                         /* master_key is encrypted with default \
-                               * password */
-#define CRYPT_TYPE_PATTERN 2  /* master_key is encrypted with a pattern */
-#define CRYPT_TYPE_PIN 3      /* master_key is encrypted with a pin */
-#define CRYPT_TYPE_MAX_TYPE 3 /* type cannot be larger than this value */
-
-#define CRYPT_MNT_MAGIC 0xD0B5B1C4
-#define PERSIST_DATA_MAGIC 0xE950CD44
-
-/* Key Derivation Function algorithms */
-#define KDF_PBKDF2 1
-#define KDF_SCRYPT 2
-/* Algorithms 3 & 4 deprecated before shipping outside of google, so removed */
-#define KDF_SCRYPT_KEYMASTER 5
-
-/* Maximum allowed keymaster blob size. */
-#define KEYMASTER_BLOB_SIZE 2048
-
-/* __le32 and __le16 defined in system/extras/ext4_utils/ext4_utils.h */
-#define __le8 unsigned char
-
-#if !defined(SHA256_DIGEST_LENGTH)
-#define SHA256_DIGEST_LENGTH 32
-#endif
-
-/* This structure starts 16,384 bytes before the end of a hardware
- * partition that is encrypted, or in a separate partition.  It's location
- * is specified by a property set in init.<device>.rc.
- * The structure allocates 48 bytes for a key, but the real key size is
- * specified in the struct.  Currently, the code is hardcoded to use 128
- * bit keys.
- * The fields after salt are only valid in rev 1.1 and later stuctures.
- * Obviously, the filesystem does not include the last 16 kbytes
- * of the partition if the crypt_mnt_ftr lives at the end of the
- * partition.
- */
-
-struct crypt_mnt_ftr {
-    __le32 magic; /* See above */
-    __le16 major_version;
-    __le16 minor_version;
-    __le32 ftr_size;             /* in bytes, not including key following */
-    __le32 flags;                /* See above */
-    __le32 keysize;              /* in bytes */
-    __le32 crypt_type;           /* how master_key is encrypted. Must be a
-                                  * CRYPT_TYPE_XXX value */
-    __le64 fs_size;              /* Size of the encrypted fs, in 512 byte sectors */
-    __le32 failed_decrypt_count; /* count of # of failed attempts to decrypt and
-                                    mount, set to 0 on successful mount */
-    unsigned char crypto_type_name[MAX_CRYPTO_TYPE_NAME_LEN]; /* The type of encryption
-                                                                 needed to decrypt this
-                                                                 partition, null terminated */
-    __le32 spare2;                                            /* ignored */
-    unsigned char master_key[MAX_KEY_LEN]; /* The encrypted key for decrypting the filesystem */
-    unsigned char salt[SALT_LEN];          /* The salt used for this encryption */
-    __le64 persist_data_offset[2];         /* Absolute offset to both copies of crypt_persist_data
-                                            * on device with that info, either the footer of the
-                                            * real_blkdevice or the metadata partition. */
-
-    __le32 persist_data_size; /* The number of bytes allocated to each copy of the
-                               * persistent data table*/
-
-    __le8 kdf_type; /* The key derivation function used. */
-
-    /* scrypt parameters. See www.tarsnap.com/scrypt/scrypt.pdf */
-    __le8 N_factor;        /* (1 << N) */
-    __le8 r_factor;        /* (1 << r) */
-    __le8 p_factor;        /* (1 << p) */
-    __le64 encrypted_upto; /* no longer used */
-    __le8 hash_first_block[SHA256_DIGEST_LENGTH]; /* no longer used */
-
-    /* key_master key, used to sign the derived key which is then used to generate
-     * the intermediate key
-     * This key should be used for no other purposes! We use this key to sign unpadded
-     * data, which is acceptable but only if the key is not reused elsewhere. */
-    __le8 keymaster_blob[KEYMASTER_BLOB_SIZE];
-    __le32 keymaster_blob_size;
-
-    /* Store scrypt of salted intermediate key. When decryption fails, we can
-       check if this matches, and if it does, we know that the problem is with the
-       drive, and there is no point in asking the user for more passwords.
-
-       Note that if any part of this structure is corrupt, this will not match and
-       we will continue to believe the user entered the wrong password. In that
-       case the only solution is for the user to enter a password enough times to
-       force a wipe.
-
-       Note also that there is no need to worry about migration. If this data is
-       wrong, we simply won't recognise a right password, and will continue to
-       prompt. On the first password change, this value will be populated and
-       then we will be OK.
-     */
-    unsigned char scrypted_intermediate_key[SCRYPT_LEN];
-
-    /* sha of this structure with this element set to zero
-       Used when encrypting on reboot to validate structure before doing something
-       fatal
-     */
-    unsigned char sha256[SHA256_DIGEST_LENGTH];
-};
-
-/* Persistant data that should be available before decryption.
- * Things like airplane mode, locale and timezone are kept
- * here and can be retrieved by the CryptKeeper UI to properly
- * configure the phone before asking for the password
- * This is only valid if the major and minor version above
- * is set to 1.1 or higher.
- *
- * This is a 4K structure.  There are 2 copies, and the code alternates
- * writing one and then clearing the previous one.  The reading
- * code reads the first valid copy it finds, based on the magic number.
- * The absolute offset to the first of the two copies is kept in rev 1.1
- * and higher crypt_mnt_ftr structures.
- */
-struct crypt_persist_entry {
-    char key[PROPERTY_KEY_MAX];
-    char val[PROPERTY_VALUE_MAX];
-};
-
-/* Should be exactly 4K in size */
-struct crypt_persist_data {
-    __le32 persist_magic;
-    __le32 persist_valid_entries;
-    __le32 persist_spare[30];
-    struct crypt_persist_entry persist_entry[0];
-};
-
-typedef int (*kdf_func)(const char* passwd, const unsigned char* salt, unsigned char* ikey,
-                        void* params);
-
-#define UNUSED __attribute__((unused))
-
-#define HASH_COUNT 2000
-
-constexpr size_t INTERMEDIATE_KEY_LEN_BYTES = 16;
-constexpr size_t INTERMEDIATE_IV_LEN_BYTES = 16;
-constexpr size_t INTERMEDIATE_BUF_SIZE = (INTERMEDIATE_KEY_LEN_BYTES + INTERMEDIATE_IV_LEN_BYTES);
-
-// SCRYPT_LEN is used by struct crypt_mnt_ftr for its intermediate key.
-static_assert(INTERMEDIATE_BUF_SIZE == SCRYPT_LEN, "Mismatch of intermediate key sizes");
-
-#define KEY_IN_FOOTER "footer"
-
-#define DEFAULT_PASSWORD "default_password"
-
-#define CRYPTO_BLOCK_DEVICE "userdata"
-
-#define BREADCRUMB_FILE "/data/misc/vold/convert_fde"
-
-#define EXT4_FS 1
-#define F2FS_FS 2
 
 #define TABLE_LOAD_RETRIES 10
 
-#define RSA_KEY_SIZE 2048
-#define RSA_KEY_SIZE_BYTES (RSA_KEY_SIZE / 8)
-#define RSA_EXPONENT 0x10001
-#define KEYMASTER_CRYPTFS_RATE_LIMIT 1  // Maximum one try per second
-
-#define RETRY_MOUNT_ATTEMPTS 10
-#define RETRY_MOUNT_DELAY_SECONDS 1
-
-#define CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE (1)
-
-static int put_crypt_ftr_and_key(struct crypt_mnt_ftr* crypt_ftr);
-
-static unsigned char saved_master_key[MAX_KEY_LEN];
-static char* saved_mount_point;
-static int master_key_saved = 0;
-static struct crypt_persist_data* persist_data = NULL;
-
 constexpr CryptoType aes_128_cbc = CryptoType()
                                            .set_config_name("AES-128-CBC")
                                            .set_kernel_name("aes-cbc-essiv:sha256")
@@ -326,805 +74,24 @@
     return KeyGeneration{get_crypto_type().get_keysize(), true, false};
 }
 
-static bool write_string_to_buf(const std::string& towrite, uint8_t* buffer, uint32_t buffer_size,
-                                uint32_t* out_size) {
-    if (!buffer || !out_size) {
-        LOG(ERROR) << "Missing target pointers";
-        return false;
-    }
-    *out_size = towrite.size();
-    if (buffer_size < towrite.size()) {
-        LOG(ERROR) << "Buffer too small " << buffer_size << " < " << towrite.size();
-        return false;
-    }
-    memset(buffer, '\0', buffer_size);
-    std::copy(towrite.begin(), towrite.end(), buffer);
-    return true;
-}
-
-static int keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
-                                                   uint32_t ratelimit, uint8_t* key_buffer,
-                                                   uint32_t key_buffer_size,
-                                                   uint32_t* key_out_size) {
-    if (key_out_size) {
-        *key_out_size = 0;
-    }
-    Keymaster dev;
-    if (!dev) {
-        LOG(ERROR) << "Failed to initiate keymaster session";
-        return -1;
-    }
-    auto keyParams = km::AuthorizationSetBuilder()
-                             .RsaSigningKey(rsa_key_size, rsa_exponent)
-                             .NoDigestOrPadding()
-                             .Authorization(km::TAG_NO_AUTH_REQUIRED)
-                             .Authorization(km::TAG_MIN_SECONDS_BETWEEN_OPS, ratelimit);
-    std::string key;
-    if (!dev.generateKey(keyParams, &key)) return -1;
-    if (!write_string_to_buf(key, key_buffer, key_buffer_size, key_out_size)) return -1;
-    return 0;
-}
-
-/* Create a new keymaster key and store it in this footer */
-static int keymaster_create_key(struct crypt_mnt_ftr* ftr) {
-    if (ftr->keymaster_blob_size) {
-        SLOGI("Already have key");
-        return 0;
-    }
-
-    int rc = keymaster_create_key_for_cryptfs_scrypt(
-        RSA_KEY_SIZE, RSA_EXPONENT, KEYMASTER_CRYPTFS_RATE_LIMIT, ftr->keymaster_blob,
-        KEYMASTER_BLOB_SIZE, &ftr->keymaster_blob_size);
-    if (rc) {
-        if (ftr->keymaster_blob_size > KEYMASTER_BLOB_SIZE) {
-            SLOGE("Keymaster key blob too large");
-            ftr->keymaster_blob_size = 0;
-        }
-        SLOGE("Failed to generate keypair");
-        return -1;
-    }
-    return 0;
-}
-
-static int keymaster_sign_object_for_cryptfs_scrypt(struct crypt_mnt_ftr* ftr, uint32_t ratelimit,
-                                                    const uint8_t* object, const size_t object_size,
-                                                    uint8_t** signature_buffer,
-                                                    size_t* signature_buffer_size) {
-    if (!object || !signature_buffer || !signature_buffer_size) {
-        LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
-        return -1;
-    }
-
-    Keymaster dev;
-    if (!dev) {
-        LOG(ERROR) << "Failed to initiate keymaster session";
-        return -1;
-    }
-
-    km::AuthorizationSet outParams;
-    std::string key(reinterpret_cast<const char*>(ftr->keymaster_blob), ftr->keymaster_blob_size);
-    std::string input(reinterpret_cast<const char*>(object), object_size);
-    std::string output;
-    KeymasterOperation op;
-
-    auto paramBuilder = km::AuthorizationSetBuilder().NoDigestOrPadding().Authorization(
-            km::TAG_PURPOSE, km::KeyPurpose::SIGN);
-    while (true) {
-        op = dev.begin(key, paramBuilder, &outParams);
-        if (op.getErrorCode() == km::ErrorCode::KEY_RATE_LIMIT_EXCEEDED) {
-            sleep(ratelimit);
-            continue;
-        } else
-            break;
-    }
-
-    if (!op) {
-        LOG(ERROR) << "Error starting keymaster signature transaction: "
-                   << int32_t(op.getErrorCode());
-        return -1;
-    }
-
-    if (op.getUpgradedBlob()) {
-        write_string_to_buf(*op.getUpgradedBlob(), ftr->keymaster_blob, KEYMASTER_BLOB_SIZE,
-                            &ftr->keymaster_blob_size);
-
-        SLOGD("Upgrading key");
-        if (put_crypt_ftr_and_key(ftr) != 0) {
-            SLOGE("Failed to write upgraded key to disk");
-            return -1;
-        }
-        SLOGD("Key upgraded successfully");
-    }
-
-    if (!op.updateCompletely(input, &output)) {
-        LOG(ERROR) << "Error sending data to keymaster signature transaction: "
-                   << int32_t(op.getErrorCode());
-        return -1;
-    }
-
-    if (!op.finish(&output)) {
-        LOG(ERROR) << "Error finalizing keymaster signature transaction: "
-                   << int32_t(op.getErrorCode());
-        return -1;
-    }
-
-    *signature_buffer = reinterpret_cast<uint8_t*>(malloc(output.size()));
-    if (*signature_buffer == nullptr) {
-        LOG(ERROR) << "Error allocation buffer for keymaster signature";
-        return -1;
-    }
-    *signature_buffer_size = output.size();
-    std::copy(output.data(), output.data() + output.size(), *signature_buffer);
-
-    return 0;
-}
-
-/* This signs the given object using the keymaster key. */
-static int keymaster_sign_object(struct crypt_mnt_ftr* ftr, const unsigned char* object,
-                                 const size_t object_size, unsigned char** signature,
-                                 size_t* signature_size) {
-    unsigned char to_sign[RSA_KEY_SIZE_BYTES];
-    size_t to_sign_size = sizeof(to_sign);
-    memset(to_sign, 0, RSA_KEY_SIZE_BYTES);
-
-    // To sign a message with RSA, the message must satisfy two
-    // constraints:
-    //
-    // 1. The message, when interpreted as a big-endian numeric value, must
-    //    be strictly less than the public modulus of the RSA key.  Note
-    //    that because the most significant bit of the public modulus is
-    //    guaranteed to be 1 (else it's an (n-1)-bit key, not an n-bit
-    //    key), an n-bit message with most significant bit 0 always
-    //    satisfies this requirement.
-    //
-    // 2. The message must have the same length in bits as the public
-    //    modulus of the RSA key.  This requirement isn't mathematically
-    //    necessary, but is necessary to ensure consistency in
-    //    implementations.
-    switch (ftr->kdf_type) {
-        case KDF_SCRYPT_KEYMASTER:
-            // This ensures the most significant byte of the signed message
-            // is zero.  We could have zero-padded to the left instead, but
-            // this approach is slightly more robust against changes in
-            // object size.  However, it's still broken (but not unusably
-            // so) because we really should be using a proper deterministic
-            // RSA padding function, such as PKCS1.
-            memcpy(to_sign + 1, object, std::min((size_t)RSA_KEY_SIZE_BYTES - 1, object_size));
-            SLOGI("Signing safely-padded object");
-            break;
-        default:
-            SLOGE("Unknown KDF type %d", ftr->kdf_type);
-            return -1;
-    }
-    return keymaster_sign_object_for_cryptfs_scrypt(ftr, KEYMASTER_CRYPTFS_RATE_LIMIT, to_sign,
-                                                    to_sign_size, signature, signature_size);
-}
-
-/* Store password when userdata is successfully decrypted and mounted.
- * Cleared by cryptfs_clear_password
- *
- * To avoid a double prompt at boot, we need to store the CryptKeeper
- * password and pass it to KeyGuard, which uses it to unlock KeyStore.
- * Since the entire framework is torn down and rebuilt after encryption,
- * we have to use a daemon or similar to store the password. Since vold
- * is secured against IPC except from system processes, it seems a reasonable
- * place to store this.
- *
- * password should be cleared once it has been used.
- *
- * password is aged out after password_max_age_seconds seconds.
- */
-static char* password = 0;
-static int password_expiry_time = 0;
-static const int password_max_age_seconds = 60;
-
-enum class RebootType { reboot, recovery, shutdown };
-static void cryptfs_reboot(RebootType rt) {
-    switch (rt) {
-        case RebootType::reboot:
-            property_set(ANDROID_RB_PROPERTY, "reboot");
-            break;
-
-        case RebootType::recovery:
-            property_set(ANDROID_RB_PROPERTY, "reboot,recovery");
-            break;
-
-        case RebootType::shutdown:
-            property_set(ANDROID_RB_PROPERTY, "shutdown");
-            break;
-    }
-
-    sleep(20);
-
-    /* Shouldn't get here, reboot should happen before sleep times out */
-    return;
-}
-
-/**
- * Gets the default device scrypt parameters for key derivation time tuning.
- * The parameters should lead to about one second derivation time for the
- * given device.
- */
-static void get_device_scrypt_params(struct crypt_mnt_ftr* ftr) {
-    char paramstr[PROPERTY_VALUE_MAX];
-    int Nf, rf, pf;
-
-    property_get(SCRYPT_PROP, paramstr, SCRYPT_DEFAULTS);
-    if (!parse_scrypt_parameters(paramstr, &Nf, &rf, &pf)) {
-        SLOGW("bad scrypt parameters '%s' should be like '12:8:1'; using defaults", paramstr);
-        parse_scrypt_parameters(SCRYPT_DEFAULTS, &Nf, &rf, &pf);
-    }
-    ftr->N_factor = Nf;
-    ftr->r_factor = rf;
-    ftr->p_factor = pf;
-}
-
-static uint64_t get_fs_size(const char* dev) {
-    int fd, block_size;
-    struct ext4_super_block sb;
-    uint64_t len;
-
-    if ((fd = open(dev, O_RDONLY | O_CLOEXEC)) < 0) {
-        SLOGE("Cannot open device to get filesystem size ");
-        return 0;
-    }
-
-    if (lseek64(fd, 1024, SEEK_SET) < 0) {
-        SLOGE("Cannot seek to superblock");
-        return 0;
-    }
-
-    if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) {
-        SLOGE("Cannot read superblock");
-        return 0;
-    }
-
-    close(fd);
-
-    if (le32_to_cpu(sb.s_magic) != EXT4_SUPER_MAGIC) {
-        SLOGE("Not a valid ext4 superblock");
-        return 0;
-    }
-    block_size = 1024 << sb.s_log_block_size;
-    /* compute length in bytes */
-    len = (((uint64_t)sb.s_blocks_count_hi << 32) + sb.s_blocks_count_lo) * block_size;
-
-    /* return length in sectors */
-    return len / 512;
-}
-
-static void get_crypt_info(std::string* key_loc, std::string* real_blk_device) {
-    for (const auto& entry : fstab_default) {
-        if (!entry.fs_mgr_flags.vold_managed &&
-            (entry.fs_mgr_flags.crypt || entry.fs_mgr_flags.force_crypt ||
-             entry.fs_mgr_flags.force_fde_or_fbe || entry.fs_mgr_flags.file_encryption)) {
-            if (key_loc != nullptr) {
-                *key_loc = entry.key_loc;
-            }
-            if (real_blk_device != nullptr) {
-                *real_blk_device = entry.blk_device;
-            }
-            return;
-        }
-    }
-}
-
-static int get_crypt_ftr_info(char** metadata_fname, off64_t* off) {
-    static int cached_data = 0;
-    static uint64_t cached_off = 0;
-    static char cached_metadata_fname[PROPERTY_VALUE_MAX] = "";
-    char key_loc[PROPERTY_VALUE_MAX];
-    char real_blkdev[PROPERTY_VALUE_MAX];
-    int rc = -1;
-
-    if (!cached_data) {
-        std::string key_loc;
-        std::string real_blkdev;
-        get_crypt_info(&key_loc, &real_blkdev);
-
-        if (key_loc == KEY_IN_FOOTER) {
-            if (android::vold::GetBlockDevSize(real_blkdev, &cached_off) == android::OK) {
-                /* If it's an encrypted Android partition, the last 16 Kbytes contain the
-                 * encryption info footer and key, and plenty of bytes to spare for future
-                 * growth.
-                 */
-                strlcpy(cached_metadata_fname, real_blkdev.c_str(), sizeof(cached_metadata_fname));
-                cached_off -= CRYPT_FOOTER_OFFSET;
-                cached_data = 1;
-            } else {
-                SLOGE("Cannot get size of block device %s\n", real_blkdev.c_str());
-            }
-        } else {
-            strlcpy(cached_metadata_fname, key_loc.c_str(), sizeof(cached_metadata_fname));
-            cached_off = 0;
-            cached_data = 1;
-        }
-    }
-
-    if (cached_data) {
-        if (metadata_fname) {
-            *metadata_fname = cached_metadata_fname;
-        }
-        if (off) {
-            *off = cached_off;
-        }
-        rc = 0;
-    }
-
-    return rc;
-}
-
-/* Set sha256 checksum in structure */
-static void set_ftr_sha(struct crypt_mnt_ftr* crypt_ftr) {
-    SHA256_CTX c;
-    SHA256_Init(&c);
-    memset(crypt_ftr->sha256, 0, sizeof(crypt_ftr->sha256));
-    SHA256_Update(&c, crypt_ftr, sizeof(*crypt_ftr));
-    SHA256_Final(crypt_ftr->sha256, &c);
-}
-
-/* key or salt can be NULL, in which case just skip writing that value.  Useful to
- * update the failed mount count but not change the key.
- */
-static int put_crypt_ftr_and_key(struct crypt_mnt_ftr* crypt_ftr) {
-    int fd;
-    unsigned int cnt;
-    /* starting_off is set to the SEEK_SET offset
-     * where the crypto structure starts
-     */
-    off64_t starting_off;
-    int rc = -1;
-    char* fname = NULL;
-    struct stat statbuf;
-
-    set_ftr_sha(crypt_ftr);
-
-    if (get_crypt_ftr_info(&fname, &starting_off)) {
-        SLOGE("Unable to get crypt_ftr_info\n");
-        return -1;
-    }
-    if (fname[0] != '/') {
-        SLOGE("Unexpected value for crypto key location\n");
-        return -1;
-    }
-    if ((fd = open(fname, O_RDWR | O_CREAT | O_CLOEXEC, 0600)) < 0) {
-        SLOGE("Cannot open footer file %s for put\n", fname);
-        return -1;
-    }
-
-    /* Seek to the start of the crypt footer */
-    if (lseek64(fd, starting_off, SEEK_SET) == -1) {
-        SLOGE("Cannot seek to real block device footer\n");
-        goto errout;
-    }
-
-    if ((cnt = write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
-        SLOGE("Cannot write real block device footer\n");
-        goto errout;
-    }
-
-    fstat(fd, &statbuf);
-    /* If the keys are kept on a raw block device, do not try to truncate it. */
-    if (S_ISREG(statbuf.st_mode)) {
-        if (ftruncate(fd, 0x4000)) {
-            SLOGE("Cannot set footer file size\n");
-            goto errout;
-        }
-    }
-
-    /* Success! */
-    rc = 0;
-
-errout:
-    close(fd);
-    return rc;
-}
-
-static bool check_ftr_sha(const struct crypt_mnt_ftr* crypt_ftr) {
-    struct crypt_mnt_ftr copy;
-    memcpy(&copy, crypt_ftr, sizeof(copy));
-    set_ftr_sha(&copy);
-    return memcmp(copy.sha256, crypt_ftr->sha256, sizeof(copy.sha256)) == 0;
-}
-
-static inline int unix_read(int fd, void* buff, int len) {
-    return TEMP_FAILURE_RETRY(read(fd, buff, len));
-}
-
-static inline int unix_write(int fd, const void* buff, int len) {
-    return TEMP_FAILURE_RETRY(write(fd, buff, len));
-}
-
-static void init_empty_persist_data(struct crypt_persist_data* pdata, int len) {
-    memset(pdata, 0, len);
-    pdata->persist_magic = PERSIST_DATA_MAGIC;
-    pdata->persist_valid_entries = 0;
-}
-
-/* A routine to update the passed in crypt_ftr to the lastest version.
- * fd is open read/write on the device that holds the crypto footer and persistent
- * data, crypt_ftr is a pointer to the struct to be updated, and offset is the
- * absolute offset to the start of the crypt_mnt_ftr on the passed in fd.
- */
-static void upgrade_crypt_ftr(int fd, struct crypt_mnt_ftr* crypt_ftr, off64_t offset) {
-    int orig_major = crypt_ftr->major_version;
-    int orig_minor = crypt_ftr->minor_version;
-
-    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 0)) {
-        struct crypt_persist_data* pdata;
-        off64_t pdata_offset = offset + CRYPT_FOOTER_TO_PERSIST_OFFSET;
-
-        SLOGW("upgrading crypto footer to 1.1");
-
-        pdata = (crypt_persist_data*)malloc(CRYPT_PERSIST_DATA_SIZE);
-        if (pdata == NULL) {
-            SLOGE("Cannot allocate persisent data\n");
-            return;
-        }
-        memset(pdata, 0, CRYPT_PERSIST_DATA_SIZE);
-
-        /* Need to initialize the persistent data area */
-        if (lseek64(fd, pdata_offset, SEEK_SET) == -1) {
-            SLOGE("Cannot seek to persisent data offset\n");
-            free(pdata);
-            return;
-        }
-        /* Write all zeros to the first copy, making it invalid */
-        unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE);
-
-        /* Write a valid but empty structure to the second copy */
-        init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
-        unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE);
-
-        /* Update the footer */
-        crypt_ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE;
-        crypt_ftr->persist_data_offset[0] = pdata_offset;
-        crypt_ftr->persist_data_offset[1] = pdata_offset + CRYPT_PERSIST_DATA_SIZE;
-        crypt_ftr->minor_version = 1;
-        free(pdata);
-    }
-
-    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 1)) {
-        SLOGW("upgrading crypto footer to 1.2");
-        /* But keep the old kdf_type.
-         * It will get updated later to KDF_SCRYPT after the password has been verified.
-         */
-        crypt_ftr->kdf_type = KDF_PBKDF2;
-        get_device_scrypt_params(crypt_ftr);
-        crypt_ftr->minor_version = 2;
-    }
-
-    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 2)) {
-        SLOGW("upgrading crypto footer to 1.3");
-        crypt_ftr->crypt_type = CRYPT_TYPE_PASSWORD;
-        crypt_ftr->minor_version = 3;
-    }
-
-    if ((orig_major != crypt_ftr->major_version) || (orig_minor != crypt_ftr->minor_version)) {
-        if (lseek64(fd, offset, SEEK_SET) == -1) {
-            SLOGE("Cannot seek to crypt footer\n");
-            return;
-        }
-        unix_write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr));
-    }
-}
-
-static int get_crypt_ftr_and_key(struct crypt_mnt_ftr* crypt_ftr) {
-    int fd;
-    unsigned int cnt;
-    off64_t starting_off;
-    int rc = -1;
-    char* fname = NULL;
-    struct stat statbuf;
-
-    if (get_crypt_ftr_info(&fname, &starting_off)) {
-        SLOGE("Unable to get crypt_ftr_info\n");
-        return -1;
-    }
-    if (fname[0] != '/') {
-        SLOGE("Unexpected value for crypto key location\n");
-        return -1;
-    }
-    if ((fd = open(fname, O_RDWR | O_CLOEXEC)) < 0) {
-        SLOGE("Cannot open footer file %s for get\n", fname);
-        return -1;
-    }
-
-    /* Make sure it's 16 Kbytes in length */
-    fstat(fd, &statbuf);
-    if (S_ISREG(statbuf.st_mode) && (statbuf.st_size != 0x4000)) {
-        SLOGE("footer file %s is not the expected size!\n", fname);
-        goto errout;
-    }
-
-    /* Seek to the start of the crypt footer */
-    if (lseek64(fd, starting_off, SEEK_SET) == -1) {
-        SLOGE("Cannot seek to real block device footer\n");
-        goto errout;
-    }
-
-    if ((cnt = read(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
-        SLOGE("Cannot read real block device footer\n");
-        goto errout;
-    }
-
-    if (crypt_ftr->magic != CRYPT_MNT_MAGIC) {
-        SLOGE("Bad magic for real block device %s\n", fname);
-        goto errout;
-    }
-
-    if (crypt_ftr->major_version != CURRENT_MAJOR_VERSION) {
-        SLOGE("Cannot understand major version %d real block device footer; expected %d\n",
-              crypt_ftr->major_version, CURRENT_MAJOR_VERSION);
-        goto errout;
-    }
-
-    // We risk buffer overflows with oversized keys, so we just reject them.
-    // 0-sized keys are problematic (essentially by-passing encryption), and
-    // AES-CBC key wrapping only works for multiples of 16 bytes.
-    if ((crypt_ftr->keysize == 0) || ((crypt_ftr->keysize % 16) != 0) ||
-        (crypt_ftr->keysize > MAX_KEY_LEN)) {
-        SLOGE(
-            "Invalid keysize (%u) for block device %s; Must be non-zero, "
-            "divisible by 16, and <= %d\n",
-            crypt_ftr->keysize, fname, MAX_KEY_LEN);
-        goto errout;
-    }
-
-    if (crypt_ftr->minor_version > CURRENT_MINOR_VERSION) {
-        SLOGW("Warning: crypto footer minor version %d, expected <= %d, continuing...\n",
-              crypt_ftr->minor_version, CURRENT_MINOR_VERSION);
-    }
-
-    /* If this is a verion 1.0 crypt_ftr, make it a 1.1 crypt footer, and update the
-     * copy on disk before returning.
-     */
-    if (crypt_ftr->minor_version < CURRENT_MINOR_VERSION) {
-        upgrade_crypt_ftr(fd, crypt_ftr, starting_off);
-    }
-
-    /* Success! */
-    rc = 0;
-
-errout:
-    close(fd);
-    return rc;
-}
-
-static int validate_persistent_data_storage(struct crypt_mnt_ftr* crypt_ftr) {
-    if (crypt_ftr->persist_data_offset[0] + crypt_ftr->persist_data_size >
-        crypt_ftr->persist_data_offset[1]) {
-        SLOGE("Crypt_ftr persist data regions overlap");
-        return -1;
-    }
-
-    if (crypt_ftr->persist_data_offset[0] >= crypt_ftr->persist_data_offset[1]) {
-        SLOGE("Crypt_ftr persist data region 0 starts after region 1");
-        return -1;
-    }
-
-    if (((crypt_ftr->persist_data_offset[1] + crypt_ftr->persist_data_size) -
-         (crypt_ftr->persist_data_offset[0] - CRYPT_FOOTER_TO_PERSIST_OFFSET)) >
-        CRYPT_FOOTER_OFFSET) {
-        SLOGE("Persistent data extends past crypto footer");
-        return -1;
-    }
-
-    return 0;
-}
-
-static int load_persistent_data(void) {
-    struct crypt_mnt_ftr crypt_ftr;
-    struct crypt_persist_data* pdata = NULL;
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    char* fname;
-    int found = 0;
-    int fd;
-    int ret;
-    int i;
-
-    if (persist_data) {
-        /* Nothing to do, we've already loaded or initialized it */
-        return 0;
-    }
-
-    /* If not encrypted, just allocate an empty table and initialize it */
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (strcmp(encrypted_state, "encrypted")) {
-        pdata = (crypt_persist_data*)malloc(CRYPT_PERSIST_DATA_SIZE);
-        if (pdata) {
-            init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
-            persist_data = pdata;
-            return 0;
-        }
-        return -1;
-    }
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        return -1;
-    }
-
-    if ((crypt_ftr.major_version < 1) ||
-        (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) {
-        SLOGE("Crypt_ftr version doesn't support persistent data");
-        return -1;
-    }
-
-    if (get_crypt_ftr_info(&fname, NULL)) {
-        return -1;
-    }
-
-    ret = validate_persistent_data_storage(&crypt_ftr);
-    if (ret) {
-        return -1;
-    }
-
-    fd = open(fname, O_RDONLY | O_CLOEXEC);
-    if (fd < 0) {
-        SLOGE("Cannot open %s metadata file", fname);
-        return -1;
-    }
-
-    pdata = (crypt_persist_data*)malloc(crypt_ftr.persist_data_size);
-    if (pdata == NULL) {
-        SLOGE("Cannot allocate memory for persistent data");
-        goto err;
-    }
-
-    for (i = 0; i < 2; i++) {
-        if (lseek64(fd, crypt_ftr.persist_data_offset[i], SEEK_SET) < 0) {
-            SLOGE("Cannot seek to read persistent data on %s", fname);
-            goto err2;
-        }
-        if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0) {
-            SLOGE("Error reading persistent data on iteration %d", i);
-            goto err2;
-        }
-        if (pdata->persist_magic == PERSIST_DATA_MAGIC) {
-            found = 1;
-            break;
-        }
-    }
-
-    if (!found) {
-        SLOGI("Could not find valid persistent data, creating");
-        init_empty_persist_data(pdata, crypt_ftr.persist_data_size);
-    }
-
-    /* Success */
-    persist_data = pdata;
-    close(fd);
-    return 0;
-
-err2:
-    free(pdata);
-
-err:
-    close(fd);
-    return -1;
-}
-
-static int save_persistent_data(void) {
-    struct crypt_mnt_ftr crypt_ftr;
-    struct crypt_persist_data* pdata;
-    char* fname;
-    off64_t write_offset;
-    off64_t erase_offset;
-    int fd;
-    int ret;
-
-    if (persist_data == NULL) {
-        SLOGE("No persistent data to save");
-        return -1;
-    }
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        return -1;
-    }
-
-    if ((crypt_ftr.major_version < 1) ||
-        (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) {
-        SLOGE("Crypt_ftr version doesn't support persistent data");
-        return -1;
-    }
-
-    ret = validate_persistent_data_storage(&crypt_ftr);
-    if (ret) {
-        return -1;
-    }
-
-    if (get_crypt_ftr_info(&fname, NULL)) {
-        return -1;
-    }
-
-    fd = open(fname, O_RDWR | O_CLOEXEC);
-    if (fd < 0) {
-        SLOGE("Cannot open %s metadata file", fname);
-        return -1;
-    }
-
-    pdata = (crypt_persist_data*)malloc(crypt_ftr.persist_data_size);
-    if (pdata == NULL) {
-        SLOGE("Cannot allocate persistant data");
-        goto err;
-    }
-
-    if (lseek64(fd, crypt_ftr.persist_data_offset[0], SEEK_SET) < 0) {
-        SLOGE("Cannot seek to read persistent data on %s", fname);
-        goto err2;
-    }
-
-    if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0) {
-        SLOGE("Error reading persistent data before save");
-        goto err2;
-    }
-
-    if (pdata->persist_magic == PERSIST_DATA_MAGIC) {
-        /* The first copy is the curent valid copy, so write to
-         * the second copy and erase this one */
-        write_offset = crypt_ftr.persist_data_offset[1];
-        erase_offset = crypt_ftr.persist_data_offset[0];
-    } else {
-        /* The second copy must be the valid copy, so write to
-         * the first copy, and erase the second */
-        write_offset = crypt_ftr.persist_data_offset[0];
-        erase_offset = crypt_ftr.persist_data_offset[1];
-    }
-
-    /* Write the new copy first, if successful, then erase the old copy */
-    if (lseek64(fd, write_offset, SEEK_SET) < 0) {
-        SLOGE("Cannot seek to write persistent data");
-        goto err2;
-    }
-    if (unix_write(fd, persist_data, crypt_ftr.persist_data_size) ==
-        (int)crypt_ftr.persist_data_size) {
-        if (lseek64(fd, erase_offset, SEEK_SET) < 0) {
-            SLOGE("Cannot seek to erase previous persistent data");
-            goto err2;
-        }
-        fsync(fd);
-        memset(pdata, 0, crypt_ftr.persist_data_size);
-        if (unix_write(fd, pdata, crypt_ftr.persist_data_size) != (int)crypt_ftr.persist_data_size) {
-            SLOGE("Cannot write to erase previous persistent data");
-            goto err2;
-        }
-        fsync(fd);
-    } else {
-        SLOGE("Cannot write to save persistent data");
-        goto err2;
-    }
-
-    /* Success */
-    free(pdata);
-    close(fd);
-    return 0;
-
-err2:
-    free(pdata);
-err:
-    close(fd);
-    return -1;
-}
-
 /* Convert a binary key of specified length into an ascii hex string equivalent,
  * without the leading 0x and with null termination
  */
-static void convert_key_to_hex_ascii(const unsigned char* master_key, unsigned int keysize,
-                                     char* master_key_ascii) {
+static void convert_key_to_hex_ascii(const KeyBuffer& key, char* key_ascii) {
     unsigned int i, a;
     unsigned char nibble;
 
-    for (i = 0, a = 0; i < keysize; i++, a += 2) {
+    for (i = 0, a = 0; i < key.size(); i++, a += 2) {
         /* For each byte, write out two ascii hex digits */
-        nibble = (master_key[i] >> 4) & 0xf;
-        master_key_ascii[a] = nibble + (nibble > 9 ? 0x37 : 0x30);
+        nibble = (key[i] >> 4) & 0xf;
+        key_ascii[a] = nibble + (nibble > 9 ? 0x37 : 0x30);
 
-        nibble = master_key[i] & 0xf;
-        master_key_ascii[a + 1] = nibble + (nibble > 9 ? 0x37 : 0x30);
+        nibble = key[i] & 0xf;
+        key_ascii[a + 1] = nibble + (nibble > 9 ? 0x37 : 0x30);
     }
 
     /* Add the null termination */
-    master_key_ascii[a] = '\0';
+    key_ascii[a] = '\0';
 }
 
 /*
@@ -1132,7 +99,7 @@
  * parameters to make dm-crypt use the specified crypto sector size and round
  * the crypto device size down to a crypto sector boundary.
  */
-static int add_sector_size_param(DmTargetCrypt* target, struct crypt_mnt_ftr* ftr) {
+static int add_sector_size_param(DmTargetCrypt* target, uint64_t* nr_sec) {
     constexpr char DM_CRYPT_SECTOR_SIZE[] = "ro.crypto.fde_sector_size";
     char value[PROPERTY_VALUE_MAX];
 
@@ -1153,800 +120,11 @@
         target->SetIvLargeSectors();
 
         // Round the crypto device size down to a crypto sector boundary.
-        ftr->fs_size &= ~((sector_size / 512) - 1);
+        *nr_sec &= ~((sector_size / 512) - 1);
     }
     return 0;
 }
 
-static int create_crypto_blk_dev(struct crypt_mnt_ftr* crypt_ftr, const unsigned char* master_key,
-                                 const char* real_blk_name, std::string* crypto_blk_name,
-                                 const char* name, uint32_t flags) {
-    auto& dm = DeviceMapper::Instance();
-
-    // We need two ASCII characters to represent each byte, and need space for
-    // the '\0' terminator.
-    char master_key_ascii[MAX_KEY_LEN * 2 + 1];
-    convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
-
-    auto target = std::make_unique<DmTargetCrypt>(0, crypt_ftr->fs_size,
-                                                  (const char*)crypt_ftr->crypto_type_name,
-                                                  master_key_ascii, 0, real_blk_name, 0);
-    target->AllowDiscards();
-
-    if (flags & CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE) {
-        target->AllowEncryptOverride();
-    }
-    if (add_sector_size_param(target.get(), crypt_ftr)) {
-        SLOGE("Error processing dm-crypt sector size param\n");
-        return -1;
-    }
-
-    DmTable table;
-    table.AddTarget(std::move(target));
-
-    int load_count = 1;
-    while (load_count < TABLE_LOAD_RETRIES) {
-        if (dm.CreateDevice(name, table)) {
-            break;
-        }
-        load_count++;
-    }
-
-    if (load_count >= TABLE_LOAD_RETRIES) {
-        SLOGE("Cannot load dm-crypt mapping table.\n");
-        return -1;
-    }
-    if (load_count > 1) {
-        SLOGI("Took %d tries to load dmcrypt table.\n", load_count);
-    }
-
-    if (!dm.GetDmDevicePathByName(name, crypto_blk_name)) {
-        SLOGE("Cannot determine dm-crypt path for %s.\n", name);
-        return -1;
-    }
-
-    /* Ensure the dm device has been created before returning. */
-    if (android::vold::WaitForFile(crypto_blk_name->c_str(), 1s) < 0) {
-        // WaitForFile generates a suitable log message
-        return -1;
-    }
-    return 0;
-}
-
-static int delete_crypto_blk_dev(const std::string& name) {
-    bool ret;
-    auto& dm = DeviceMapper::Instance();
-    // TODO(b/149396179) there appears to be a race somewhere in the system where trying
-    // to delete the device fails with EBUSY; for now, work around this by retrying.
-    int tries = 5;
-    while (tries-- > 0) {
-        ret = dm.DeleteDevice(name);
-        if (ret || errno != EBUSY) {
-            break;
-        }
-        SLOGW("DM_DEV Cannot remove dm-crypt device %s: %s, retrying...\n", name.c_str(),
-              strerror(errno));
-        std::this_thread::sleep_for(std::chrono::milliseconds(100));
-    }
-    if (!ret) {
-        SLOGE("DM_DEV Cannot remove dm-crypt device %s: %s\n", name.c_str(), strerror(errno));
-        return -1;
-    }
-    return 0;
-}
-
-static int pbkdf2(const char* passwd, const unsigned char* salt, unsigned char* ikey,
-                  void* params UNUSED) {
-    SLOGI("Using pbkdf2 for cryptfs KDF");
-
-    /* Turn the password into a key and IV that can decrypt the master key */
-    return PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), salt, SALT_LEN, HASH_COUNT,
-                                  INTERMEDIATE_BUF_SIZE, ikey) != 1;
-}
-
-static int scrypt(const char* passwd, const unsigned char* salt, unsigned char* ikey, void* params) {
-    SLOGI("Using scrypt for cryptfs KDF");
-
-    struct crypt_mnt_ftr* ftr = (struct crypt_mnt_ftr*)params;
-
-    int N = 1 << ftr->N_factor;
-    int r = 1 << ftr->r_factor;
-    int p = 1 << ftr->p_factor;
-
-    /* Turn the password into a key and IV that can decrypt the master key */
-    crypto_scrypt((const uint8_t*)passwd, strlen(passwd), salt, SALT_LEN, N, r, p, ikey,
-                  INTERMEDIATE_BUF_SIZE);
-
-    return 0;
-}
-
-static int scrypt_keymaster(const char* passwd, const unsigned char* salt, unsigned char* ikey,
-                            void* params) {
-    SLOGI("Using scrypt with keymaster for cryptfs KDF");
-
-    int rc;
-    size_t signature_size;
-    unsigned char* signature;
-    struct crypt_mnt_ftr* ftr = (struct crypt_mnt_ftr*)params;
-
-    int N = 1 << ftr->N_factor;
-    int r = 1 << ftr->r_factor;
-    int p = 1 << ftr->p_factor;
-
-    rc = crypto_scrypt((const uint8_t*)passwd, strlen(passwd), salt, SALT_LEN, N, r, p, ikey,
-                       INTERMEDIATE_BUF_SIZE);
-
-    if (rc) {
-        SLOGE("scrypt failed");
-        return -1;
-    }
-
-    if (keymaster_sign_object(ftr, ikey, INTERMEDIATE_BUF_SIZE, &signature, &signature_size)) {
-        SLOGE("Signing failed");
-        return -1;
-    }
-
-    rc = crypto_scrypt(signature, signature_size, salt, SALT_LEN, N, r, p, ikey,
-                       INTERMEDIATE_BUF_SIZE);
-    free(signature);
-
-    if (rc) {
-        SLOGE("scrypt failed");
-        return -1;
-    }
-
-    return 0;
-}
-
-static int encrypt_master_key(const char* passwd, const unsigned char* salt,
-                              const unsigned char* decrypted_master_key,
-                              unsigned char* encrypted_master_key, struct crypt_mnt_ftr* crypt_ftr) {
-    unsigned char ikey[INTERMEDIATE_BUF_SIZE] = {0};
-    EVP_CIPHER_CTX e_ctx;
-    int encrypted_len, final_len;
-    int rc = 0;
-
-    /* Turn the password into an intermediate key and IV that can decrypt the master key */
-    get_device_scrypt_params(crypt_ftr);
-
-    switch (crypt_ftr->kdf_type) {
-        case KDF_SCRYPT_KEYMASTER:
-            if (keymaster_create_key(crypt_ftr)) {
-                SLOGE("keymaster_create_key failed");
-                return -1;
-            }
-
-            if (scrypt_keymaster(passwd, salt, ikey, crypt_ftr)) {
-                SLOGE("scrypt failed");
-                return -1;
-            }
-            break;
-
-        case KDF_SCRYPT:
-            if (scrypt(passwd, salt, ikey, crypt_ftr)) {
-                SLOGE("scrypt failed");
-                return -1;
-            }
-            break;
-
-        default:
-            SLOGE("Invalid kdf_type");
-            return -1;
-    }
-
-    /* Initialize the decryption engine */
-    EVP_CIPHER_CTX_init(&e_ctx);
-    if (!EVP_EncryptInit_ex(&e_ctx, EVP_aes_128_cbc(), NULL, ikey,
-                            ikey + INTERMEDIATE_KEY_LEN_BYTES)) {
-        SLOGE("EVP_EncryptInit failed\n");
-        return -1;
-    }
-    EVP_CIPHER_CTX_set_padding(&e_ctx, 0); /* Turn off padding as our data is block aligned */
-
-    /* Encrypt the master key */
-    if (!EVP_EncryptUpdate(&e_ctx, encrypted_master_key, &encrypted_len, decrypted_master_key,
-                           crypt_ftr->keysize)) {
-        SLOGE("EVP_EncryptUpdate failed\n");
-        return -1;
-    }
-    if (!EVP_EncryptFinal_ex(&e_ctx, encrypted_master_key + encrypted_len, &final_len)) {
-        SLOGE("EVP_EncryptFinal failed\n");
-        return -1;
-    }
-
-    if (encrypted_len + final_len != static_cast<int>(crypt_ftr->keysize)) {
-        SLOGE("EVP_Encryption length check failed with %d, %d bytes\n", encrypted_len, final_len);
-        return -1;
-    }
-
-    /* Store the scrypt of the intermediate key, so we can validate if it's a
-       password error or mount error when things go wrong.
-       Note there's no need to check for errors, since if this is incorrect, we
-       simply won't wipe userdata, which is the correct default behavior
-    */
-    int N = 1 << crypt_ftr->N_factor;
-    int r = 1 << crypt_ftr->r_factor;
-    int p = 1 << crypt_ftr->p_factor;
-
-    rc = crypto_scrypt(ikey, INTERMEDIATE_KEY_LEN_BYTES, crypt_ftr->salt, sizeof(crypt_ftr->salt),
-                       N, r, p, crypt_ftr->scrypted_intermediate_key,
-                       sizeof(crypt_ftr->scrypted_intermediate_key));
-
-    if (rc) {
-        SLOGE("encrypt_master_key: crypto_scrypt failed");
-    }
-
-    EVP_CIPHER_CTX_cleanup(&e_ctx);
-
-    return 0;
-}
-
-static int decrypt_master_key_aux(const char* passwd, unsigned char* salt,
-                                  const unsigned char* encrypted_master_key, size_t keysize,
-                                  unsigned char* decrypted_master_key, kdf_func kdf,
-                                  void* kdf_params, unsigned char** intermediate_key,
-                                  size_t* intermediate_key_size) {
-    unsigned char ikey[INTERMEDIATE_BUF_SIZE] = {0};
-    EVP_CIPHER_CTX d_ctx;
-    int decrypted_len, final_len;
-
-    /* Turn the password into an intermediate key and IV that can decrypt the
-       master key */
-    if (kdf(passwd, salt, ikey, kdf_params)) {
-        SLOGE("kdf failed");
-        return -1;
-    }
-
-    /* Initialize the decryption engine */
-    EVP_CIPHER_CTX_init(&d_ctx);
-    if (!EVP_DecryptInit_ex(&d_ctx, EVP_aes_128_cbc(), NULL, ikey,
-                            ikey + INTERMEDIATE_KEY_LEN_BYTES)) {
-        return -1;
-    }
-    EVP_CIPHER_CTX_set_padding(&d_ctx, 0); /* Turn off padding as our data is block aligned */
-    /* Decrypt the master key */
-    if (!EVP_DecryptUpdate(&d_ctx, decrypted_master_key, &decrypted_len, encrypted_master_key,
-                           keysize)) {
-        return -1;
-    }
-    if (!EVP_DecryptFinal_ex(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) {
-        return -1;
-    }
-
-    if (decrypted_len + final_len != static_cast<int>(keysize)) {
-        return -1;
-    }
-
-    /* Copy intermediate key if needed by params */
-    if (intermediate_key && intermediate_key_size) {
-        *intermediate_key = (unsigned char*)malloc(INTERMEDIATE_KEY_LEN_BYTES);
-        if (*intermediate_key) {
-            memcpy(*intermediate_key, ikey, INTERMEDIATE_KEY_LEN_BYTES);
-            *intermediate_key_size = INTERMEDIATE_KEY_LEN_BYTES;
-        }
-    }
-
-    EVP_CIPHER_CTX_cleanup(&d_ctx);
-
-    return 0;
-}
-
-static void get_kdf_func(struct crypt_mnt_ftr* ftr, kdf_func* kdf, void** kdf_params) {
-    if (ftr->kdf_type == KDF_SCRYPT_KEYMASTER) {
-        *kdf = scrypt_keymaster;
-        *kdf_params = ftr;
-    } else if (ftr->kdf_type == KDF_SCRYPT) {
-        *kdf = scrypt;
-        *kdf_params = ftr;
-    } else {
-        *kdf = pbkdf2;
-        *kdf_params = NULL;
-    }
-}
-
-static int decrypt_master_key(const char* passwd, unsigned char* decrypted_master_key,
-                              struct crypt_mnt_ftr* crypt_ftr, unsigned char** intermediate_key,
-                              size_t* intermediate_key_size) {
-    kdf_func kdf;
-    void* kdf_params;
-    int ret;
-
-    get_kdf_func(crypt_ftr, &kdf, &kdf_params);
-    ret = decrypt_master_key_aux(passwd, crypt_ftr->salt, crypt_ftr->master_key, crypt_ftr->keysize,
-                                 decrypted_master_key, kdf, kdf_params, intermediate_key,
-                                 intermediate_key_size);
-    if (ret != 0) {
-        SLOGW("failure decrypting master key");
-    }
-
-    return ret;
-}
-
-static int create_encrypted_random_key(const char* passwd, unsigned char* master_key,
-                                       unsigned char* salt, struct crypt_mnt_ftr* crypt_ftr) {
-    unsigned char key_buf[MAX_KEY_LEN];
-
-    /* Get some random bits for a key and salt */
-    if (android::vold::ReadRandomBytes(sizeof(key_buf), reinterpret_cast<char*>(key_buf)) != 0) {
-        return -1;
-    }
-    if (android::vold::ReadRandomBytes(SALT_LEN, reinterpret_cast<char*>(salt)) != 0) {
-        return -1;
-    }
-
-    /* Now encrypt it with the password */
-    return encrypt_master_key(passwd, salt, key_buf, master_key, crypt_ftr);
-}
-
-static void ensure_subdirectory_unmounted(const char *prefix) {
-    std::vector<std::string> umount_points;
-    std::unique_ptr<FILE, int (*)(FILE*)> mnts(setmntent("/proc/mounts", "r"), endmntent);
-    if (!mnts) {
-        SLOGW("could not read mount files");
-        return;
-    }
-
-    //Find sudirectory mount point
-    mntent* mentry;
-    std::string top_directory(prefix);
-    if (!android::base::EndsWith(prefix, "/")) {
-        top_directory = top_directory + "/";
-    }
-    while ((mentry = getmntent(mnts.get())) != nullptr) {
-        if (strcmp(mentry->mnt_dir, top_directory.c_str()) == 0) {
-            continue;
-        }
-
-        if (android::base::StartsWith(mentry->mnt_dir, top_directory)) {
-            SLOGW("found sub-directory mount %s - %s\n", prefix, mentry->mnt_dir);
-            umount_points.push_back(mentry->mnt_dir);
-        }
-    }
-
-    //Sort by path length to umount longest path first
-    std::sort(std::begin(umount_points), std::end(umount_points),
-        [](const std::string& s1, const std::string& s2) {return s1.length() > s2.length(); });
-
-    for (std::string& mount_point : umount_points) {
-        umount(mount_point.c_str());
-        SLOGW("umount sub-directory mount %s\n", mount_point.c_str());
-    }
-}
-
-static int wait_and_unmount(const char* mountpoint) {
-    int i, err, rc;
-
-    // Subdirectory mount will cause a failure of umount.
-    ensure_subdirectory_unmounted(mountpoint);
-#define WAIT_UNMOUNT_COUNT 20
-
-    /*  Now umount the tmpfs filesystem */
-    for (i = 0; i < WAIT_UNMOUNT_COUNT; i++) {
-        if (umount(mountpoint) == 0) {
-            break;
-        }
-
-        if (errno == EINVAL) {
-            /* EINVAL is returned if the directory is not a mountpoint,
-             * i.e. there is no filesystem mounted there.  So just get out.
-             */
-            break;
-        }
-
-        err = errno;
-
-        // If it's taking too long, kill the processes with open files.
-        //
-        // Originally this logic was only a fail-safe, but now it's relied on to
-        // kill certain processes that aren't stopped by init because they
-        // aren't in the main or late_start classes.  So to avoid waiting for
-        // too long, we now are fairly aggressive in starting to kill processes.
-        static_assert(WAIT_UNMOUNT_COUNT >= 4);
-        if (i == 2) {
-            SLOGW("sending SIGTERM to processes with open files\n");
-            android::vold::KillProcessesWithOpenFiles(mountpoint, SIGTERM);
-        } else if (i >= 3) {
-            SLOGW("sending SIGKILL to processes with open files\n");
-            android::vold::KillProcessesWithOpenFiles(mountpoint, SIGKILL);
-        }
-
-        sleep(1);
-    }
-
-    if (i < WAIT_UNMOUNT_COUNT) {
-        SLOGD("unmounting %s succeeded\n", mountpoint);
-        rc = 0;
-    } else {
-        android::vold::KillProcessesWithOpenFiles(mountpoint, 0);
-        SLOGE("unmounting %s failed: %s\n", mountpoint, strerror(err));
-        rc = -1;
-    }
-
-    return rc;
-}
-
-static void prep_data_fs(void) {
-    // NOTE: post_fs_data results in init calling back around to vold, so all
-    // callers to this method must be async
-
-    /* Do the prep of the /data filesystem */
-    property_set("vold.post_fs_data_done", "0");
-    property_set("vold.decrypt", "trigger_post_fs_data");
-    SLOGD("Just triggered post_fs_data");
-
-    /* Wait a max of 50 seconds, hopefully it takes much less */
-    while (!android::base::WaitForProperty("vold.post_fs_data_done", "1", std::chrono::seconds(15))) {
-        /* We timed out to prep /data in time.  Continue wait. */
-        SLOGE("waited 15s for vold.post_fs_data_done, still waiting...");
-    }
-    SLOGD("post_fs_data done");
-}
-
-static void cryptfs_set_corrupt() {
-    // Mark the footer as bad
-    struct crypt_mnt_ftr crypt_ftr;
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Failed to get crypto footer - panic");
-        return;
-    }
-
-    crypt_ftr.flags |= CRYPT_DATA_CORRUPT;
-    if (put_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Failed to set crypto footer - panic");
-        return;
-    }
-}
-
-static void cryptfs_trigger_restart_min_framework() {
-    if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) {
-        SLOGE("Failed to mount tmpfs on data - panic");
-        return;
-    }
-
-    if (property_set("vold.decrypt", "trigger_post_fs_data")) {
-        SLOGE("Failed to trigger post fs data - panic");
-        return;
-    }
-
-    if (property_set("vold.decrypt", "trigger_restart_min_framework")) {
-        SLOGE("Failed to trigger restart min framework - panic");
-        return;
-    }
-}
-
-/* returns < 0 on failure */
-static int cryptfs_restart_internal(int restart_main) {
-    char crypto_blkdev[MAXPATHLEN];
-    int rc = -1;
-    static int restart_successful = 0;
-
-    /* Validate that it's OK to call this routine */
-    if (!master_key_saved) {
-        SLOGE("Encrypted filesystem not validated, aborting");
-        return -1;
-    }
-
-    if (restart_successful) {
-        SLOGE("System already restarted with encrypted disk, aborting");
-        return -1;
-    }
-
-    if (restart_main) {
-        /* Here is where we shut down the framework.  The init scripts
-         * start all services in one of these classes: core, early_hal, hal,
-         * main and late_start. To get to the minimal UI for PIN entry, we
-         * need to start core, early_hal, hal and main. When we want to
-         * shutdown the framework again, we need to stop most of the services in
-         * these classes, but only those services that were started after
-         * /data was mounted. This excludes critical services like vold and
-         * ueventd, which need to keep running. We could possible stop
-         * even fewer services, but because we want services to pick up APEX
-         * libraries from the real /data, restarting is better, as it makes
-         * these devices consistent with FBE devices and lets them use the
-         * most recent code.
-         *
-         * Once these services have stopped, we should be able
-         * to umount the tmpfs /data, then mount the encrypted /data.
-         * We then restart the class core, hal, main, and also the class
-         * late_start.
-         *
-         * At the moment, I've only put a few things in late_start that I know
-         * are not needed to bring up the framework, and that also cause problems
-         * with unmounting the tmpfs /data, but I hope to add add more services
-         * to the late_start class as we optimize this to decrease the delay
-         * till the user is asked for the password to the filesystem.
-         */
-
-        /* The init files are setup to stop the right set of services when
-         * vold.decrypt is set to trigger_shutdown_framework.
-         */
-        property_set("vold.decrypt", "trigger_shutdown_framework");
-        SLOGD("Just asked init to shut down class main\n");
-
-        /* Ugh, shutting down the framework is not synchronous, so until it
-         * can be fixed, this horrible hack will wait a moment for it all to
-         * shut down before proceeding.  Without it, some devices cannot
-         * restart the graphics services.
-         */
-        sleep(2);
-    }
-
-    /* Now that the framework is shutdown, we should be able to umount()
-     * the tmpfs filesystem, and mount the real one.
-     */
-
-    property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "");
-    if (strlen(crypto_blkdev) == 0) {
-        SLOGE("fs_crypto_blkdev not set\n");
-        return -1;
-    }
-
-    if (!(rc = wait_and_unmount(DATA_MNT_POINT))) {
-        /* If ro.crypto.readonly is set to 1, mount the decrypted
-         * filesystem readonly.  This is used when /data is mounted by
-         * recovery mode.
-         */
-        char ro_prop[PROPERTY_VALUE_MAX];
-        property_get("ro.crypto.readonly", ro_prop, "");
-        if (strlen(ro_prop) > 0 && std::stoi(ro_prop)) {
-            auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
-            if (entry != nullptr) {
-                entry->flags |= MS_RDONLY;
-            }
-        }
-
-        /* If that succeeded, then mount the decrypted filesystem */
-        int retries = RETRY_MOUNT_ATTEMPTS;
-        int mount_rc;
-
-        /*
-         * fs_mgr_do_mount runs fsck. Use setexeccon to run trusted
-         * partitions in the fsck domain.
-         */
-        if (setexeccon(android::vold::sFsckContext)) {
-            SLOGE("Failed to setexeccon");
-            return -1;
-        }
-        bool needs_cp = android::vold::cp_needsCheckpoint();
-        while ((mount_rc = fs_mgr_do_mount(&fstab_default, DATA_MNT_POINT, crypto_blkdev, 0,
-                                           needs_cp, false)) != 0) {
-            if (mount_rc == FS_MGR_DOMNT_BUSY) {
-                /* TODO: invoke something similar to
-                   Process::killProcessWithOpenFiles(DATA_MNT_POINT,
-                                   retries > RETRY_MOUNT_ATTEMPT/2 ? 1 : 2 ) */
-                SLOGI("Failed to mount %s because it is busy - waiting", crypto_blkdev);
-                if (--retries) {
-                    sleep(RETRY_MOUNT_DELAY_SECONDS);
-                } else {
-                    /* Let's hope that a reboot clears away whatever is keeping
-                       the mount busy */
-                    cryptfs_reboot(RebootType::reboot);
-                }
-            } else {
-                SLOGE("Failed to mount decrypted data");
-                cryptfs_set_corrupt();
-                cryptfs_trigger_restart_min_framework();
-                SLOGI("Started framework to offer wipe");
-                if (setexeccon(NULL)) {
-                    SLOGE("Failed to setexeccon");
-                }
-                return -1;
-            }
-        }
-        if (setexeccon(NULL)) {
-            SLOGE("Failed to setexeccon");
-            return -1;
-        }
-
-        /* Create necessary paths on /data */
-        prep_data_fs();
-        property_set("vold.decrypt", "trigger_load_persist_props");
-
-        /* startup service classes main and late_start */
-        property_set("vold.decrypt", "trigger_restart_framework");
-        SLOGD("Just triggered restart_framework\n");
-
-        /* Give it a few moments to get started */
-        sleep(1);
-    }
-
-    if (rc == 0) {
-        restart_successful = 1;
-    }
-
-    return rc;
-}
-
-int cryptfs_restart(void) {
-    SLOGI("cryptfs_restart");
-    if (fscrypt_is_native()) {
-        SLOGE("cryptfs_restart not valid for file encryption:");
-        return -1;
-    }
-
-    /* Call internal implementation forcing a restart of main service group */
-    return cryptfs_restart_internal(1);
-}
-
-static int do_crypto_complete(const char* mount_point) {
-    struct crypt_mnt_ftr crypt_ftr;
-    char encrypted_state[PROPERTY_VALUE_MAX];
-
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (strcmp(encrypted_state, "encrypted")) {
-        SLOGE("not running with encryption, aborting");
-        return CRYPTO_COMPLETE_NOT_ENCRYPTED;
-    }
-
-    // crypto_complete is full disk encrypted status
-    if (fscrypt_is_native()) {
-        return CRYPTO_COMPLETE_NOT_ENCRYPTED;
-    }
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        std::string key_loc;
-        get_crypt_info(&key_loc, nullptr);
-
-        /*
-         * Only report this error if key_loc is a file and it exists.
-         * If the device was never encrypted, and /data is not mountable for
-         * some reason, returning 1 should prevent the UI from presenting the
-         * a "enter password" screen, or worse, a "press button to wipe the
-         * device" screen.
-         */
-        if (!key_loc.empty() && key_loc[0] == '/' && (access("key_loc", F_OK) == -1)) {
-            SLOGE("master key file does not exist, aborting");
-            return CRYPTO_COMPLETE_NOT_ENCRYPTED;
-        } else {
-            SLOGE("Error getting crypt footer and key\n");
-            return CRYPTO_COMPLETE_BAD_METADATA;
-        }
-    }
-
-    // Test for possible error flags
-    if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) {
-        SLOGE("Encryption process is partway completed\n");
-        return CRYPTO_COMPLETE_PARTIAL;
-    }
-
-    if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE) {
-        SLOGE("Encryption process was interrupted but cannot continue\n");
-        return CRYPTO_COMPLETE_INCONSISTENT;
-    }
-
-    if (crypt_ftr.flags & CRYPT_DATA_CORRUPT) {
-        SLOGE("Encryption is successful but data is corrupt\n");
-        return CRYPTO_COMPLETE_CORRUPT;
-    }
-
-    /* We passed the test! We shall diminish, and return to the west */
-    return CRYPTO_COMPLETE_ENCRYPTED;
-}
-
-static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, const char* passwd,
-                                   const char* mount_point, const char* label) {
-    unsigned char decrypted_master_key[MAX_KEY_LEN];
-    std::string crypto_blkdev;
-    std::string real_blkdev;
-    char tmp_mount_point[64];
-    unsigned int orig_failed_decrypt_count;
-    int rc;
-    int upgrade = 0;
-    unsigned char* intermediate_key = 0;
-    size_t intermediate_key_size = 0;
-    int N = 1 << crypt_ftr->N_factor;
-    int r = 1 << crypt_ftr->r_factor;
-    int p = 1 << crypt_ftr->p_factor;
-
-    SLOGD("crypt_ftr->fs_size = %lld\n", crypt_ftr->fs_size);
-    orig_failed_decrypt_count = crypt_ftr->failed_decrypt_count;
-
-    if (!(crypt_ftr->flags & CRYPT_MNT_KEY_UNENCRYPTED)) {
-        if (decrypt_master_key(passwd, decrypted_master_key, crypt_ftr, &intermediate_key,
-                               &intermediate_key_size)) {
-            SLOGE("Failed to decrypt master key\n");
-            rc = -1;
-            goto errout;
-        }
-    }
-
-    get_crypt_info(nullptr, &real_blkdev);
-
-    // Create crypto block device - all (non fatal) code paths
-    // need it
-    if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, real_blkdev.c_str(), &crypto_blkdev,
-                              label, 0)) {
-        SLOGE("Error creating decrypted block device\n");
-        rc = -1;
-        goto errout;
-    }
-
-    /* Work out if the problem is the password or the data */
-    unsigned char scrypted_intermediate_key[sizeof(crypt_ftr->scrypted_intermediate_key)];
-
-    rc = crypto_scrypt(intermediate_key, intermediate_key_size, crypt_ftr->salt,
-                       sizeof(crypt_ftr->salt), N, r, p, scrypted_intermediate_key,
-                       sizeof(scrypted_intermediate_key));
-
-    // Does the key match the crypto footer?
-    if (rc == 0 && memcmp(scrypted_intermediate_key, crypt_ftr->scrypted_intermediate_key,
-                          sizeof(scrypted_intermediate_key)) == 0) {
-        SLOGI("Password matches");
-        rc = 0;
-    } else {
-        /* Try mounting the file system anyway, just in case the problem's with
-         * the footer, not the key. */
-        snprintf(tmp_mount_point, sizeof(tmp_mount_point), "%s/tmp_mnt", mount_point);
-        mkdir(tmp_mount_point, 0755);
-        if (fs_mgr_do_mount(&fstab_default, DATA_MNT_POINT,
-                            const_cast<char*>(crypto_blkdev.c_str()), tmp_mount_point)) {
-            SLOGE("Error temp mounting decrypted block device\n");
-            delete_crypto_blk_dev(label);
-
-            rc = ++crypt_ftr->failed_decrypt_count;
-            put_crypt_ftr_and_key(crypt_ftr);
-        } else {
-            /* Success! */
-            SLOGI("Password did not match but decrypted drive mounted - continue");
-            umount(tmp_mount_point);
-            rc = 0;
-        }
-    }
-
-    if (rc == 0) {
-        crypt_ftr->failed_decrypt_count = 0;
-        if (orig_failed_decrypt_count != 0) {
-            put_crypt_ftr_and_key(crypt_ftr);
-        }
-
-        /* Save the name of the crypto block device
-         * so we can mount it when restarting the framework. */
-        property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev.c_str());
-
-        /* Also save a the master key so we can reencrypted the key
-         * the key when we want to change the password on it. */
-        memcpy(saved_master_key, decrypted_master_key, crypt_ftr->keysize);
-        saved_mount_point = strdup(mount_point);
-        master_key_saved = 1;
-        SLOGD("%s(): Master key saved\n", __FUNCTION__);
-        rc = 0;
-
-        // Upgrade if we're not using the latest KDF.
-        if (crypt_ftr->kdf_type != KDF_SCRYPT_KEYMASTER) {
-            crypt_ftr->kdf_type = KDF_SCRYPT_KEYMASTER;
-            upgrade = 1;
-        }
-
-        if (upgrade) {
-            rc = encrypt_master_key(passwd, crypt_ftr->salt, saved_master_key,
-                                    crypt_ftr->master_key, crypt_ftr);
-            if (!rc) {
-                rc = put_crypt_ftr_and_key(crypt_ftr);
-            }
-            SLOGD("Key Derivation Function upgrade: rc=%d\n", rc);
-
-            // Do not fail even if upgrade failed - machine is bootable
-            // Note that if this code is ever hit, there is a *serious* problem
-            // since KDFs should never fail. You *must* fix the kdf before
-            // proceeding!
-            if (rc) {
-                SLOGW(
-                    "Upgrade failed with error %d,"
-                    " but continuing with previous state",
-                    rc);
-                rc = 0;
-            }
-        }
-    }
-
-errout:
-    if (intermediate_key) {
-        memset(intermediate_key, 0, intermediate_key_size);
-        free(intermediate_key);
-    }
-    return rc;
-}
-
 /*
  * Called by vold when it's asked to mount an encrypted external
  * storage volume. The incoming partition has no crypto header/footer,
@@ -1967,899 +145,54 @@
         return -1;
     }
 
-    struct crypt_mnt_ftr ext_crypt_ftr;
-    memset(&ext_crypt_ftr, 0, sizeof(ext_crypt_ftr));
-    ext_crypt_ftr.fs_size = nr_sec;
-    ext_crypt_ftr.keysize = crypto_type.get_keysize();
-    strlcpy((char*)ext_crypt_ftr.crypto_type_name, crypto_type.get_kernel_name(),
-            MAX_CRYPTO_TYPE_NAME_LEN);
-    uint32_t flags = 0;
+    auto& dm = DeviceMapper::Instance();
+
+    // We need two ASCII characters to represent each byte, and need space for
+    // the '\0' terminator.
+    char key_ascii[MAX_KEY_LEN * 2 + 1];
+    convert_key_to_hex_ascii(key, key_ascii);
+
+    auto target = std::make_unique<DmTargetCrypt>(0, nr_sec, crypto_type.get_kernel_name(),
+                                                  key_ascii, 0, real_blkdev, 0);
+    target->AllowDiscards();
+
     if (fscrypt_is_native() &&
-        android::base::GetBoolProperty("ro.crypto.allow_encrypt_override", false))
-        flags |= CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE;
-
-    return create_crypto_blk_dev(&ext_crypt_ftr, reinterpret_cast<const unsigned char*>(key.data()),
-                                 real_blkdev, out_crypto_blkdev, label, flags);
-}
-
-int cryptfs_crypto_complete(void) {
-    return do_crypto_complete("/data");
-}
-
-int check_unmounted_and_get_ftr(struct crypt_mnt_ftr* crypt_ftr) {
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (master_key_saved || strcmp(encrypted_state, "encrypted")) {
-        SLOGE(
-            "encrypted fs already validated or not running with encryption,"
-            " aborting");
+        android::base::GetBoolProperty("ro.crypto.allow_encrypt_override", false)) {
+        target->AllowEncryptOverride();
+    }
+    if (add_sector_size_param(target.get(), &nr_sec)) {
+        SLOGE("Error processing dm-crypt sector size param\n");
         return -1;
     }
 
-    if (get_crypt_ftr_and_key(crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key");
+    DmTable table;
+    table.AddTarget(std::move(target));
+
+    int load_count = 1;
+    while (load_count < TABLE_LOAD_RETRIES) {
+        if (dm.CreateDevice(label, table)) {
+            break;
+        }
+        load_count++;
+    }
+
+    if (load_count >= TABLE_LOAD_RETRIES) {
+        SLOGE("Cannot load dm-crypt mapping table.\n");
+        return -1;
+    }
+    if (load_count > 1) {
+        SLOGI("Took %d tries to load dmcrypt table.\n", load_count);
+    }
+
+    if (!dm.GetDmDevicePathByName(label, out_crypto_blkdev)) {
+        SLOGE("Cannot determine dm-crypt path for %s.\n", label);
         return -1;
     }
 
+    /* Ensure the dm device has been created before returning. */
+    if (android::vold::WaitForFile(out_crypto_blkdev->c_str(), 1s) < 0) {
+        // WaitForFile generates a suitable log message
+        return -1;
+    }
     return 0;
 }
-
-int cryptfs_check_passwd(const char* passwd) {
-    SLOGI("cryptfs_check_passwd");
-    if (fscrypt_is_native()) {
-        SLOGE("cryptfs_check_passwd not valid for file encryption");
-        return -1;
-    }
-
-    struct crypt_mnt_ftr crypt_ftr;
-    int rc;
-
-    rc = check_unmounted_and_get_ftr(&crypt_ftr);
-    if (rc) {
-        SLOGE("Could not get footer");
-        return rc;
-    }
-
-    rc = test_mount_encrypted_fs(&crypt_ftr, passwd, DATA_MNT_POINT, CRYPTO_BLOCK_DEVICE);
-    if (rc) {
-        SLOGE("Password did not match");
-        return rc;
-    }
-
-    if (crypt_ftr.flags & CRYPT_FORCE_COMPLETE) {
-        // Here we have a default actual password but a real password
-        // we must test against the scrypted value
-        // First, we must delete the crypto block device that
-        // test_mount_encrypted_fs leaves behind as a side effect
-        delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE);
-        rc = test_mount_encrypted_fs(&crypt_ftr, DEFAULT_PASSWORD, DATA_MNT_POINT,
-                                     CRYPTO_BLOCK_DEVICE);
-        if (rc) {
-            SLOGE("Default password did not match on reboot encryption");
-            return rc;
-        }
-
-        crypt_ftr.flags &= ~CRYPT_FORCE_COMPLETE;
-        put_crypt_ftr_and_key(&crypt_ftr);
-        rc = cryptfs_changepw(crypt_ftr.crypt_type, passwd);
-        if (rc) {
-            SLOGE("Could not change password on reboot encryption");
-            return rc;
-        }
-    }
-
-    if (crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) {
-        cryptfs_clear_password();
-        password = strdup(passwd);
-        struct timespec now;
-        clock_gettime(CLOCK_BOOTTIME, &now);
-        password_expiry_time = now.tv_sec + password_max_age_seconds;
-    }
-
-    return rc;
-}
-
-int cryptfs_verify_passwd(const char* passwd) {
-    struct crypt_mnt_ftr crypt_ftr;
-    unsigned char decrypted_master_key[MAX_KEY_LEN];
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    int rc;
-
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (strcmp(encrypted_state, "encrypted")) {
-        SLOGE("device not encrypted, aborting");
-        return -2;
-    }
-
-    if (!master_key_saved) {
-        SLOGE("encrypted fs not yet mounted, aborting");
-        return -1;
-    }
-
-    if (!saved_mount_point) {
-        SLOGE("encrypted fs failed to save mount point, aborting");
-        return -1;
-    }
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key\n");
-        return -1;
-    }
-
-    if (crypt_ftr.flags & CRYPT_MNT_KEY_UNENCRYPTED) {
-        /* If the device has no password, then just say the password is valid */
-        rc = 0;
-    } else {
-        decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
-        if (!memcmp(decrypted_master_key, saved_master_key, crypt_ftr.keysize)) {
-            /* They match, the password is correct */
-            rc = 0;
-        } else {
-            /* If incorrect, sleep for a bit to prevent dictionary attacks */
-            sleep(1);
-            rc = 1;
-        }
-    }
-
-    return rc;
-}
-
-/* Initialize a crypt_mnt_ftr structure.  The keysize is
- * defaulted to get_crypto_type().get_keysize() bytes, and the filesystem size to 0.
- * Presumably, at a minimum, the caller will update the
- * filesystem size and crypto_type_name after calling this function.
- */
-static int cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr* ftr) {
-    off64_t off;
-
-    memset(ftr, 0, sizeof(struct crypt_mnt_ftr));
-    ftr->magic = CRYPT_MNT_MAGIC;
-    ftr->major_version = CURRENT_MAJOR_VERSION;
-    ftr->minor_version = CURRENT_MINOR_VERSION;
-    ftr->ftr_size = sizeof(struct crypt_mnt_ftr);
-    ftr->keysize = get_crypto_type().get_keysize();
-    ftr->kdf_type = KDF_SCRYPT_KEYMASTER;
-
-    get_device_scrypt_params(ftr);
-
-    ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE;
-    if (get_crypt_ftr_info(NULL, &off) == 0) {
-        ftr->persist_data_offset[0] = off + CRYPT_FOOTER_TO_PERSIST_OFFSET;
-        ftr->persist_data_offset[1] = off + CRYPT_FOOTER_TO_PERSIST_OFFSET + ftr->persist_data_size;
-    }
-
-    return 0;
-}
-
-#define FRAMEWORK_BOOT_WAIT 60
-
-static int vold_unmountAll(void) {
-    VolumeManager* vm = VolumeManager::Instance();
-    return vm->unmountAll();
-}
-
-int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
-    std::string crypto_blkdev;
-    std::string real_blkdev;
-    unsigned char decrypted_master_key[MAX_KEY_LEN];
-    int rc = -1, i;
-    struct crypt_mnt_ftr crypt_ftr;
-    struct crypt_persist_data* pdata;
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    char lockid[32] = {0};
-    std::string key_loc;
-    int num_vols;
-    bool rebootEncryption = false;
-    bool onlyCreateHeader = false;
-
-    /* Get a wakelock as this may take a while, and we don't want the
-     * device to sleep on us.  We'll grab a partial wakelock, and if the UI
-     * wants to keep the screen on, it can grab a full wakelock.
-     */
-    snprintf(lockid, sizeof(lockid), "enablecrypto%d", (int)getpid());
-    auto wl = android::wakelock::WakeLock::tryGet(lockid);
-    if (!wl.has_value()) {
-        return android::UNEXPECTED_NULL;
-    }
-
-    if (get_crypt_ftr_and_key(&crypt_ftr) == 0) {
-        if (crypt_ftr.flags & CRYPT_FORCE_ENCRYPTION) {
-            if (!check_ftr_sha(&crypt_ftr)) {
-                memset(&crypt_ftr, 0, sizeof(crypt_ftr));
-                put_crypt_ftr_and_key(&crypt_ftr);
-                goto error_unencrypted;
-            }
-
-            /* Doing a reboot-encryption*/
-            crypt_ftr.flags &= ~CRYPT_FORCE_ENCRYPTION;
-            crypt_ftr.flags |= CRYPT_FORCE_COMPLETE;
-            rebootEncryption = true;
-        }
-    } else {
-        // We don't want to accidentally reference invalid data.
-        memset(&crypt_ftr, 0, sizeof(crypt_ftr));
-    }
-
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (!strcmp(encrypted_state, "encrypted")) {
-        SLOGE("Device is already running encrypted, aborting");
-        goto error_unencrypted;
-    }
-
-    get_crypt_info(&key_loc, &real_blkdev);
-
-    /* Get the size of the real block device */
-    uint64_t nr_sec;
-    if (android::vold::GetBlockDev512Sectors(real_blkdev, &nr_sec) != android::OK) {
-        SLOGE("Cannot get size of block device %s\n", real_blkdev.c_str());
-        goto error_unencrypted;
-    }
-
-    /* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */
-    if (key_loc == KEY_IN_FOOTER) {
-        uint64_t fs_size_sec, max_fs_size_sec;
-        fs_size_sec = get_fs_size(real_blkdev.c_str());
-        if (fs_size_sec == 0) fs_size_sec = get_f2fs_filesystem_size_sec(real_blkdev.data());
-
-        max_fs_size_sec = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
-
-        if (fs_size_sec > max_fs_size_sec) {
-            SLOGE("Orig filesystem overlaps crypto footer region.  Cannot encrypt in place.");
-            goto error_unencrypted;
-        }
-    }
-
-    /* The init files are setup to stop the class main and late start when
-     * vold sets trigger_shutdown_framework.
-     */
-    property_set("vold.decrypt", "trigger_shutdown_framework");
-    SLOGD("Just asked init to shut down class main\n");
-
-    /* Ask vold to unmount all devices that it manages */
-    if (vold_unmountAll()) {
-        SLOGE("Failed to unmount all vold managed devices");
-    }
-
-    /* no_ui means we are being called from init, not settings.
-       Now we always reboot from settings, so !no_ui means reboot
-     */
-    if (!no_ui) {
-        /* Try fallback, which is to reboot and try there */
-        onlyCreateHeader = true;
-        FILE* breadcrumb = fopen(BREADCRUMB_FILE, "we");
-        if (breadcrumb == 0) {
-            SLOGE("Failed to create breadcrumb file");
-            goto error_shutting_down;
-        }
-        fclose(breadcrumb);
-    }
-
-    /* Do extra work for a better UX when doing the long inplace encryption */
-    if (!onlyCreateHeader) {
-        /* Now that /data is unmounted, we need to mount a tmpfs
-         * /data, set a property saying we're doing inplace encryption,
-         * and restart the framework.
-         */
-        wait_and_unmount(DATA_MNT_POINT);
-        if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) {
-            goto error_shutting_down;
-        }
-        /* Tells the framework that inplace encryption is starting */
-        property_set("vold.encrypt_progress", "0");
-
-        /* restart the framework. */
-        /* Create necessary paths on /data */
-        prep_data_fs();
-
-        /* Ugh, shutting down the framework is not synchronous, so until it
-         * can be fixed, this horrible hack will wait a moment for it all to
-         * shut down before proceeding.  Without it, some devices cannot
-         * restart the graphics services.
-         */
-        sleep(2);
-    }
-
-    /* Start the actual work of making an encrypted filesystem */
-    /* Initialize a crypt_mnt_ftr for the partition */
-    if (!rebootEncryption) {
-        if (cryptfs_init_crypt_mnt_ftr(&crypt_ftr)) {
-            goto error_shutting_down;
-        }
-
-        if (key_loc == KEY_IN_FOOTER) {
-            crypt_ftr.fs_size = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
-        } else {
-            crypt_ftr.fs_size = nr_sec;
-        }
-        /* At this point, we are in an inconsistent state. Until we successfully
-           complete encryption, a reboot will leave us broken. So mark the
-           encryption failed in case that happens.
-           On successfully completing encryption, remove this flag */
-        if (onlyCreateHeader) {
-            crypt_ftr.flags |= CRYPT_FORCE_ENCRYPTION;
-        } else {
-            crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
-        }
-        crypt_ftr.crypt_type = crypt_type;
-        strlcpy((char*)crypt_ftr.crypto_type_name, get_crypto_type().get_kernel_name(),
-                MAX_CRYPTO_TYPE_NAME_LEN);
-
-        /* Make an encrypted master key */
-        if (create_encrypted_random_key(onlyCreateHeader ? DEFAULT_PASSWORD : passwd,
-                                        crypt_ftr.master_key, crypt_ftr.salt, &crypt_ftr)) {
-            SLOGE("Cannot create encrypted master key\n");
-            goto error_shutting_down;
-        }
-
-        /* Replace scrypted intermediate key if we are preparing for a reboot */
-        if (onlyCreateHeader) {
-            unsigned char fake_master_key[MAX_KEY_LEN];
-            unsigned char encrypted_fake_master_key[MAX_KEY_LEN];
-            memset(fake_master_key, 0, sizeof(fake_master_key));
-            encrypt_master_key(passwd, crypt_ftr.salt, fake_master_key, encrypted_fake_master_key,
-                               &crypt_ftr);
-        }
-
-        /* Write the key to the end of the partition */
-        put_crypt_ftr_and_key(&crypt_ftr);
-
-        /* If any persistent data has been remembered, save it.
-         * If none, create a valid empty table and save that.
-         */
-        if (!persist_data) {
-            pdata = (crypt_persist_data*)malloc(CRYPT_PERSIST_DATA_SIZE);
-            if (pdata) {
-                init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
-                persist_data = pdata;
-            }
-        }
-        if (persist_data) {
-            save_persistent_data();
-        }
-    }
-
-    if (onlyCreateHeader) {
-        sleep(2);
-        cryptfs_reboot(RebootType::reboot);
-    }
-
-    if (!no_ui || rebootEncryption) {
-        /* startup service classes main and late_start */
-        property_set("vold.decrypt", "trigger_restart_min_framework");
-        SLOGD("Just triggered restart_min_framework\n");
-
-        /* OK, the framework is restarted and will soon be showing a
-         * progress bar.  Time to setup an encrypted mapping, and
-         * either write a new filesystem, or encrypt in place updating
-         * the progress bar as we work.
-         */
-    }
-
-    decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
-    rc = create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev.c_str(),
-                               &crypto_blkdev, CRYPTO_BLOCK_DEVICE, 0);
-    if (!rc) {
-        if (encrypt_inplace(crypto_blkdev, real_blkdev, crypt_ftr.fs_size, true)) {
-            crypt_ftr.encrypted_upto = crypt_ftr.fs_size;
-            rc = 0;
-        } else {
-            rc = -1;
-        }
-        /* Undo the dm-crypt mapping whether we succeed or not */
-        delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE);
-    }
-
-    if (!rc) {
-        /* Success */
-        crypt_ftr.flags &= ~CRYPT_INCONSISTENT_STATE;
-
-        put_crypt_ftr_and_key(&crypt_ftr);
-
-        char value[PROPERTY_VALUE_MAX];
-        property_get("ro.crypto.state", value, "");
-        if (!strcmp(value, "")) {
-            /* default encryption - continue first boot sequence */
-            property_set("ro.crypto.state", "encrypted");
-            property_set("ro.crypto.type", "block");
-            wl.reset();
-            if (rebootEncryption && crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) {
-                // Bring up cryptkeeper that will check the password and set it
-                property_set("vold.decrypt", "trigger_shutdown_framework");
-                sleep(2);
-                property_set("vold.encrypt_progress", "");
-                cryptfs_trigger_restart_min_framework();
-            } else {
-                cryptfs_check_passwd(DEFAULT_PASSWORD);
-                cryptfs_restart_internal(1);
-            }
-            return 0;
-        } else {
-            sleep(2); /* Give the UI a chance to show 100% progress */
-            cryptfs_reboot(RebootType::reboot);
-        }
-    } else {
-        char value[PROPERTY_VALUE_MAX];
-
-        property_get("ro.vold.wipe_on_crypt_fail", value, "0");
-        if (!strcmp(value, "1")) {
-            /* wipe data if encryption failed */
-            SLOGE("encryption failed - rebooting into recovery to wipe data\n");
-            std::string err;
-            const std::vector<std::string> options = {
-                "--wipe_data\n--reason=cryptfs_enable_internal\n"};
-            if (!write_bootloader_message(options, &err)) {
-                SLOGE("could not write bootloader message: %s", err.c_str());
-            }
-            cryptfs_reboot(RebootType::recovery);
-        } else {
-            /* set property to trigger dialog */
-            property_set("vold.encrypt_progress", "error_partially_encrypted");
-        }
-        return -1;
-    }
-
-    /* hrm, the encrypt step claims success, but the reboot failed.
-     * This should not happen.
-     * Set the property and return.  Hope the framework can deal with it.
-     */
-    property_set("vold.encrypt_progress", "error_reboot_failed");
-    return rc;
-
-error_unencrypted:
-    property_set("vold.encrypt_progress", "error_not_encrypted");
-    return -1;
-
-error_shutting_down:
-    /* we failed, and have not encrypted anthing, so the users's data is still intact,
-     * but the framework is stopped and not restarted to show the error, so it's up to
-     * vold to restart the system.
-     */
-    SLOGE(
-        "Error enabling encryption after framework is shutdown, no data changed, restarting "
-        "system");
-    cryptfs_reboot(RebootType::reboot);
-
-    /* shouldn't get here */
-    property_set("vold.encrypt_progress", "error_shutting_down");
-    return -1;
-}
-
-int cryptfs_enable(int type, const char* passwd, int no_ui) {
-    return cryptfs_enable_internal(type, passwd, no_ui);
-}
-
-int cryptfs_enable_default(int no_ui) {
-    return cryptfs_enable_internal(CRYPT_TYPE_DEFAULT, DEFAULT_PASSWORD, no_ui);
-}
-
-int cryptfs_changepw(int crypt_type, const char* newpw) {
-    if (fscrypt_is_native()) {
-        SLOGE("cryptfs_changepw not valid for file encryption");
-        return -1;
-    }
-
-    struct crypt_mnt_ftr crypt_ftr;
-    int rc;
-
-    /* This is only allowed after we've successfully decrypted the master key */
-    if (!master_key_saved) {
-        SLOGE("Key not saved, aborting");
-        return -1;
-    }
-
-    if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
-        SLOGE("Invalid crypt_type %d", crypt_type);
-        return -1;
-    }
-
-    /* get key */
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key");
-        return -1;
-    }
-
-    crypt_ftr.crypt_type = crypt_type;
-
-    rc = encrypt_master_key(crypt_type == CRYPT_TYPE_DEFAULT ? DEFAULT_PASSWORD : newpw,
-                            crypt_ftr.salt, saved_master_key, crypt_ftr.master_key, &crypt_ftr);
-    if (rc) {
-        SLOGE("Encrypt master key failed: %d", rc);
-        return -1;
-    }
-    /* save the key */
-    put_crypt_ftr_and_key(&crypt_ftr);
-
-    return 0;
-}
-
-static unsigned int persist_get_max_entries(int encrypted) {
-    struct crypt_mnt_ftr crypt_ftr;
-    unsigned int dsize;
-
-    /* If encrypted, use the values from the crypt_ftr, otherwise
-     * use the values for the current spec.
-     */
-    if (encrypted) {
-        if (get_crypt_ftr_and_key(&crypt_ftr)) {
-            /* Something is wrong, assume no space for entries */
-            return 0;
-        }
-        dsize = crypt_ftr.persist_data_size;
-    } else {
-        dsize = CRYPT_PERSIST_DATA_SIZE;
-    }
-
-    if (dsize > sizeof(struct crypt_persist_data)) {
-        return (dsize - sizeof(struct crypt_persist_data)) / sizeof(struct crypt_persist_entry);
-    } else {
-        return 0;
-    }
-}
-
-static int persist_get_key(const char* fieldname, char* value) {
-    unsigned int i;
-
-    if (persist_data == NULL) {
-        return -1;
-    }
-    for (i = 0; i < persist_data->persist_valid_entries; i++) {
-        if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) {
-            /* We found it! */
-            strlcpy(value, persist_data->persist_entry[i].val, PROPERTY_VALUE_MAX);
-            return 0;
-        }
-    }
-
-    return -1;
-}
-
-static int persist_set_key(const char* fieldname, const char* value, int encrypted) {
-    unsigned int i;
-    unsigned int num;
-    unsigned int max_persistent_entries;
-
-    if (persist_data == NULL) {
-        return -1;
-    }
-
-    max_persistent_entries = persist_get_max_entries(encrypted);
-
-    num = persist_data->persist_valid_entries;
-
-    for (i = 0; i < num; i++) {
-        if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) {
-            /* We found an existing entry, update it! */
-            memset(persist_data->persist_entry[i].val, 0, PROPERTY_VALUE_MAX);
-            strlcpy(persist_data->persist_entry[i].val, value, PROPERTY_VALUE_MAX);
-            return 0;
-        }
-    }
-
-    /* We didn't find it, add it to the end, if there is room */
-    if (persist_data->persist_valid_entries < max_persistent_entries) {
-        memset(&persist_data->persist_entry[num], 0, sizeof(struct crypt_persist_entry));
-        strlcpy(persist_data->persist_entry[num].key, fieldname, PROPERTY_KEY_MAX);
-        strlcpy(persist_data->persist_entry[num].val, value, PROPERTY_VALUE_MAX);
-        persist_data->persist_valid_entries++;
-        return 0;
-    }
-
-    return -1;
-}
-
-/**
- * Test if key is part of the multi-entry (field, index) sequence. Return non-zero if key is in the
- * sequence and its index is greater than or equal to index. Return 0 otherwise.
- */
-int match_multi_entry(const char* key, const char* field, unsigned index) {
-    std::string key_ = key;
-    std::string field_ = field;
-
-    std::string parsed_field;
-    unsigned parsed_index;
-
-    std::string::size_type split = key_.find_last_of('_');
-    if (split == std::string::npos) {
-        parsed_field = key_;
-        parsed_index = 0;
-    } else {
-        parsed_field = key_.substr(0, split);
-        parsed_index = std::stoi(key_.substr(split + 1));
-    }
-
-    return parsed_field == field_ && parsed_index >= index;
-}
-
-/*
- * Delete entry/entries from persist_data. If the entries are part of a multi-segment field, all
- * remaining entries starting from index will be deleted.
- * returns PERSIST_DEL_KEY_OK if deletion succeeds,
- * PERSIST_DEL_KEY_ERROR_NO_FIELD if the field does not exist,
- * and PERSIST_DEL_KEY_ERROR_OTHER if error occurs.
- *
- */
-static int persist_del_keys(const char* fieldname, unsigned index) {
-    unsigned int i;
-    unsigned int j;
-    unsigned int num;
-
-    if (persist_data == NULL) {
-        return PERSIST_DEL_KEY_ERROR_OTHER;
-    }
-
-    num = persist_data->persist_valid_entries;
-
-    j = 0;  // points to the end of non-deleted entries.
-    // Filter out to-be-deleted entries in place.
-    for (i = 0; i < num; i++) {
-        if (!match_multi_entry(persist_data->persist_entry[i].key, fieldname, index)) {
-            persist_data->persist_entry[j] = persist_data->persist_entry[i];
-            j++;
-        }
-    }
-
-    if (j < num) {
-        persist_data->persist_valid_entries = j;
-        // Zeroise the remaining entries
-        memset(&persist_data->persist_entry[j], 0, (num - j) * sizeof(struct crypt_persist_entry));
-        return PERSIST_DEL_KEY_OK;
-    } else {
-        // Did not find an entry matching the given fieldname
-        return PERSIST_DEL_KEY_ERROR_NO_FIELD;
-    }
-}
-
-static int persist_count_keys(const char* fieldname) {
-    unsigned int i;
-    unsigned int count;
-
-    if (persist_data == NULL) {
-        return -1;
-    }
-
-    count = 0;
-    for (i = 0; i < persist_data->persist_valid_entries; i++) {
-        if (match_multi_entry(persist_data->persist_entry[i].key, fieldname, 0)) {
-            count++;
-        }
-    }
-
-    return count;
-}
-
-/* Return the value of the specified field. */
-int cryptfs_getfield(const char* fieldname, char* value, int len) {
-    if (fscrypt_is_native()) {
-        SLOGE("Cannot get field when file encrypted");
-        return -1;
-    }
-
-    char temp_value[PROPERTY_VALUE_MAX];
-    /* CRYPTO_GETFIELD_OK is success,
-     * CRYPTO_GETFIELD_ERROR_NO_FIELD is value not set,
-     * CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL is buffer (as given by len) too small,
-     * CRYPTO_GETFIELD_ERROR_OTHER is any other error
-     */
-    int rc = CRYPTO_GETFIELD_ERROR_OTHER;
-    int i;
-    char temp_field[PROPERTY_KEY_MAX];
-
-    if (persist_data == NULL) {
-        load_persistent_data();
-        if (persist_data == NULL) {
-            SLOGE("Getfield error, cannot load persistent data");
-            goto out;
-        }
-    }
-
-    // Read value from persistent entries. If the original value is split into multiple entries,
-    // stitch them back together.
-    if (!persist_get_key(fieldname, temp_value)) {
-        // We found it, copy it to the caller's buffer and keep going until all entries are read.
-        if (strlcpy(value, temp_value, len) >= (unsigned)len) {
-            // value too small
-            rc = CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL;
-            goto out;
-        }
-        rc = CRYPTO_GETFIELD_OK;
-
-        for (i = 1; /* break explicitly */; i++) {
-            if (snprintf(temp_field, sizeof(temp_field), "%s_%d", fieldname, i) >=
-                (int)sizeof(temp_field)) {
-                // If the fieldname is very long, we stop as soon as it begins to overflow the
-                // maximum field length. At this point we have in fact fully read out the original
-                // value because cryptfs_setfield would not allow fields with longer names to be
-                // written in the first place.
-                break;
-            }
-            if (!persist_get_key(temp_field, temp_value)) {
-                if (strlcat(value, temp_value, len) >= (unsigned)len) {
-                    // value too small.
-                    rc = CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL;
-                    goto out;
-                }
-            } else {
-                // Exhaust all entries.
-                break;
-            }
-        }
-    } else {
-        /* Sadness, it's not there.  Return the error */
-        rc = CRYPTO_GETFIELD_ERROR_NO_FIELD;
-    }
-
-out:
-    return rc;
-}
-
-/* Set the value of the specified field. */
-int cryptfs_setfield(const char* fieldname, const char* value) {
-    if (fscrypt_is_native()) {
-        SLOGE("Cannot set field when file encrypted");
-        return -1;
-    }
-
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    /* 0 is success, negative values are error */
-    int rc = CRYPTO_SETFIELD_ERROR_OTHER;
-    int encrypted = 0;
-    unsigned int field_id;
-    char temp_field[PROPERTY_KEY_MAX];
-    unsigned int num_entries;
-    unsigned int max_keylen;
-
-    if (persist_data == NULL) {
-        load_persistent_data();
-        if (persist_data == NULL) {
-            SLOGE("Setfield error, cannot load persistent data");
-            goto out;
-        }
-    }
-
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (!strcmp(encrypted_state, "encrypted")) {
-        encrypted = 1;
-    }
-
-    // Compute the number of entries required to store value, each entry can store up to
-    // (PROPERTY_VALUE_MAX - 1) chars
-    if (strlen(value) == 0) {
-        // Empty value also needs one entry to store.
-        num_entries = 1;
-    } else {
-        num_entries = (strlen(value) + (PROPERTY_VALUE_MAX - 1) - 1) / (PROPERTY_VALUE_MAX - 1);
-    }
-
-    max_keylen = strlen(fieldname);
-    if (num_entries > 1) {
-        // Need an extra "_%d" suffix.
-        max_keylen += 1 + log10(num_entries);
-    }
-    if (max_keylen > PROPERTY_KEY_MAX - 1) {
-        rc = CRYPTO_SETFIELD_ERROR_FIELD_TOO_LONG;
-        goto out;
-    }
-
-    // Make sure we have enough space to write the new value
-    if (persist_data->persist_valid_entries + num_entries - persist_count_keys(fieldname) >
-        persist_get_max_entries(encrypted)) {
-        rc = CRYPTO_SETFIELD_ERROR_VALUE_TOO_LONG;
-        goto out;
-    }
-
-    // Now that we know persist_data has enough space for value, let's delete the old field first
-    // to make up space.
-    persist_del_keys(fieldname, 0);
-
-    if (persist_set_key(fieldname, value, encrypted)) {
-        // fail to set key, should not happen as we have already checked the available space
-        SLOGE("persist_set_key() error during setfield()");
-        goto out;
-    }
-
-    for (field_id = 1; field_id < num_entries; field_id++) {
-        snprintf(temp_field, sizeof(temp_field), "%s_%u", fieldname, field_id);
-
-        if (persist_set_key(temp_field, value + field_id * (PROPERTY_VALUE_MAX - 1), encrypted)) {
-            // fail to set key, should not happen as we have already checked the available space.
-            SLOGE("persist_set_key() error during setfield()");
-            goto out;
-        }
-    }
-
-    /* If we are running encrypted, save the persistent data now */
-    if (encrypted) {
-        if (save_persistent_data()) {
-            SLOGE("Setfield error, cannot save persistent data");
-            goto out;
-        }
-    }
-
-    rc = CRYPTO_SETFIELD_OK;
-
-out:
-    return rc;
-}
-
-/* Checks userdata. Attempt to mount the volume if default-
- * encrypted.
- * On success trigger next init phase and return 0.
- * Currently do not handle failure - see TODO below.
- */
-int cryptfs_mount_default_encrypted(void) {
-    int crypt_type = cryptfs_get_password_type();
-    if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
-        SLOGE("Bad crypt type - error");
-    } else if (crypt_type != CRYPT_TYPE_DEFAULT) {
-        SLOGD(
-            "Password is not default - "
-            "starting min framework to prompt");
-        property_set("vold.decrypt", "trigger_restart_min_framework");
-        return 0;
-    } else if (cryptfs_check_passwd(DEFAULT_PASSWORD) == 0) {
-        SLOGD("Password is default - restarting filesystem");
-        cryptfs_restart_internal(0);
-        return 0;
-    } else {
-        SLOGE("Encrypted, default crypt type but can't decrypt");
-    }
-
-    /** Corrupt. Allow us to boot into framework, which will detect bad
-        crypto when it calls do_crypto_complete, then do a factory reset
-     */
-    property_set("vold.decrypt", "trigger_restart_min_framework");
-    return 0;
-}
-
-/* Returns type of the password, default, pattern, pin or password.
- */
-int cryptfs_get_password_type(void) {
-    if (fscrypt_is_native()) {
-        SLOGE("cryptfs_get_password_type not valid for file encryption");
-        return -1;
-    }
-
-    struct crypt_mnt_ftr crypt_ftr;
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key\n");
-        return -1;
-    }
-
-    if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE) {
-        return -1;
-    }
-
-    return crypt_ftr.crypt_type;
-}
-
-const char* cryptfs_get_password() {
-    if (fscrypt_is_native()) {
-        SLOGE("cryptfs_get_password not valid for file encryption");
-        return 0;
-    }
-
-    struct timespec now;
-    clock_gettime(CLOCK_BOOTTIME, &now);
-    if (now.tv_sec < password_expiry_time) {
-        return password;
-    } else {
-        cryptfs_clear_password();
-        return 0;
-    }
-}
-
-void cryptfs_clear_password() {
-    if (password) {
-        size_t len = strlen(password);
-        memset(password, 0, len);
-        free(password);
-        password = 0;
-        password_expiry_time = 0;
-    }
-}
-
-int cryptfs_isConvertibleToFBE() {
-    auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
-    return entry && entry->fs_mgr_flags.force_fde_or_fbe;
-}
diff --git a/cryptfs.h b/cryptfs.h
index 872806e..e166f49 100644
--- a/cryptfs.h
+++ b/cryptfs.h
@@ -19,61 +19,11 @@
 
 #include <string>
 
-#include <linux/types.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#include <cutils/properties.h>
-
 #include "KeyBuffer.h"
 #include "KeyUtil.h"
 
-#define CRYPT_FOOTER_OFFSET 0x4000
-
-/* Return values for cryptfs_crypto_complete */
-#define CRYPTO_COMPLETE_NOT_ENCRYPTED 1
-#define CRYPTO_COMPLETE_ENCRYPTED 0
-#define CRYPTO_COMPLETE_BAD_METADATA (-1)
-#define CRYPTO_COMPLETE_PARTIAL (-2)
-#define CRYPTO_COMPLETE_INCONSISTENT (-3)
-#define CRYPTO_COMPLETE_CORRUPT (-4)
-
-/* Return values for cryptfs_getfield */
-#define CRYPTO_GETFIELD_OK 0
-#define CRYPTO_GETFIELD_ERROR_NO_FIELD (-1)
-#define CRYPTO_GETFIELD_ERROR_OTHER (-2)
-#define CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL (-3)
-
-/* Return values for cryptfs_setfield */
-#define CRYPTO_SETFIELD_OK 0
-#define CRYPTO_SETFIELD_ERROR_OTHER (-1)
-#define CRYPTO_SETFIELD_ERROR_FIELD_TOO_LONG (-2)
-#define CRYPTO_SETFIELD_ERROR_VALUE_TOO_LONG (-3)
-
-/* Return values for persist_del_key */
-#define PERSIST_DEL_KEY_OK 0
-#define PERSIST_DEL_KEY_ERROR_OTHER (-1)
-#define PERSIST_DEL_KEY_ERROR_NO_FIELD (-2)
-
-// Exposed for testing only
-int match_multi_entry(const char* key, const char* field, unsigned index);
-
-int cryptfs_crypto_complete(void);
-int cryptfs_check_passwd(const char* pw);
-int cryptfs_verify_passwd(const char* pw);
-int cryptfs_restart(void);
-int cryptfs_enable(int type, const char* passwd, int no_ui);
-int cryptfs_changepw(int type, const char* newpw);
-int cryptfs_enable_default(int no_ui);
 int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev,
                              const android::vold::KeyBuffer& key, std::string* out_crypto_blkdev);
-int cryptfs_getfield(const char* fieldname, char* value, int len);
-int cryptfs_setfield(const char* fieldname, const char* value);
-int cryptfs_mount_default_encrypted(void);
-int cryptfs_get_password_type(void);
-const char* cryptfs_get_password(void);
-void cryptfs_clear_password(void);
-int cryptfs_isConvertibleToFBE(void);
 const android::vold::KeyGeneration cryptfs_get_keygen();
 
 #endif /* ANDROID_VOLD_CRYPTFS_H */
diff --git a/fs/Exfat.cpp b/fs/Exfat.cpp
index 7782dd3..c8b19e0 100644
--- a/fs/Exfat.cpp
+++ b/fs/Exfat.cpp
@@ -44,7 +44,7 @@
     cmd.push_back("-y");
     cmd.push_back(source);
 
-    int rc = ForkExecvp(cmd, nullptr, sFsckUntrustedContext);
+    int rc = ForkExecvpTimeout(cmd, kUntrustedFsckSleepTime, sFsckUntrustedContext);
     if (rc == 0) {
         LOG(INFO) << "Check OK";
         return 0;
diff --git a/fs/Vfat.cpp b/fs/Vfat.cpp
index 4f1e982..f3f04d8 100644
--- a/fs/Vfat.cpp
+++ b/fs/Vfat.cpp
@@ -68,10 +68,9 @@
         cmd.push_back(source);
 
         // Fat devices are currently always untrusted
-        rc = ForkExecvp(cmd, nullptr, sFsckUntrustedContext);
-
+        rc = ForkExecvpTimeout(cmd, kUntrustedFsckSleepTime, sFsckUntrustedContext);
         if (rc < 0) {
-            LOG(ERROR) << "Filesystem check failed due to logwrap error";
+            LOG(ERROR) << "Filesystem check failed due to fork error";
             errno = EIO;
             return -1;
         }
@@ -81,6 +80,10 @@
                 LOG(INFO) << "Filesystem check completed OK";
                 return 0;
 
+            case 1:
+                LOG(INFO) << "Failed to check filesystem";
+                return -1;
+
             case 2:
                 LOG(ERROR) << "Filesystem check failed (not a FAT filesystem)";
                 errno = ENODATA;
@@ -100,6 +103,11 @@
                 errno = ENODATA;
                 return -1;
 
+            case ETIMEDOUT:
+                LOG(ERROR) << "Filesystem check timed out";
+                errno = ETIMEDOUT;
+                return -1;
+
             default:
                 LOG(ERROR) << "Filesystem check failed (unknown exit code " << rc << ")";
                 errno = EIO;
diff --git a/main.cpp b/main.cpp
index 1f85fb5..978db66 100644
--- a/main.cpp
+++ b/main.cpp
@@ -16,6 +16,7 @@
 
 #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
 
+#include "MetadataCrypt.h"
 #include "NetlinkManager.h"
 #include "VoldNativeService.h"
 #include "VoldUtil.h"
@@ -51,8 +52,11 @@
 static int process_config(VolumeManager* vm, VoldConfigs* configs);
 static void coldboot(const char* path);
 static void parse_args(int argc, char** argv);
+static void VoldLogger(android::base::LogId log_buffer_id, android::base::LogSeverity severity,
+                       const char* tag, const char* file, unsigned int line, const char* message);
 
 struct selabel_handle* sehandle;
+android::base::LogdLogger logd_logger(android::base::SYSTEM);
 
 using android::base::StringPrintf;
 using android::fs_mgr::ReadDefaultFstab;
@@ -60,7 +64,7 @@
 int main(int argc, char** argv) {
     atrace_set_tracing_enabled(false);
     setenv("ANDROID_LOG_TAGS", "*:d", 1);  // Do not submit with verbose logs enabled
-    android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
+    android::base::InitLogging(argv, &VoldLogger);
 
     LOG(INFO) << "Vold 3.0 (the awakening) firing up";
 
@@ -247,6 +251,11 @@
             PLOG(FATAL) << "could not find logical partition " << entry.blk_device;
         }
 
+        if (entry.mount_point == "/data" && !entry.metadata_encryption.empty()) {
+            // Pre-populate userdata dm-devices since the uevents are asynchronous (b/198405417).
+            android::vold::defaultkey_precreate_dm_device();
+        }
+
         if (entry.fs_mgr_flags.vold_managed) {
             if (entry.fs_mgr_flags.nonremovable) {
                 LOG(WARNING) << "nonremovable no longer supported; ignoring volume";
@@ -272,3 +281,23 @@
     }
     return 0;
 }
+
+static void VoldLogger(android::base::LogId log_buffer_id, android::base::LogSeverity severity,
+                       const char* tag, const char* file, unsigned int line, const char* message) {
+    logd_logger(log_buffer_id, severity, tag, file, line, message);
+
+    if (severity >= android::base::ERROR) {
+        static bool is_data_mounted = false;
+
+        // When /data fails to mount, we don't have adb to get logcat. So until /data is
+        // mounted we log errors to the kernel. This allows us to get failures via serial logs
+        // and via last dmesg/"fastboot oem dmesg" on devices that support it.
+        //
+        // As a very quick-and-dirty test for /data, we check whether /data/misc/vold exists.
+        if (is_data_mounted || access("/data/misc/vold", F_OK) == 0) {
+            is_data_mounted = true;
+            return;
+        }
+        android::base::KernelLogger(log_buffer_id, severity, tag, file, line, message);
+    }
+}
diff --git a/model/Disk.h b/model/Disk.h
index 16476dc..8c75f59 100644
--- a/model/Disk.h
+++ b/model/Disk.h
@@ -70,6 +70,8 @@
     const std::string& getLabel() const { return mLabel; }
     int getFlags() const { return mFlags; }
 
+    bool isStub() const { return (mFlags & kStubInvisible) || (mFlags & kStubVisible); }
+
     std::shared_ptr<VolumeBase> findVolume(const std::string& id);
 
     void listVolumes(VolumeBase::Type type, std::list<std::string>& list) const;
@@ -123,8 +125,6 @@
 
     int getMaxMinors();
 
-    bool isStub() { return (mFlags & kStubInvisible) || (mFlags & kStubVisible); }
-
     DISALLOW_COPY_AND_ASSIGN(Disk);
 };
 
diff --git a/model/EmulatedVolume.cpp b/model/EmulatedVolume.cpp
index 6f21ff8..7c8a4e0 100644
--- a/model/EmulatedVolume.cpp
+++ b/model/EmulatedVolume.cpp
@@ -49,6 +49,7 @@
     mRawPath = rawPath;
     mLabel = "emulated";
     mFuseMounted = false;
+    mFuseBpfEnabled = base::GetBoolProperty(kFuseBpfEnabled, false);
     mUseSdcardFs = IsSdcardfsUsed();
     mAppDataIsolationEnabled = base::GetBoolProperty(kVoldAppDataIsolationEnabled, false);
 }
@@ -60,6 +61,7 @@
     mRawPath = rawPath;
     mLabel = fsUuid;
     mFuseMounted = false;
+    mFuseBpfEnabled = base::GetBoolProperty(kFuseBpfEnabled, false);
     mUseSdcardFs = IsSdcardfsUsed();
     mAppDataIsolationEnabled = base::GetBoolProperty(kVoldAppDataIsolationEnabled, false);
 }
@@ -246,7 +248,7 @@
 
 status_t EmulatedVolume::doMount() {
     std::string label = getLabel();
-    bool isVisible = getMountFlags() & MountFlags::kVisible;
+    bool isVisible = isVisibleForWrite();
 
     mSdcardFsDefault = StringPrintf("/mnt/runtime/default/%s", label.c_str());
     mSdcardFsRead = StringPrintf("/mnt/runtime/read/%s", label.c_str());
@@ -359,10 +361,12 @@
             }
         }
 
-        // Only do the bind-mounts when we know for sure the FUSE daemon can resolve the path.
-        res = mountFuseBindMounts();
-        if (res != OK) {
-            return res;
+        if (!mFuseBpfEnabled) {
+            // Only do the bind-mounts when we know for sure the FUSE daemon can resolve the path.
+            res = mountFuseBindMounts();
+            if (res != OK) {
+                return res;
+            }
         }
 
         ConfigureReadAheadForFuse(GetFuseMountPathForUser(user_id, label), 256u);
@@ -416,9 +420,11 @@
     if (mFuseMounted) {
         std::string label = getLabel();
 
-        // Ignoring unmount return status because we do want to try to unmount
-        // the rest cleanly.
-        unmountFuseBindMounts();
+        if (!mFuseBpfEnabled) {
+            // Ignoring unmount return status because we do want to try to
+            // unmount the rest cleanly.
+            unmountFuseBindMounts();
+        }
 
         if (UnmountUserFuse(userId, getInternalPath(), label) != OK) {
             PLOG(INFO) << "UnmountUserFuse failed on emulated fuse volume";
diff --git a/model/EmulatedVolume.h b/model/EmulatedVolume.h
index 1d2385d..0f39fbd 100644
--- a/model/EmulatedVolume.h
+++ b/model/EmulatedVolume.h
@@ -64,6 +64,9 @@
     /* Whether we mounted FUSE for this volume */
     bool mFuseMounted;
 
+    /* Whether the FUSE BPF feature is enabled */
+    bool mFuseBpfEnabled;
+
     /* Whether to use sdcardfs for this volume */
     bool mUseSdcardFs;
 
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index 12e31ff..bf54c95 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -97,7 +97,7 @@
 }
 
 status_t PublicVolume::doMount() {
-    bool isVisible = getMountFlags() & MountFlags::kVisible;
+    bool isVisible = isVisibleForWrite();
     readMetadata();
 
     if (mFsType == "vfat" && vfat::IsSupported()) {
diff --git a/model/VolumeBase.h b/model/VolumeBase.h
index 689750d..f29df65 100644
--- a/model/VolumeBase.h
+++ b/model/VolumeBase.h
@@ -63,8 +63,14 @@
     enum MountFlags {
         /* Flag that volume is primary external storage */
         kPrimary = 1 << 0,
-        /* Flag that volume is visible to normal apps */
-        kVisible = 1 << 1,
+        /*
+         * Flags indicating that volume is visible to normal apps.
+         * kVisibleForRead and kVisibleForWrite correspond to
+         * VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_READ and
+         * VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE, respectively.
+         */
+        kVisibleForRead = 1 << 1,
+        kVisibleForWrite = 1 << 2,
     };
 
     enum class State {
@@ -103,6 +109,9 @@
     std::shared_ptr<VolumeBase> findVolume(const std::string& id);
 
     bool isEmulated() { return mType == Type::kEmulated; }
+    bool isVisibleForRead() const { return (mMountFlags & MountFlags::kVisibleForRead) != 0; }
+    bool isVisibleForWrite() const { return (mMountFlags & MountFlags::kVisibleForWrite) != 0; }
+    bool isVisible() const { return isVisibleForRead() || isVisibleForWrite(); }
 
     status_t create();
     status_t destroy();
diff --git a/tests/Android.bp b/tests/Android.bp
index cad96fd..3c4f07b 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -12,7 +12,6 @@
     srcs: [
         "Utils_test.cpp",
         "VoldNativeServiceValidation_test.cpp",
-        "cryptfs_test.cpp",
     ],
     static_libs: ["libvold"],
     shared_libs: ["libbinder"]
diff --git a/tests/cryptfs_test.cpp b/tests/cryptfs_test.cpp
deleted file mode 100644
index 2093768..0000000
--- a/tests/cryptfs_test.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include "../cryptfs.h"
-
-namespace android {
-
-class CryptfsTest : public testing::Test {
-  protected:
-    virtual void SetUp() {}
-
-    virtual void TearDown() {}
-};
-
-TEST_F(CryptfsTest, MatchMultiEntryTest) {
-    ASSERT_NE(0, match_multi_entry("foo", "foo", 0));
-    ASSERT_NE(0, match_multi_entry("foo_0", "foo", 0));
-    ASSERT_NE(0, match_multi_entry("foo_1", "foo", 0));
-    ASSERT_NE(0, match_multi_entry("foo_2", "foo", 0));
-
-    ASSERT_EQ(0, match_multi_entry("foo", "foo", 1));
-    ASSERT_EQ(0, match_multi_entry("foo_0", "foo", 1));
-    ASSERT_NE(0, match_multi_entry("foo_1", "foo", 1));
-    ASSERT_NE(0, match_multi_entry("foo_2", "foo", 1));
-
-    ASSERT_EQ(0, match_multi_entry("foo", "foo", 2));
-    ASSERT_EQ(0, match_multi_entry("foo_0", "foo", 2));
-    ASSERT_EQ(0, match_multi_entry("foo_1", "foo", 2));
-    ASSERT_NE(0, match_multi_entry("foo_2", "foo", 2));
-
-    ASSERT_EQ(0, match_multi_entry("food", "foo", 0));
-    ASSERT_EQ(0, match_multi_entry("foo", "food", 0));
-    ASSERT_EQ(0, match_multi_entry("foo", "bar", 0));
-    ASSERT_EQ(0, match_multi_entry("foo_2", "bar", 0));
-}
-
-}  // namespace android
diff --git a/vdc.rc b/vdc.rc
deleted file mode 100644
index f2a8076..0000000
--- a/vdc.rc
+++ /dev/null
@@ -1,12 +0,0 @@
-# One shot invocation to deal with encrypted volume.
-on defaultcrypto
-    exec - root -- /system/bin/vdc --wait cryptfs mountdefaultencrypted
-    # vold will set vold.decrypt to trigger_restart_framework (default
-    # encryption) or trigger_restart_min_framework (other encryption)
-
-# One shot invocation to encrypt unencrypted volumes
-on encrypt
-    start surfaceflinger
-    exec - root -- /system/bin/vdc --wait cryptfs enablecrypto
-    # vold will set vold.decrypt to trigger_restart_framework (default
-    # encryption)
diff --git a/vold.rc b/vold.rc
index a21d1d9..9474a1e 100644
--- a/vold.rc
+++ b/vold.rc
@@ -3,7 +3,7 @@
         --fsck_context=u:r:fsck:s0 --fsck_untrusted_context=u:r:fsck_untrusted:s0
     class core
     ioprio be 2
-    writepid /dev/cpuset/foreground/tasks
+    task_profiles ProcessCapacityHigh
     shutdown critical
     group root reserved_disk
     reboot_on_failure reboot,vold-failed
diff --git a/vold_prepare_subdirs.cpp b/vold_prepare_subdirs.cpp
index e2afb81..0d58e4d 100644
--- a/vold_prepare_subdirs.cpp
+++ b/vold_prepare_subdirs.cpp
@@ -208,10 +208,23 @@
             if (!prepare_dir(sehandle, 0700, 0, 0, misc_ce_path + "/vold")) return false;
             if (!prepare_dir(sehandle, 0700, 0, 0, misc_ce_path + "/storaged")) return false;
             if (!prepare_dir(sehandle, 0700, 0, 0, misc_ce_path + "/rollback")) return false;
-
             // TODO: Return false if this returns false once sure this should succeed.
             prepare_dir(sehandle, 0700, 0, 0, misc_ce_path + "/apexrollback");
             prepare_apex_subdirs(sehandle, misc_ce_path);
+            // Give gmscore (who runs in cache group) access to the checkin directory. Also provide
+            // the user id to set the correct selinux mls_level.
+            if (!prepare_dir_for_user(sehandle, 0770, AID_SYSTEM, AID_CACHE,
+                                      misc_ce_path + "/checkin", user_id)) {
+                // TODO(b/203742483) the checkin directory was created with the wrong permission &
+                // context. Delete the directory to get these devices out of the bad state. Revert
+                // the change once the droidfood population is on newer build.
+                LOG(INFO) << "Failed to prepare the checkin directory, deleting for recreation";
+                android::vold::DeleteDirContentsAndDir(misc_ce_path + "/checkin");
+                if (!prepare_dir_for_user(sehandle, 0770, AID_SYSTEM, AID_CACHE,
+                                          misc_ce_path + "/checkin", user_id)) {
+                    return false;
+                }
+            }
 
             auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
             if (!prepare_dir(sehandle, 0700, AID_SYSTEM, AID_SYSTEM, system_ce_path + "/backup")) {
diff --git a/wait_for_keymaster.cpp b/wait_for_keymaster.cpp
deleted file mode 100644
index bf26518..0000000
--- a/wait_for_keymaster.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android-base/logging.h>
-
-#include "Keymaster.h"
-
-int main(int argc, char** argv) {
-    setenv("ANDROID_LOG_TAGS", "*:v", 1);
-    if (getppid() == 1) {
-        // If init is calling us then it's during boot and we should log to kmsg
-        android::base::InitLogging(argv, &android::base::KernelLogger);
-    } else {
-        android::base::InitLogging(argv, &android::base::StderrLogger);
-    }
-    LOG(INFO) << "Waiting for Keymaster device";
-    android::vold::Keymaster keymaster;
-    LOG(INFO) << "Keymaster device ready";
-    return 0;
-}
diff --git a/wait_for_keymaster.rc b/wait_for_keymaster.rc
deleted file mode 100644
index 9e83a93..0000000
--- a/wait_for_keymaster.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service wait_for_keymaster /system/bin/wait_for_keymaster
-    user root
-    group root system
-    priority -20
-    ioprio rt 0
