Merge "Enable ProjectID for the file systems by default."
diff --git a/Android.bp b/Android.bp
index 1550264..c113ed0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -9,9 +9,7 @@
         "-Wall",
         "-Werror",
         "-Wextra",
-        "-Wno-missing-field-initializers",
         "-Wno-unused-parameter",
-        "-Wno-unused-variable",
     ],
 
     clang: true,
@@ -115,7 +113,6 @@
         "Benchmark.cpp",
         "Checkpoint.cpp",
         "CryptoType.cpp",
-        "Devmapper.cpp",
         "EncryptInplace.cpp",
         "FileDeviceUtils.cpp",
         "FsCrypt.cpp",
diff --git a/Devmapper.cpp b/Devmapper.cpp
deleted file mode 100644
index 00fb4b3..0000000
--- a/Devmapper.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-#define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <linux/kdev_t.h>
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <libdm/dm.h>
-#include <utils/Trace.h>
-
-#include "Devmapper.h"
-
-using android::base::StringPrintf;
-using namespace android::dm;
-
-static const char* kVoldPrefix = "vold:";
-
-int Devmapper::create(const char* name_raw, const char* loopFile, const char* key,
-                      unsigned long numSectors, char* ubuffer, size_t len) {
-    auto& dm = DeviceMapper::Instance();
-    auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
-
-    DmTable table;
-    table.Emplace<DmTargetCrypt>(0, numSectors, "twofish", key, 0, loopFile, 0);
-
-    if (!dm.CreateDevice(name_string, table)) {
-        LOG(ERROR) << "Failed to create device-mapper device " << name_string;
-        return -1;
-    }
-
-    std::string path;
-    if (!dm.GetDmDevicePathByName(name_string, &path)) {
-        LOG(ERROR) << "Failed to get device-mapper device path for " << name_string;
-        return -1;
-    }
-    snprintf(ubuffer, len, "%s", path.c_str());
-    return 0;
-}
-
-int Devmapper::destroy(const char* name_raw) {
-    auto& dm = DeviceMapper::Instance();
-
-    auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
-    if (!dm.DeleteDevice(name_string)) {
-        if (errno != ENXIO) {
-            PLOG(ERROR) << "Failed DM_DEV_REMOVE";
-        }
-        return -1;
-    }
-    return 0;
-}
-
-int Devmapper::destroyAll() {
-    ATRACE_NAME("Devmapper::destroyAll");
-
-    auto& dm = DeviceMapper::Instance();
-    std::vector<DeviceMapper::DmBlockDevice> devices;
-    if (!dm.GetAvailableDevices(&devices)) {
-        LOG(ERROR) << "Failed to get dm devices";
-        return -1;
-    }
-
-    for (const auto& device : devices) {
-        if (android::base::StartsWith(device.name(), kVoldPrefix)) {
-            LOG(DEBUG) << "Tearing down stale dm device named " << device.name();
-            if (!dm.DeleteDevice(device.name())) {
-                if (errno != ENXIO) {
-                    PLOG(WARNING) << "Failed to destroy dm device named " << device.name();
-                }
-            }
-        }
-    }
-    return 0;
-}
diff --git a/Devmapper.h b/Devmapper.h
deleted file mode 100644
index 9d4896e..0000000
--- a/Devmapper.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2008 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 _DEVMAPPER_H
-#define _DEVMAPPER_H
-
-#include <linux/dm-ioctl.h>
-#include <unistd.h>
-
-class Devmapper {
-  public:
-    static int create(const char* name, const char* loopFile, const char* key,
-                      unsigned long numSectors, char* buffer, size_t len);
-    static int destroy(const char* name);
-    static int destroyAll();
-};
-
-#endif
diff --git a/EncryptInplace.cpp b/EncryptInplace.cpp
index 057b3ef..190bb83 100644
--- a/EncryptInplace.cpp
+++ b/EncryptInplace.cpp
@@ -20,13 +20,11 @@
 #include <ext4_utils/ext4_utils.h>
 #include <f2fs_sparseblock.h>
 #include <fcntl.h>
-#include <time.h>
 
 #include <algorithm>
 #include <vector>
 
 #include <android-base/logging.h>
