diff --git a/Android.bp b/Android.bp
index 35f74bf..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: [
@@ -130,7 +130,6 @@
         "NetlinkHandler.cpp",
         "NetlinkManager.cpp",
         "Process.cpp",
-        "ScryptParameters.cpp",
         "Utils.cpp",
         "VoldNativeService.cpp",
         "VoldNativeServiceValidation.cpp",
@@ -166,7 +165,6 @@
     shared_libs: [
         "android.hardware.health.storage@1.0",
         "android.hardware.health.storage-V1-ndk",
-        "android.system.keystore2-V1-ndk",
         "android.security.maintenance-ndk",
         "libbinder_ndk",
         "libkeymint_support",
@@ -182,6 +180,7 @@
     defaults: [
         "vold_default_flags",
         "vold_default_libs",
+        "keystore2_use_latest_aidl_ndk_shared",
     ],
 
     srcs: ["main.cpp"],
@@ -193,12 +192,12 @@
     required: [
         "mke2fs",
         "vold_prepare_subdirs",
+        "fuse_media.o",
     ],
 
     shared_libs: [
         "android.hardware.health.storage@1.0",
         "android.hardware.health.storage-V1-ndk",
-        "android.system.keystore2-V1-ndk",
         "android.security.maintenance-ndk",
         "libbinder_ndk",
         "libkeymint_support",
@@ -235,7 +234,6 @@
     static_libs: [
         "libvold_binder",
     ],
-    init_rc: ["vdc.rc"],
 }
 
 cc_binary {
diff --git a/FsCrypt.cpp b/FsCrypt.cpp
index 017ffec..be68222 100644
--- a/FsCrypt.cpp
+++ b/FsCrypt.cpp
@@ -208,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)) {
@@ -224,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.
@@ -241,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;
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 ebaefa3..3ede67e 100644
--- a/KeyStorage.cpp
+++ b/KeyStorage.cpp
@@ -18,7 +18,6 @@
 
 #include "Checkpoint.h"
 #include "Keystore.h"
-#include "ScryptParameters.h"
 #include "Utils.h"
 
 #include <algorithm>
@@ -45,11 +44,6 @@
 
 #include <cutils/properties.h>
 
-extern "C" {
-
-#include "crypto_scrypt.h"
-}
-
 namespace android {
 namespace vold {
 
@@ -598,9 +592,15 @@
         if (!generateKeyStorageKey(keystore, appId, &ksKey)) return false;
         if (!writeStringToFile(ksKey, dir + "/" + kFn_keymaster_key_blob)) return false;
         km::AuthorizationSet keyParams = beginParams(appId);
-        if (!encryptWithKeystoreKey(keystore, dir, keyParams, key, &encryptedKey)) return false;
+        if (!encryptWithKeystoreKey(keystore, dir, keyParams, key, &encryptedKey)) {
+            LOG(ERROR) << "encryptWithKeystoreKey failed";
+            return false;
+        }
     } else {
-        if (!encryptWithoutKeystore(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;
@@ -645,9 +645,15 @@
         Keystore keystore;
         if (!keystore) return false;
         km::AuthorizationSet keyParams = beginParams(appId);
-        if (!decryptWithKeystoreKey(keystore, dir, keyParams, encryptedMessage, key)) return false;
+        if (!decryptWithKeystoreKey(keystore, dir, keyParams, encryptedMessage, key)) {
+            LOG(ERROR) << "decryptWithKeystoreKey failed";
+            return false;
+        }
     } else {
-        if (!decryptWithoutKeystore(appId, encryptedMessage, key)) return false;
+        if (!decryptWithoutKeystore(appId, encryptedMessage, key)) {
+            LOG(ERROR) << "decryptWithoutKeystore failed";
+            return false;
+        }
     }
     return true;
 }
diff --git a/KeyUtil.cpp b/KeyUtil.cpp
index 2f9c876..25d5af3 100644
--- a/KeyUtil.cpp
+++ b/KeyUtil.cpp
@@ -54,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/MetadataCrypt.cpp b/MetadataCrypt.cpp
index 277a908..6550be4 100644
--- a/MetadataCrypt.cpp
+++ b/MetadataCrypt.cpp
@@ -52,6 +52,7 @@
 using android::fscrypt::GetFirstApiLevel;
 using android::vold::KeyBuffer;
 using namespace android::dm;
+using namespace std::chrono_literals;
 
 // Parsed from metadata options
 struct CryptoOptions {
@@ -81,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.
@@ -113,7 +125,9 @@
     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) {
@@ -171,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;
@@ -220,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;
     }
 
@@ -257,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) {
@@ -276,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/TEST_MAPPING b/TEST_MAPPING
index 4f62642..49b2d60 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,9 +1,15 @@
 {
   "presubmit": [
     {
+      "name": "CtsScopedStorageCoreHostTest"
+    },
+    {
       "name": "CtsScopedStorageHostTest"
     },
     {
+      "name": "CtsScopedStorageDeviceOnlyTest"
+    },
+    {
       "name": "AdoptableHostTest"
     }
   ]
diff --git a/Utils.cpp b/Utils.cpp
index 97a71a7..e077ead 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -1494,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 3cca60b..b5bb4c2 100644
--- a/Utils.h
+++ b/Utils.h
@@ -36,6 +36,7 @@
 
 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);
 
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index da57328..1c94220 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>
 
@@ -38,15 +37,12 @@
 #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 {
@@ -55,6 +51,7 @@
 namespace {
 
 constexpr const char* kDump = "android.permission.DUMP";
+constexpr auto kIncFsReadNoTimeoutMs = 100;
 
 static binder::Status error(const std::string& msg) {
     PLOG(ERROR) << msg;
@@ -132,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;
 }
 
@@ -474,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();
 }
 
@@ -491,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;
@@ -523,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();
 }
 
@@ -657,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();
 }
 
@@ -676,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();
 }
 
@@ -939,42 +945,10 @@
     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();
     Keystore::earlyBootEnded();
     return Ok();
@@ -989,6 +963,7 @@
 
 binder::Status VoldNativeService::mountIncFs(
         const std::string& backingPath, const std::string& targetDir, int32_t flags,
+        const std::string& sysfsName,
         ::android::os::incremental::IncrementalFileSystemControlParcel* _aidl_return) {
     ENFORCE_SYSTEM_OR_ROOT;
     CHECK_ARGUMENT_PATH(backingPath);
@@ -996,9 +971,11 @@
 
     auto control = incfs::mount(backingPath, targetDir,
                                 {.flags = IncFsMountFlags(flags),
+                                 // Mount with read timeouts.
                                  .defaultReadTimeoutMs = INCFS_DEFAULT_READ_TIMEOUT_MS,
                                  // Mount with read logs disabled.
-                                 .readLogBufferPages = 0});
+                                 .readLogBufferPages = 0,
+                                 .sysfsName = sysfsName.c_str()});
     if (!control) {
         return translate(-errno);
     }
