Merge "Add IVold::destroyDsuMetadataKey()"
diff --git a/Checkpoint.cpp b/Checkpoint.cpp
index 61035e5..755f0e3 100644
--- a/Checkpoint.cpp
+++ b/Checkpoint.cpp
@@ -47,7 +47,6 @@
 using android::base::SetProperty;
 using android::binder::Status;
 using android::fs_mgr::Fstab;
-using android::fs_mgr::ReadDefaultFstab;
 using android::fs_mgr::ReadFstabFromFile;
 using android::hardware::hidl_string;
 using android::hardware::boot::V1_0::BoolResult;
diff --git a/IdleMaint.cpp b/IdleMaint.cpp
index 2b5a8f1..e4a1806 100644
--- a/IdleMaint.cpp
+++ b/IdleMaint.cpp
@@ -17,6 +17,7 @@
 #include "IdleMaint.h"
 #include "FileDeviceUtils.h"
 #include "Utils.h"
+#include "VoldUtil.h"
 #include "VolumeManager.h"
 #include "model/PrivateVolume.h"
 
@@ -45,8 +46,6 @@
 using android::base::StringPrintf;
 using android::base::Timer;
 using android::base::WriteStringToFile;
-using android::fs_mgr::Fstab;
-using android::fs_mgr::ReadDefaultFstab;
 using android::hardware::Return;
 using android::hardware::Void;
 using android::hardware::health::storage::V1_0::IStorage;