-#include <android-base/properties.h>
 #include <android-base/unique_fd.h>
 
 enum EncryptInPlaceError {
@@ -43,7 +41,7 @@
 class InPlaceEncrypter {
   public:
     bool EncryptInPlace(const std::string& crypto_blkdev, const std::string& real_blkdev,
-                        uint64_t nr_sec, bool set_progress_properties);
+                        uint64_t nr_sec);
     bool ProcessUsedBlock(uint64_t block_num);
 
   private:
@@ -75,19 +73,14 @@
     std::string real_blkdev_;
     std::string crypto_blkdev_;
     uint64_t nr_sec_;
-    bool set_progress_properties_;
 
     android::base::unique_fd realfd_;
     android::base::unique_fd cryptofd_;
 
-    time_t time_started_;
-    int remaining_time_;
-
     std::string fs_type_;
     uint64_t blocks_done_;
     uint64_t blocks_to_encrypt_;
     unsigned int block_size_;
-    unsigned int cur_pct_;
 
     std::vector<uint8_t> io_buffer_;
     uint64_t first_pending_block_;
@@ -108,7 +101,6 @@
     blocks_done_ = 0;
     blocks_to_encrypt_ = blocks_to_encrypt;
     block_size_ = block_size;
-    cur_pct_ = 0;
 
     // Allocate the I/O buffer.  kIOBufferSize should always be a multiple of
     // the filesystem block size, but round it up just in case.
@@ -136,46 +128,6 @@
 
     if (blocks_done_ >= blocks_next_msg)
         LOG(DEBUG) << "Encrypted " << blocks_next_msg << " of " << blocks_to_encrypt_ << " blocks";
-
-    if (!set_progress_properties_) return;
-
-    uint64_t new_pct;
-    if (done) {
-        new_pct = 100;
-    } else {
-        new_pct = (blocks_done_ * 100) / std::max<uint64_t>(blocks_to_encrypt_, 1);
-        new_pct = std::min<uint64_t>(new_pct, 99);
-    }
-    if (new_pct > cur_pct_) {
-        cur_pct_ = new_pct;
-        android::base::SetProperty("vold.encrypt_progress", std::to_string(new_pct));
-    }
-
-    if (cur_pct_ >= 5) {
-        struct timespec time_now;
-        if (clock_gettime(CLOCK_MONOTONIC, &time_now)) {
-            PLOG(WARNING) << "Error getting time while updating encryption progress";
-        } else {
-            double elapsed_time = difftime(time_now.tv_sec, time_started_);
-
-            uint64_t remaining_blocks = 0;
-            if (blocks_done_ < blocks_to_encrypt_)
-                remaining_blocks = blocks_to_encrypt_ - blocks_done_;
-
-            int remaining_time = 0;
-            if (blocks_done_ != 0)
-                remaining_time = (int)(elapsed_time * remaining_blocks / blocks_done_);
-
-            // Change time only if not yet set, lower, or a lot higher for
-            // best user experience
-            if (remaining_time_ == -1 || remaining_time < remaining_time_ ||
-                remaining_time > remaining_time_ + 60) {
-                remaining_time_ = remaining_time;
-                android::base::SetProperty("vold.encrypt_time_remaining",
-                                           std::to_string(remaining_time));
-            }
-        }
-    }
 }
 
 bool InPlaceEncrypter::EncryptPendingData() {
@@ -313,14 +265,10 @@
 }
 
 bool InPlaceEncrypter::EncryptInPlace(const std::string& crypto_blkdev,
-                                      const std::string& real_blkdev, uint64_t nr_sec,
-                                      bool set_progress_properties) {
-    struct timespec time_started = {0};
-
+                                      const std::string& real_blkdev, uint64_t nr_sec) {
     real_blkdev_ = real_blkdev;
     crypto_blkdev_ = crypto_blkdev;
     nr_sec_ = nr_sec;
-    set_progress_properties_ = set_progress_properties;
 
     realfd_.reset(open64(real_blkdev.c_str(), O_RDONLY | O_CLOEXEC));
     if (realfd_ < 0) {
@@ -334,13 +282,6 @@
         return false;
     }
 
-    if (clock_gettime(CLOCK_MONOTONIC, &time_started)) {
-        PLOG(WARNING) << "Error getting time at start of in-place encryption";
-        // Note - continue anyway - we'll run with 0
-    }
-    time_started_ = time_started.tv_sec;
-    remaining_time_ = -1;
-
     bool success = DoEncryptInPlace();
 
     if (success) success &= EncryptPendingData();
@@ -359,8 +300,11 @@
                      << ") was incorrect; we actually encrypted " << blocks_done_
                      << " blocks.  Encryption progress was inaccurate";
     }
-    // Make sure vold.encrypt_progress gets set to 100.
+    // Ensure that the final progress message is printed, so the series of log
+    // messages ends with e.g. "Encrypted 50327 of 50327 blocks" rather than
+    // "Encrypted 50000 of 50327 blocks".
     UpdateProgress(0, true);
+
     LOG(INFO) << "Successfully encrypted " << DescribeFilesystem();
     return true;
 }
@@ -371,10 +315,10 @@
 // sectors; however, if a filesystem is detected, then its size will be used
 // instead, and only the in-use blocks of the filesystem will be encrypted.
 bool encrypt_inplace(const std::string& crypto_blkdev, const std::string& real_blkdev,
-                     uint64_t nr_sec, bool set_progress_properties) {
+                     uint64_t nr_sec) {
     LOG(DEBUG) << "encrypt_inplace(" << crypto_blkdev << ", " << real_blkdev << ", " << nr_sec
-               << ", " << (set_progress_properties ? "true" : "false") << ")";
+               << ")";
 
     InPlaceEncrypter encrypter;
-    return encrypter.EncryptInPlace(crypto_blkdev, real_blkdev, nr_sec, set_progress_properties);
+    return encrypter.EncryptInPlace(crypto_blkdev, real_blkdev, nr_sec);
 }
diff --git a/EncryptInplace.h b/EncryptInplace.h
index 480a47c..ef6f848 100644
--- a/EncryptInplace.h
+++ b/EncryptInplace.h
@@ -21,6 +21,6 @@
 #include <string>
 
 bool encrypt_inplace(const std::string& crypto_blkdev, const std::string& real_blkdev,
-                     uint64_t nr_sec, bool set_progress_properties);
+                     uint64_t nr_sec);
 
 #endif