@@ -1007,6 +984,9 @@
     _aidl_return->cmd.reset(unique_fd(fds[CMD].release()));
     _aidl_return->pendingReads.reset(unique_fd(fds[PENDING_READS].release()));
     _aidl_return->log.reset(unique_fd(fds[LOGS].release()));
+    if (fds[BLOCKS_WRITTEN].ok()) {
+        _aidl_return->blocksWritten.emplace(unique_fd(fds[BLOCKS_WRITTEN].release()));
+    }
     return Ok();
 }
 
@@ -1019,11 +999,12 @@
 
 binder::Status VoldNativeService::setIncFsMountOptions(
         const ::android::os::incremental::IncrementalFileSystemControlParcel& control,
-        bool enableReadLogs) {
+        bool enableReadLogs, bool enableReadTimeouts, const std::string& sysfsName) {
     ENFORCE_SYSTEM_OR_ROOT;
 
     auto incfsControl =
-            incfs::createControl(control.cmd.get(), control.pendingReads.get(), control.log.get());
+            incfs::createControl(control.cmd.get(), control.pendingReads.get(), control.log.get(),
+                                 control.blocksWritten ? control.blocksWritten->get() : -1);
     auto cleanupFunc = [](auto incfsControl) {
         for (auto& fd : incfsControl->releaseFds()) {
             (void)fd.release();
@@ -1031,14 +1012,30 @@
     };
     auto cleanup =
             std::unique_ptr<incfs::Control, decltype(cleanupFunc)>(&incfsControl, cleanupFunc);
-    if (auto error = incfs::setOptions(
-                incfsControl,
-                {.defaultReadTimeoutMs = INCFS_DEFAULT_READ_TIMEOUT_MS,
-                 .readLogBufferPages = enableReadLogs ? INCFS_DEFAULT_PAGE_READ_BUFFER_PAGES : 0});
-        error < 0) {
-        return binder::Status::fromServiceSpecificError(error);
-    }
 
+    constexpr auto minReadLogBufferPages = INCFS_DEFAULT_PAGE_READ_BUFFER_PAGES;
+    constexpr auto maxReadLogBufferPages = 8 * INCFS_DEFAULT_PAGE_READ_BUFFER_PAGES;
+    auto options = incfs::MountOptions{
+            .defaultReadTimeoutMs =
+                    enableReadTimeouts ? INCFS_DEFAULT_READ_TIMEOUT_MS : kIncFsReadNoTimeoutMs,
+            .readLogBufferPages = enableReadLogs ? maxReadLogBufferPages : 0,
+            .sysfsName = sysfsName.c_str()};
+
+    for (;;) {
+        const auto error = incfs::setOptions(incfsControl, options);
+        if (!error) {
+            return Ok();
+        }
+        if (!enableReadLogs || error != -ENOMEM) {
+            return binder::Status::fromServiceSpecificError(error);
+        }
+        // In case of memory allocation error retry with a smaller buffer.
+        options.readLogBufferPages /= 2;
+        if (options.readLogBufferPages < minReadLogBufferPages) {
+            return binder::Status::fromServiceSpecificError(error);
+        }
+    }
+    // unreachable, but makes the compiler happy
     return Ok();
 }
 
diff --git a/VoldNativeService.h b/VoldNativeService.h
index 33d0f3a..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);
@@ -162,11 +168,12 @@
     binder::Status incFsEnabled(bool* _aidl_return) override;
     binder::Status mountIncFs(
             const std::string& backingPath, const std::string& targetDir, int32_t flags,
+            const std::string& sysfsName,
             ::android::os::incremental::IncrementalFileSystemControlParcel* _aidl_return) override;
     binder::Status unmountIncFs(const std::string& dir) override;
     binder::Status setIncFsMountOptions(
             const ::android::os::incremental::IncrementalFileSystemControlParcel& control,
-            bool enableReadLogs) override;
+            bool enableReadLogs, bool enableReadTimeouts, const std::string& sysfsName) override;
     binder::Status bindMount(const std::string& sourceDir, const std::string& targetDir) override;
 
     binder::Status destroyDsuMetadataKey(const std::string& dsuSlot) override;
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index d299593..9311321 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -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 62685e5..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);
@@ -140,9 +145,9 @@
     FileDescriptor openAppFuseFile(int uid, int mountId, int fileId, int flags);
 
     boolean incFsEnabled();