@@ -104,17 +103,18 @@
 }
 
 static void addFromFstab(std::list<std::string>* paths, PathTypes path_type) {
-    Fstab fstab;
-    ReadDefaultFstab(&fstab);
-
     std::string previous_mount_point;
-    for (const auto& entry : fstab) {
-        // Skip raw partitions.
-        if (entry.fs_type == "emmc" || entry.fs_type == "mtd") {
+    for (const auto& entry : fstab_default) {
+        // Skip raw partitions and swap space.
+        if (entry.fs_type == "emmc" || entry.fs_type == "mtd" || entry.fs_type == "swap") {
             continue;
         }
-        // Skip read-only filesystems
-        if (entry.flags & MS_RDONLY) {
+        // Skip read-only filesystems and bind mounts.
+        if (entry.flags & (MS_RDONLY | MS_BIND)) {
+            continue;
+        }
+        // Skip anything without an underlying block device, e.g. virtiofs.
+        if (entry.blk_device[0] != '/') {
             continue;
         }
         if (entry.fs_mgr_flags.vold_managed) {
@@ -253,11 +253,8 @@
 }
 
 static void runDevGcFstab(void) {
-    Fstab fstab;
-    ReadDefaultFstab(&fstab);
-
     std::string path;
-    for (const auto& entry : fstab) {
+    for (const auto& entry : fstab_default) {
         if (!entry.sysfs_path.empty()) {
             path = entry.sysfs_path;
             break;
diff --git a/KeyStorage.cpp b/KeyStorage.cpp
index 951536b..533a7cb 100644
--- a/KeyStorage.cpp
+++ b/KeyStorage.cpp
@@ -141,9 +141,12 @@
     if (!keymaster) return false;
     std::string key_temp;
     auto paramBuilder = km::AuthorizationSetBuilder().AesEncryptionKey(AES_KEY_BYTES * 8);
-    paramBuilder.Authorization(km::TAG_ROLLBACK_RESISTANCE);
     paramBuilder.Authorization(km::TAG_STORAGE_KEY);
-    if (!keymaster.generateKey(paramBuilder, &key_temp)) return false;
+    auto paramsWithRollback = paramBuilder;
+    paramsWithRollback.Authorization(km::TAG_ROLLBACK_RESISTANCE);
+    if (!keymaster.generateKey(paramsWithRollback, &key_temp)) {
+        if (!keymaster.generateKey(paramBuilder, &key_temp)) return false;
+    }
     *key = KeyBuffer(key_temp.size());
     memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
     return true;
diff --git a/Loop.cpp b/Loop.cpp
index 9fa876c..87f105d 100644
--- a/Loop.cpp
+++ b/Loop.cpp
@@ -150,7 +150,9 @@
 
         struct loop_info64 li;
         if (ioctl(fd.get(), LOOP_GET_STATUS64, &li) < 0) {
-            PLOG(WARNING) << "Failed to LOOP_GET_STATUS64 " << path;
+            if (errno != ENXIO) {
+                PLOG(WARNING) << "Failed to LOOP_GET_STATUS64 " << path;
+            }
             continue;
         }
 
diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp
index 52add4a..5950425 100644
--- a/MetadataCrypt.cpp
+++ b/MetadataCrypt.cpp
@@ -46,8 +46,6 @@
 #include "Utils.h"
 #include "VoldUtil.h"
 
-#define TABLE_LOAD_RETRIES 10
-
 namespace android {
 namespace vold {
 
@@ -216,20 +214,8 @@
     table.AddTarget(std::move(target));
 
     auto& dm = DeviceMapper::Instance();
-    for (int i = 0;; i++) {
-        if (dm.CreateDevice(dm_name, table)) {
-            break;
-        }
-        if (i + 1 >= TABLE_LOAD_RETRIES) {
-            PLOG(ERROR) << "Could not create default-key device " << dm_name;
-            return false;
-        }
-        PLOG(INFO) << "Could not create default-key device, retrying";
-        usleep(500000);
-    }
-
-    if (!dm.GetDmDevicePathByName(dm_name, crypto_blkdev)) {
-        LOG(ERROR) << "Cannot retrieve default-key device status " << dm_name;
+    if (!dm.CreateDevice(dm_name, table, crypto_blkdev, std::chrono::seconds(5))) {
+        PLOG(ERROR) << "Could not create default-key device " << dm_name;
         return false;
     }
     return true;
diff --git a/Utils.cpp b/Utils.cpp
index a9b7440..17921e8 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -416,7 +416,32 @@
     return OK;
 }
 
-status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid) {
+int SetAttrs(const std::string& path, unsigned int attrs) {
+    unsigned long flags;
+    android::base::unique_fd fd(
+            TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC)));
+
+    if (fd == -1) {
+        PLOG(ERROR) << "Failed to open " << path;
+        return -1;
+    }
+
+    if (ioctl(fd, FS_IOC_GETFLAGS, (void*)&flags)) {
+        PLOG(ERROR) << "Failed to get flags for " << path;
+        return -1;
+    }
+
+    if ((flags & attrs) == attrs) return 0;
+    flags |= attrs;
+    if (ioctl(fd, FS_IOC_SETFLAGS, (void*)&flags)) {
+        PLOG(ERROR) << "Failed to set flags for " << path << "(0x" << std::hex << attrs << ")";
+        return -1;
+    }
+    return 0;
+}
+
+status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid,
+                    unsigned int attrs) {
     std::lock_guard<std::mutex> lock(kSecurityLock);
     const char* cpath = path.c_str();
 
@@ -434,6 +459,9 @@
         freecon(secontext);
     }
 
+    if (res) return -errno;
+    if (attrs) res = SetAttrs(path, attrs);
+
     if (res == 0) {
         return OK;
     } else {
diff --git a/Utils.h b/Utils.h
index 04cbac4..5351450 100644
--- a/Utils.h
+++ b/Utils.h
@@ -67,7 +67,8 @@
                           bool fixupExisting);
 
 /* fs_prepare_dir wrapper that creates with SELinux context */
-status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid);
+status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid,
+                    unsigned int attrs = 0);
 
 /* Really unmounts the path, killing active processes along the way */
 status_t ForceUnmount(const std::string& path);
diff --git a/model/PrivateVolume.cpp b/model/PrivateVolume.cpp
index 39a946c..1875b7b 100644
--- a/model/PrivateVolume.cpp
+++ b/model/PrivateVolume.cpp
@@ -166,11 +166,14 @@
 
     RestoreconRecursive(mPath);
 
+    int attrs = 0;
+    if (!IsSdcardfsUsed()) attrs = FS_CASEFOLD_FL;
+
     // Verify that common directories are ready to roll
     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 + "/media", 0770, AID_MEDIA_RW, AID_MEDIA_RW) ||
+        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) ||
         PrepareDir(mPath + "/local/tmp", 0771, AID_SHELL, AID_SHELL)) {