diff --git a/FsCrypt.cpp b/FsCrypt.cpp
index be68222..49e7bd0 100644
--- a/FsCrypt.cpp
+++ b/FsCrypt.cpp
@@ -764,7 +764,7 @@
         // unlock directories when not in emulation mode, to bring devices
         // back into a known-good state.
         if (!emulated_unlock(android::vold::BuildDataSystemCePath(user_id), 0771) ||
-            !emulated_unlock(android::vold::BuildDataMiscCePath(user_id), 01771) ||
+            !emulated_unlock(android::vold::BuildDataMiscCePath("", user_id), 01771) ||
             !emulated_unlock(android::vold::BuildDataMediaCePath("", user_id), 0770) ||
             !emulated_unlock(android::vold::BuildDataUserCePath("", user_id), 0771)) {
             LOG(ERROR) << "Failed to unlock user " << user_id;
@@ -782,7 +782,7 @@
     } else if (fscrypt_is_emulated()) {
         // When in emulation mode, we just use chmod
         if (!emulated_lock(android::vold::BuildDataSystemCePath(user_id)) ||
-            !emulated_lock(android::vold::BuildDataMiscCePath(user_id)) ||
+            !emulated_lock(android::vold::BuildDataMiscCePath("", user_id)) ||
             !emulated_lock(android::vold::BuildDataMediaCePath("", user_id)) ||
             !emulated_lock(android::vold::BuildDataUserCePath("", user_id))) {
             LOG(ERROR) << "Failed to lock user " << user_id;
@@ -817,7 +817,7 @@
 
         // DE_n key
         auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
-        auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
+        auto misc_de_path = android::vold::BuildDataMiscDePath(volume_uuid, user_id);
         auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
         auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
 
@@ -831,9 +831,10 @@
             if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
 
             if (!prepare_dir(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
-            if (!prepare_dir(misc_de_path, 01771, AID_SYSTEM, AID_MISC)) return false;
             if (!prepare_dir(vendor_de_path, 0771, AID_ROOT, AID_ROOT)) return false;
         }
+
+        if (!prepare_dir(misc_de_path, 01771, AID_SYSTEM, AID_MISC)) return false;
         if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
 
         if (fscrypt_is_native()) {
@@ -841,11 +842,14 @@
             if (volume_uuid.empty()) {
                 if (!lookup_policy(s_de_policies, user_id, &de_policy)) return false;
                 if (!EnsurePolicy(de_policy, system_de_path)) return false;
-                if (!EnsurePolicy(de_policy, misc_de_path)) return false;
                 if (!EnsurePolicy(de_policy, vendor_de_path)) return false;
             } else {
-                if (!read_or_create_volkey(misc_de_path, volume_uuid, &de_policy)) return false;
+                auto misc_de_empty_volume_path = android::vold::BuildDataMiscDePath("", user_id);
+                if (!read_or_create_volkey(misc_de_empty_volume_path, volume_uuid, &de_policy)) {
+                    return false;
+                }
             }
+            if (!EnsurePolicy(de_policy, misc_de_path)) return false;
             if (!EnsurePolicy(de_policy, user_de_path)) return false;
         }
     }
@@ -853,14 +857,13 @@
     if (flags & android::os::IVold::STORAGE_FLAG_CE) {
         // CE_n key
         auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
-        auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
+        auto misc_ce_path = android::vold::BuildDataMiscCePath(volume_uuid, user_id);
         auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
         auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
         auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
 
         if (volume_uuid.empty()) {
             if (!prepare_dir(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
-            if (!prepare_dir(misc_ce_path, 01771, AID_SYSTEM, AID_MISC)) return false;
             if (!prepare_dir(vendor_ce_path, 0771, AID_ROOT, AID_ROOT)) return false;
         }
         if (!prepare_dir(media_ce_path, 02770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
@@ -873,6 +876,7 @@
             return false;
         }
 
+        if (!prepare_dir(misc_ce_path, 01771, AID_SYSTEM, AID_MISC)) return false;
         if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
 
         if (fscrypt_is_native()) {
@@ -880,12 +884,15 @@
             if (volume_uuid.empty()) {
                 if (!lookup_policy(s_ce_policies, user_id, &ce_policy)) return false;
                 if (!EnsurePolicy(ce_policy, system_ce_path)) return false;
-                if (!EnsurePolicy(ce_policy, misc_ce_path)) return false;
                 if (!EnsurePolicy(ce_policy, vendor_ce_path)) return false;
             } else {
-                if (!read_or_create_volkey(misc_ce_path, volume_uuid, &ce_policy)) return false;
+                auto misc_ce_empty_volume_path = android::vold::BuildDataMiscCePath("", user_id);
+                if (!read_or_create_volkey(misc_ce_empty_volume_path, volume_uuid, &ce_policy)) {
+                    return false;
+                }
             }
             if (!EnsurePolicy(ce_policy, media_ce_path)) return false;
+            if (!EnsurePolicy(ce_policy, misc_ce_path)) return false;
             if (!EnsurePolicy(ce_policy, user_ce_path)) return false;
         }
 
@@ -913,20 +920,21 @@
     if (flags & android::os::IVold::STORAGE_FLAG_CE) {
         // CE_n key
         auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
-        auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
+        auto misc_ce_path = android::vold::BuildDataMiscCePath(volume_uuid, user_id);
         auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
         auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
         auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
 
         res &= destroy_dir(media_ce_path);
+        res &= destroy_dir(misc_ce_path);
         res &= destroy_dir(user_ce_path);
         if (volume_uuid.empty()) {
             res &= destroy_dir(system_ce_path);
-            res &= destroy_dir(misc_ce_path);
             res &= destroy_dir(vendor_ce_path);
         } else {
             if (fscrypt_is_native()) {
-                res &= destroy_volkey(misc_ce_path, volume_uuid);
+                auto misc_ce_empty_volume_path = android::vold::BuildDataMiscCePath("", user_id);
+                res &= destroy_volkey(misc_ce_empty_volume_path, volume_uuid);
             }
         }
     }
@@ -939,11 +947,12 @@
 
         // DE_n key
         auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
-        auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
+        auto misc_de_path = android::vold::BuildDataMiscDePath(volume_uuid, user_id);
         auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
         auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
 
         res &= destroy_dir(user_de_path);
+        res &= destroy_dir(misc_de_path);
         if (volume_uuid.empty()) {
             res &= destroy_dir(system_legacy_path);
 #if MANAGE_MISC_DIRS
@@ -951,11 +960,11 @@
 #endif
             res &= destroy_dir(profiles_de_path);
             res &= destroy_dir(system_de_path);
-            res &= destroy_dir(misc_de_path);
             res &= destroy_dir(vendor_de_path);
         } else {
             if (fscrypt_is_native()) {
-                res &= destroy_volkey(misc_de_path, volume_uuid);
+                auto misc_de_empty_volume_path = android::vold::BuildDataMiscDePath("", user_id);
+                res &= destroy_volkey(misc_de_empty_volume_path, volume_uuid);
             }
         }
     }
diff --git a/IdleMaint.cpp b/IdleMaint.cpp
index 769d7a5..2fc0d4b 100644
--- a/IdleMaint.cpp
+++ b/IdleMaint.cpp
@@ -89,7 +89,7 @@
 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 const int GC_URGENT_MID_MODE = 3;
 
 static int32_t previousSegmentWrite = 0;
 
@@ -596,7 +596,7 @@
         return;
     }
 
-    if (!WriteStringToFile(std::to_string(GC_URGENT_HIGH_MODE), gcUrgentModePath)) {
+    if (!WriteStringToFile(std::to_string(GC_URGENT_MID_MODE), gcUrgentModePath)) {
         PLOG(WARNING) << "Writing failed in " << gcUrgentModePath;
         return;
     }
diff --git a/Keystore.cpp b/Keystore.cpp
index a017d68..d993b0d 100644
--- a/Keystore.cpp
+++ b/Keystore.cpp
@@ -166,7 +166,13 @@
         *key = std::string(ephemeral_key_response.ephemeralKey.begin(),
                            ephemeral_key_response.ephemeralKey.end());
 
-    // TODO b/185811713 store the upgraded key blob if provided and delete the old key blob.
+    // vold intentionally ignores ephemeral_key_response.upgradedBlob, since the
+    // concept of "upgrading" doesn't make sense for TAG_STORAGE_KEY keys
+    // (hardware-wrapped inline encryption keys).  These keys are only meant as
+    // a substitute for raw keys; they still go through vold's usual layer of
+    // key wrapping, which already handles version binding.  So, vold just keeps
+    // using the original blobs for TAG_STORAGE_KEY keys.  If KeyMint "upgrades"
+    // them anyway, then they'll just get re-upgraded before each use.
 
     ret = true;
 out:
diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp
index 6550be4..5c9e644 100644
--- a/MetadataCrypt.cpp
+++ b/MetadataCrypt.cpp
@@ -261,7 +261,7 @@
 
     CryptoOptions options;
     if (options_format_version == 1) {
-        if (!data_rec->metadata_encryption.empty()) {
+        if (!data_rec->metadata_encryption_options.empty()) {
             LOG(ERROR) << "metadata_encryption options cannot be set in legacy mode";
             return false;
         }
@@ -274,7 +274,7 @@
             return false;
         }
     } else if (options_format_version == 2) {
-        if (!parse_options(data_rec->metadata_encryption, &options)) return false;
+        if (!parse_options(data_rec->metadata_encryption_options, &options)) return false;
     } else {
         LOG(ERROR) << "Unknown options_format_version: " << options_format_version;
         return false;
@@ -314,7 +314,7 @@
             }
             LOG(DEBUG) << "Format of " << crypto_blkdev << " for " << mount_point << " succeeded.";
         } else {
-            if (!encrypt_inplace(crypto_blkdev, blk_device, nr_sec, false)) {
+            if (!encrypt_inplace(crypto_blkdev, blk_device, nr_sec)) {
                 LOG(ERROR) << "encrypt_inplace failed in mountFstab";
                 return false;
             }
diff --git a/Utils.cpp b/Utils.cpp
index 864cbf8..ba6afd8 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -1120,14 +1120,6 @@
     return StringPrintf("%s/misc/user/%u", BuildDataPath("").c_str(), userId);
 }
 
-std::string BuildDataMiscCePath(userid_t userId) {
-    return StringPrintf("%s/misc_ce/%u", BuildDataPath("").c_str(), userId);
-}
-
-std::string BuildDataMiscDePath(userid_t userId) {
-    return StringPrintf("%s/misc_de/%u", BuildDataPath("").c_str(), userId);
-}
-
 // Keep in sync with installd (frameworks/native/cmds/installd/utils.h)
 std::string BuildDataProfilesDePath(userid_t userId) {
     return StringPrintf("%s/misc/profiles/cur/%u", BuildDataPath("").c_str(), userId);
@@ -1157,6 +1149,14 @@
     return StringPrintf("%s/media/%u", data.c_str(), userId);
 }
 
+std::string BuildDataMiscCePath(const std::string& volumeUuid, userid_t userId) {
+    return StringPrintf("%s/misc_ce/%u", BuildDataPath(volumeUuid).c_str(), userId);
+}
+
+std::string BuildDataMiscDePath(const std::string& volumeUuid, userid_t userId) {
+    return StringPrintf("%s/misc_de/%u", BuildDataPath(volumeUuid).c_str(), userId);
+}
+
 std::string BuildDataUserCePath(const std::string& volumeUuid, userid_t userId) {
     // TODO: unify with installd path generation logic
     std::string data(BuildDataPath(volumeUuid));
@@ -1266,49 +1266,6 @@
     return kMajorBlockVirtioBlk && major == kMajorBlockVirtioBlk;
 }
 
-static status_t findMountPointsWithPrefix(const std::string& prefix,
-                                          std::list<std::string>& mountPoints) {
-    // Add a trailing slash if the client didn't provide one so that we don't match /foo/barbaz
-    // when the prefix is /foo/bar
-    std::string prefixWithSlash(prefix);
-    if (prefix.back() != '/') {
-        android::base::StringAppendF(&prefixWithSlash, "/");
-    }
-
-    std::unique_ptr<FILE, int (*)(FILE*)> mnts(setmntent("/proc/mounts", "re"), endmntent);
-    if (!mnts) {
-        PLOG(ERROR) << "Unable to open /proc/mounts";
-        return -errno;
-    }
-
-    // Some volumes can be stacked on each other, so force unmount in
-    // reverse order to give us the best chance of success.
-    struct mntent* mnt;  // getmntent returns a thread local, so it's safe.
-    while ((mnt = getmntent(mnts.get())) != nullptr) {
-        auto mountPoint = std::string(mnt->mnt_dir) + "/";
-        if (android::base::StartsWith(mountPoint, prefixWithSlash)) {
-            mountPoints.push_front(mountPoint);
-        }
-    }
-    return OK;
-}
-
-// Unmount all mountpoints that start with prefix. prefix itself doesn't need to be a mountpoint.
-status_t UnmountTreeWithPrefix(const std::string& prefix) {
-    std::list<std::string> toUnmount;
-    status_t result = findMountPointsWithPrefix(prefix, toUnmount);
-    if (result < 0) {
-        return result;
-    }
-    for (const auto& path : toUnmount) {
-        if (umount2(path.c_str(), MNT_DETACH)) {
-            PLOG(ERROR) << "Failed to unmount " << path;
-            result = -errno;
-        }
-    }
-    return result;
-}
-
 status_t UnmountTree(const std::string& mountPoint) {
     if (TEMP_FAILURE_RETRY(umount2(mountPoint.c_str(), MNT_DETACH)) < 0 && errno != EINVAL &&
         errno != ENOENT) {
diff --git a/Utils.h b/Utils.h
index 2d54639..71eb5eb 100644
--- a/Utils.h
+++ b/Utils.h
@@ -37,7 +37,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 const char* kFuseBpfEnabled = "persist.sys.fuse.bpf.override";
 
 static constexpr std::chrono::seconds kUntrustedFsckSleepTime(45);
 
@@ -150,14 +150,14 @@
 std::string BuildDataSystemCePath(userid_t userid);
 std::string BuildDataSystemDePath(userid_t userid);
 std::string BuildDataMiscLegacyPath(userid_t userid);
-std::string BuildDataMiscCePath(userid_t userid);
-std::string BuildDataMiscDePath(userid_t userid);
 std::string BuildDataProfilesDePath(userid_t userid);
 std::string BuildDataVendorCePath(userid_t userid);
 std::string BuildDataVendorDePath(userid_t userid);
 
 std::string BuildDataPath(const std::string& volumeUuid);
 std::string BuildDataMediaCePath(const std::string& volumeUuid, userid_t userid);
+std::string BuildDataMiscCePath(const std::string& volumeUuid, userid_t userid);
+std::string BuildDataMiscDePath(const std::string& volumeUuid, userid_t userid);
 std::string BuildDataUserCePath(const std::string& volumeUuid, userid_t userid);
 std::string BuildDataUserDePath(const std::string& volumeUuid, userid_t userid);
 
@@ -175,7 +175,6 @@
 // Handles dynamic major assignment for virtio-block
 bool IsVirtioBlkDevice(unsigned int major);
 
-status_t UnmountTreeWithPrefix(const std::string& prefix);
 status_t UnmountTree(const std::string& mountPoint);
 
 bool IsDotOrDotDot(const struct dirent& ent);
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index 1033af9..f5fb908 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -414,16 +414,13 @@
     return translate(VolumeManager::Instance()->fixupAppDir(path, appUid));
 }
 
-binder::Status VoldNativeService::createObb(const std::string& sourcePath,
-                                            const std::string& sourceKey, int32_t ownerGid,
+binder::Status VoldNativeService::createObb(const std::string& sourcePath, int32_t ownerGid,
                                             std::string* _aidl_return) {
     ENFORCE_SYSTEM_OR_ROOT;
     CHECK_ARGUMENT_PATH(sourcePath);
-    CHECK_ARGUMENT_HEX(sourceKey);
     ACQUIRE_LOCK;
 
-    return translate(
-            VolumeManager::Instance()->createObb(sourcePath, sourceKey, ownerGid, _aidl_return));
+    return translate(VolumeManager::Instance()->createObb(sourcePath, ownerGid, _aidl_return));
 }
 
 binder::Status VoldNativeService::destroyObb(const std::string& volId) {
@@ -731,36 +728,19 @@
     return translateBool(fscrypt_destroy_user_key(userId));
 }
 
-static bool token_empty(const std::string& token) {
-    return token.size() == 0 || token == "!";
-}
-
 binder::Status VoldNativeService::addUserKeyAuth(int32_t userId, int32_t userSerial,
-                                                 const std::string& token,
                                                  const std::string& secret) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    if (!token_empty(token)) {
-        LOG(ERROR) << "Vold doesn't use auth tokens, but non-empty token passed to addUserKeyAuth.";
-        return binder::Status::fromServiceSpecificError(-EINVAL);
-    }
-
     return translateBool(fscrypt_add_user_key_auth(userId, userSerial, secret));
 }
 
 binder::Status VoldNativeService::clearUserKeyAuth(int32_t userId, int32_t userSerial,
-                                                   const std::string& token,
                                                    const std::string& secret) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    if (!token_empty(token)) {
-        LOG(ERROR)
-                << "Vold doesn't use auth tokens, but non-empty token passed to clearUserKeyAuth.";
-        return binder::Status::fromServiceSpecificError(-EINVAL);
-    }
-
     return translateBool(fscrypt_clear_user_key_auth(userId, userSerial, secret));
 }
 
@@ -780,16 +760,10 @@
 }
 
 binder::Status VoldNativeService::unlockUserKey(int32_t userId, int32_t userSerial,
-                                                const std::string& token,
                                                 const std::string& secret) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
-    if (!token_empty(token)) {
-        LOG(ERROR) << "Vold doesn't use auth tokens, but non-empty token passed to unlockUserKey.";
-        return binder::Status::fromServiceSpecificError(-EINVAL);
-    }
-
     return translateBool(fscrypt_unlock_user_key(userId, userSerial, secret));
 }
 
diff --git a/VoldNativeService.h b/VoldNativeService.h
index 49bcbaa..88fc9e7 100644
--- a/VoldNativeService.h
+++ b/VoldNativeService.h
@@ -73,8 +73,8 @@
     binder::Status setupAppDir(const std::string& path, int32_t appUid);
     binder::Status fixupAppDir(const std::string& path, int32_t appUid);
 
-    binder::Status createObb(const std::string& sourcePath, const std::string& sourceKey,
-                             int32_t ownerGid, std::string* _aidl_return);
+    binder::Status createObb(const std::string& sourcePath, int32_t ownerGid,
+                             std::string* _aidl_return);
     binder::Status destroyObb(const std::string& volId);
 
     binder::Status createStubVolume(const std::string& sourcePath, const std::string& mountPath,
@@ -127,15 +127,12 @@
     binder::Status createUserKey(int32_t userId, int32_t userSerial, bool ephemeral);
     binder::Status destroyUserKey(int32_t userId);
 
-    binder::Status addUserKeyAuth(int32_t userId, int32_t userSerial, const std::string& token,
-                                  const std::string& secret);
-    binder::Status clearUserKeyAuth(int32_t userId, int32_t userSerial, const std::string& token,
-                                    const std::string& secret);
+    binder::Status addUserKeyAuth(int32_t userId, int32_t userSerial, const std::string& secret);
+    binder::Status clearUserKeyAuth(int32_t userId, int32_t userSerial, const std::string& secret);
     binder::Status fixateNewestUserKeyAuth(int32_t userId);
 
     binder::Status getUnlockedUsers(std::vector<int>* _aidl_return);
-    binder::Status unlockUserKey(int32_t userId, int32_t userSerial, const std::string& token,
-                                 const std::string& secret);
+    binder::Status unlockUserKey(int32_t userId, int32_t userSerial, const std::string& secret);
     binder::Status lockUserKey(int32_t userId);
 
     binder::Status prepareUserStorage(const std::optional<std::string>& uuid, int32_t userId,
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 9311321..bc556ef 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -55,7 +55,6 @@
 #include <fscrypt/fscrypt.h>
 
 #include "AppFuseUtil.h"
-#include "Devmapper.h"
 #include "FsCrypt.h"
 #include "Loop.h"
 #include "NetlinkManager.h"
@@ -94,7 +93,6 @@
 using android::vold::VoldNativeService;
 using android::vold::VolumeBase;
 
-static const char* kPathUserMount = "/mnt/user";
 static const char* kPathVirtualDisk = "/data/misc/vold/virtual_disk";
 
 static const char* kPropVirtualDisk = "persist.sys.virtual_disk";
@@ -179,7 +177,6 @@
     // directories that we own, in case we crashed.
     unmountAll();
 
-    Devmapper::destroyAll();
     Loop::destroyAll();
 
     // Assume that we always have an emulated volume on internal
@@ -1075,8 +1072,8 @@
     return setupAppDir(path, appUid, true /* fixupExistingOnly */);
 }
 
-int VolumeManager::createObb(const std::string& sourcePath, const std::string& sourceKey,
-                             int32_t ownerGid, std::string* outVolId) {
+int VolumeManager::createObb(const std::string& sourcePath, int32_t ownerGid,
+                             std::string* outVolId) {
     int id = mNextObbId++;
 
     std::string lowerSourcePath;
@@ -1114,7 +1111,7 @@
     }
 
     auto vol = std::shared_ptr<android::vold::VolumeBase>(
-            new android::vold::ObbVolume(id, lowerSourcePath, sourceKey, ownerGid));
+            new android::vold::ObbVolume(id, lowerSourcePath, ownerGid));
     vol->create();
 
     mObbVolumes.push_back(vol);
diff --git a/VolumeManager.h b/VolumeManager.h
index 3573b1a..a8117c9 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -186,8 +186,7 @@
     // Called before zygote starts to ensure dir exists so zygote can bind mount them.
     int ensureAppDirsCreated(const std::vector<std::string>& paths, int32_t appUid);
 
-    int createObb(const std::string& path, const std::string& key, int32_t ownerGid,
-                  std::string* outVolId);
+    int createObb(const std::string& path, int32_t ownerGid, std::string* outVolId);
     int destroyObb(const std::string& volId);
 
     int createStubVolume(const std::string& sourcePath, const std::string& mountPath,
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index c72ceea..aee75f5 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -60,8 +60,7 @@
     void fixupAppDir(@utf8InCpp String path, int appUid);
     void ensureAppDirsCreated(in @utf8InCpp String[] paths, int appUid);
 
-    @utf8InCpp String createObb(@utf8InCpp String sourcePath, @utf8InCpp String sourceKey,
-                                int ownerGid);
+    @utf8InCpp String createObb(@utf8InCpp String sourcePath, int ownerGid);
     void destroyObb(@utf8InCpp String volId);
 
     void fstrim(int fstrimFlags, IVoldTaskListener listener);
@@ -101,15 +100,12 @@
     void createUserKey(int userId, int userSerial, boolean ephemeral);
     void destroyUserKey(int userId);
 
-    void addUserKeyAuth(int userId, int userSerial, @utf8InCpp String token,
-                        @utf8InCpp String secret);
-    void clearUserKeyAuth(int userId, int userSerial, @utf8InCpp String token,
-                        @utf8InCpp String secret);
+    void addUserKeyAuth(int userId, int userSerial, @utf8InCpp String secret);
+    void clearUserKeyAuth(int userId, int userSerial, @utf8InCpp String secret);
     void fixateNewestUserKeyAuth(int userId);
 
     int[] getUnlockedUsers();
-    void unlockUserKey(int userId, int userSerial, @utf8InCpp String token,
-                       @utf8InCpp String secret);
+    void unlockUserKey(int userId, int userSerial, @utf8InCpp String secret);
     void lockUserKey(int userId);
 
     void prepareUserStorage(@nullable @utf8InCpp String uuid, int userId, int userSerial,
diff --git a/fs/Ext4.cpp b/fs/Ext4.cpp
index 91f62ff..52f6772 100644
--- a/fs/Ext4.cpp
+++ b/fs/Ext4.cpp
@@ -66,8 +66,6 @@
 
     const char* c_source = source.c_str();
     const char* c_target = target.c_str();
-
-    int status;
     int ret;
     long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
     char* tmpmnt_opts = (char*)"nomblk_io_submit,errors=remount-ro";
diff --git a/main.cpp b/main.cpp
index 978db66..42789c9 100644
--- a/main.cpp
+++ b/main.cpp
@@ -251,7 +251,7 @@
             PLOG(FATAL) << "could not find logical partition " << entry.blk_device;
         }
 
-        if (entry.mount_point == "/data" && !entry.metadata_encryption.empty()) {
+        if (entry.mount_point == "/data" && !entry.metadata_key_dir.empty()) {
             // Pre-populate userdata dm-devices since the uevents are asynchronous (b/198405417).
             android::vold::defaultkey_precreate_dm_device();
         }
diff --git a/model/ObbVolume.cpp b/model/ObbVolume.cpp
index 21479c4..b64c1ba 100644
--- a/model/ObbVolume.cpp
+++ b/model/ObbVolume.cpp
@@ -15,7 +15,6 @@
  */
 
 #include "ObbVolume.h"
-#include "Devmapper.h"
 #include "Loop.h"
 #include "Utils.h"
 #include "VoldUtil.h"
@@ -39,12 +38,10 @@
 namespace android {
 namespace vold {
 
-ObbVolume::ObbVolume(int id, const std::string& sourcePath, const std::string& sourceKey,
-                     gid_t ownerGid)
+ObbVolume::ObbVolume(int id, const std::string& sourcePath, gid_t ownerGid)
     : VolumeBase(Type::kObb) {
     setId(StringPrintf("obb:%d", id));
     mSourcePath = sourcePath;
-    mSourceKey = sourceKey;
     mOwnerGid = ownerGid;
 }
 
@@ -55,36 +52,13 @@
         PLOG(ERROR) << getId() << " failed to create loop";
         return -1;
     }
-
-    if (!mSourceKey.empty()) {
-        uint64_t nr_sec = 0;
-        if (GetBlockDev512Sectors(mLoopPath, &nr_sec) != OK) {
-            PLOG(ERROR) << getId() << " failed to get loop size";
-            return -1;
-        }
-
-        char tmp[PATH_MAX];
-        if (Devmapper::create(getId().c_str(), mLoopPath.c_str(), mSourceKey.c_str(), nr_sec, tmp,
-                              PATH_MAX)) {
-            PLOG(ERROR) << getId() << " failed to create dm";
-            return -1;
-        }
-        mDmPath = tmp;
-        mMountPath = mDmPath;
-    } else {
-        mMountPath = mLoopPath;
-    }
     return OK;
 }
 
 status_t ObbVolume::doDestroy() {
-    if (!mDmPath.empty() && Devmapper::destroy(getId().c_str())) {
-        PLOG(WARNING) << getId() << " failed to destroy dm";
-    }
     if (!mLoopPath.empty() && Loop::destroyByDevice(mLoopPath.c_str())) {
         PLOG(WARNING) << getId() << " failed to destroy loop";
     }
-    mDmPath.clear();
     mLoopPath.clear();
     return OK;
 }
@@ -98,7 +72,7 @@
         return -1;
     }
     // clang-format off
-    if (android::vold::vfat::Mount(mMountPath, path, true, false, true,
+    if (android::vold::vfat::Mount(mLoopPath, path, true, false, true,
                                    0, mOwnerGid, 0227, false)) {
         // clang-format on
         PLOG(ERROR) << getId() << " failed to mount";
diff --git a/model/ObbVolume.h b/model/ObbVolume.h
index 8f7ee94..bfcd3d2 100644
--- a/model/ObbVolume.h
+++ b/model/ObbVolume.h
@@ -29,7 +29,7 @@
  */
 class ObbVolume : public VolumeBase {
   public:
-    ObbVolume(int id, const std::string& sourcePath, const std::string& sourceKey, gid_t ownerGid);
+    ObbVolume(int id, const std::string& sourcePath, gid_t ownerGid);
     virtual ~ObbVolume();
 
   protected:
@@ -40,12 +40,9 @@
 
   private:
     std::string mSourcePath;
-    std::string mSourceKey;
     gid_t mOwnerGid;
 
     std::string mLoopPath;
-    std::string mDmPath;
-    std::string mMountPath;
 
     DISALLOW_COPY_AND_ASSIGN(ObbVolume);
 };
diff --git a/model/PrivateVolume.cpp b/model/PrivateVolume.cpp
index 1875b7b..a692ea9 100644
--- a/model/PrivateVolume.cpp
+++ b/model/PrivateVolume.cpp
@@ -173,6 +173,8 @@
     if (PrepareDir(mPath + "/app", 0771, AID_SYSTEM, AID_SYSTEM) ||
         PrepareDir(mPath + "/user", 0711, AID_SYSTEM, AID_SYSTEM) ||
         PrepareDir(mPath + "/user_de", 0711, AID_SYSTEM, AID_SYSTEM) ||
+        PrepareDir(mPath + "/misc_ce", 0711, AID_SYSTEM, AID_SYSTEM) ||
+        PrepareDir(mPath + "/misc_de", 0711, AID_SYSTEM, AID_SYSTEM) ||
         PrepareDir(mPath + "/media", 0770, AID_MEDIA_RW, AID_MEDIA_RW, attrs) ||
         PrepareDir(mPath + "/media/0", 0770, AID_MEDIA_RW, AID_MEDIA_RW) ||
         PrepareDir(mPath + "/local", 0751, AID_ROOT, AID_ROOT) ||
diff --git a/vdc.cpp b/vdc.cpp
index 313ef55..740e246 100644
--- a/vdc.cpp
+++ b/vdc.cpp
@@ -116,12 +116,6 @@
         checkStatus(args, vold->fbeEnable());
     } else if (args[0] == "cryptfs" && args[1] == "init_user0") {
         checkStatus(args, vold->initUser0());
-    } else if (args[0] == "cryptfs" && args[1] == "enablecrypto") {
-        int passwordType = android::os::IVold::PASSWORD_TYPE_DEFAULT;
-        int encryptionFlags = android::os::IVold::ENCRYPTION_FLAG_NO_UI;
-        checkStatus(args, vold->fdeEnable(passwordType, "", encryptionFlags));
-    } else if (args[0] == "cryptfs" && args[1] == "mountdefaultencrypted") {
-        checkStatus(args, vold->mountDefaultEncrypted());
     } else if (args[0] == "volume" && args[1] == "abort_fuse") {
         checkStatus(args, vold->abortFuse());
     } else if (args[0] == "volume" && args[1] == "shutdown") {
diff --git a/vold_prepare_subdirs.cpp b/vold_prepare_subdirs.cpp
index 0d58e4d..94d7f15 100644
--- a/vold_prepare_subdirs.cpp
+++ b/vold_prepare_subdirs.cpp
@@ -172,8 +172,13 @@
             return false;
         }
 
+        auto misc_de_path = android::vold::BuildDataMiscDePath(volume_uuid, user_id);
+        if (!prepare_dir_for_user(sehandle, 0771, AID_SYSTEM, AID_SYSTEM,
+                                  misc_de_path + "/sdksandbox", user_id)) {
+            return false;
+        }
+
         if (volume_uuid.empty()) {
-            auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
             if (!prepare_dir(sehandle, 0700, 0, 0, misc_de_path + "/vold")) return false;
             if (!prepare_dir(sehandle, 0700, 0, 0, misc_de_path + "/storaged")) return false;
             if (!prepare_dir(sehandle, 0700, 0, 0, misc_de_path + "/rollback")) return false;
@@ -203,8 +208,13 @@
             return false;
         }
 
+        auto misc_ce_path = android::vold::BuildDataMiscCePath(volume_uuid, user_id);
+        if (!prepare_dir_for_user(sehandle, 0771, AID_SYSTEM, AID_SYSTEM,
+                                  misc_ce_path + "/sdksandbox", user_id)) {
+            return false;
+        }
+
         if (volume_uuid.empty()) {
-            auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
             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;
@@ -246,18 +256,20 @@
 
 static bool destroy_subdirs(const std::string& volume_uuid, int user_id, int flags) {
     bool res = true;
-    if (volume_uuid.empty()) {
-        if (flags & android::os::IVold::STORAGE_FLAG_CE) {
-            auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
-            res &= rmrf_contents(misc_ce_path);
+    if (flags & android::os::IVold::STORAGE_FLAG_CE) {
+        auto misc_ce_path = android::vold::BuildDataMiscCePath(volume_uuid, user_id);
+        res &= rmrf_contents(misc_ce_path);
 
+        if (volume_uuid.empty()) {
             auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
             res &= rmrf_contents(vendor_ce_path);
         }
-        if (flags & android::os::IVold::STORAGE_FLAG_DE) {
-            auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
-            res &= rmrf_contents(misc_de_path);
+    }
+    if (flags & android::os::IVold::STORAGE_FLAG_DE) {
+        auto misc_de_path = android::vold::BuildDataMiscDePath(volume_uuid, user_id);
+        res &= rmrf_contents(misc_de_path);
 
+        if (volume_uuid.empty()) {
             auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
             res &= rmrf_contents(vendor_de_path);
         }