-    IncrementalFileSystemControlParcel mountIncFs(@utf8InCpp String backingPath, @utf8InCpp String targetDir, int flags);
+    IncrementalFileSystemControlParcel mountIncFs(@utf8InCpp String backingPath, @utf8InCpp String targetDir, int flags, @utf8InCpp String sysfsName);
     void unmountIncFs(@utf8InCpp String dir);
-    void setIncFsMountOptions(in IncrementalFileSystemControlParcel control, boolean enableReadLogs);
+    void setIncFsMountOptions(in IncrementalFileSystemControlParcel control, boolean enableReadLogs, boolean enableReadTimeouts, @utf8InCpp String sysfsName);
     void bindMount(@utf8InCpp String sourceDir, @utf8InCpp String targetDir);
 
     void destroyDsuMetadataKey(@utf8InCpp String dsuSlot);
@@ -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 f9d4ed4..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 "Keystore.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;
-    }
-    Keystore 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;
-    }
-
-    Keystore 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;
-    KeystoreOperation 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,806 +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) {
-        SLOGW("unmounting sub-directory mount %s\n", mount_point.c_str());
-        if (umount(mount_point.c_str()) != 0) {
-            SLOGE("unmounting %s failed: %s\n", mount_point.c_str(), strerror(errno));
-        }
-    }
-}
-
-static int wait_and_unmount(const char* mountpoint) {
-    int i, err, rc;
-
-#define WAIT_UNMOUNT_COUNT 20
-
-    /*  Now umount the tmpfs filesystem */
-    for (i = 0; i < WAIT_UNMOUNT_COUNT; i++) {
-        // Subdirectory mount will cause a failure of umount.
-        ensure_subdirectory_unmounted(mountpoint);
-
-        SLOGD("unmounting mount %s\n", mountpoint);
-        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.
-             */
-            SLOGD("%s is not a mountpoint, nothing to do\n", mountpoint);
-            break;
-        }
-
-        err = errno;
-        SLOGW("unmounting mount %s failed: %s\n", mountpoint, strerror(err));
-
-        // 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 {
-        SLOGE("too many retries -- giving up unmounting %s\n", mountpoint);
-        android::vold::KillProcessesWithOpenFiles(mountpoint, 0);
-        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,
@@ -1973,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/Ext4.cpp b/fs/Ext4.cpp
index 6bc7ad2..7a5f5da 100644
--- a/fs/Ext4.cpp
+++ b/fs/Ext4.cpp
@@ -198,7 +198,7 @@
         cmd.push_back("-E");
         std::string extopts = "";
         if (needs_casefold) extopts += "encoding=utf8,";
-        if (needs_projid) extopts += "quotatype=prjquota,";
+        if (needs_projid) extopts += "quotatype=usrquota:grpquota:prjquota,";
         cmd.push_back(extopts);
     }
 
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 0252c2f..9474a1e 100644
--- a/vold.rc
+++ b/vold.rc
@@ -6,3 +6,4 @@
     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")) {
