Merge "Fix mounting /data on Virtual A/B devices without metadata encryption."
diff --git a/base/Android.bp b/base/Android.bp
index b25d0df..a32959b 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -33,6 +33,7 @@
 cc_library_headers {
     name: "libbase_headers",
     vendor_available: true,
+    ramdisk_available: true,
     recovery_available: true,
     host_supported: true,
     native_bridge_supported: true,
@@ -112,6 +113,7 @@
     name: "libbase",
     defaults: ["libbase_defaults"],
     vendor_available: true,
+    ramdisk_available: true,
     recovery_available: true,
     host_supported: true,
     native_bridge_supported: true,
diff --git a/base/include/android-base/expected.h b/base/include/android-base/expected.h
index 030ef35e..b3f5adb 100644
--- a/base/include/android-base/expected.h
+++ b/base/include/android-base/expected.h
@@ -111,6 +111,7 @@
     !(!std::is_convertible_v<const U&, T> ||
      !std::is_convertible_v<const G&, E>) /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(const expected<U, G>& rhs) {
     if (rhs.has_value()) var_ = rhs.value();
     else var_ = unexpected(rhs.error());
@@ -149,6 +150,7 @@
     !(!std::is_convertible_v<const U&, T> ||
      !std::is_convertible_v<const G&, E>) /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(expected<U, G>&& rhs) {
     if (rhs.has_value()) var_ = std::move(rhs.value());
     else var_ = unexpected(std::move(rhs.error()));
@@ -180,6 +182,7 @@
                 !std::is_same_v<unexpected<E>, std::remove_cv_t<std::remove_reference_t<U>>> &&
                 std::is_convertible_v<U&&, T> /* non-explicit */
                 )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(U&& v) : var_(std::in_place_index<0>, std::forward<U>(v)) {}
 
   template <class U = T _ENABLE_IF(
@@ -195,6 +198,7 @@
     std::is_constructible_v<E, const G&> &&
     std::is_convertible_v<const G&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(const unexpected<G>& e)
   : var_(std::in_place_index<1>, e.value()) {}
 
@@ -209,6 +213,7 @@
     std::is_constructible_v<E, G&&> &&
     std::is_convertible_v<G&&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(unexpected<G>&& e)
   : var_(std::in_place_index<1>, std::move(e.value())) {}
 
@@ -457,6 +462,7 @@
     std::is_void_v<U> &&
     std::is_convertible_v<const G&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(const expected<U, G>& rhs) {
     if (!rhs.has_value()) var_ = unexpected(rhs.error());
   }
@@ -473,6 +479,7 @@
     std::is_void_v<U> &&
     std::is_convertible_v<const G&&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(expected<U, G>&& rhs) {
     if (!rhs.has_value()) var_ = unexpected(std::move(rhs.error()));
   }
@@ -489,6 +496,7 @@
     std::is_constructible_v<E, const G&> &&
     std::is_convertible_v<const G&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(const unexpected<G>& e)
   : var_(std::in_place_index<1>, e.value()) {}
 
@@ -503,6 +511,7 @@
     std::is_constructible_v<E, G&&> &&
     std::is_convertible_v<G&&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(unexpected<G>&& e)
   : var_(std::in_place_index<1>, std::move(e.value())) {}
 
@@ -640,6 +649,7 @@
                 std::is_constructible_v<E, Err> &&
                 !std::is_same_v<std::remove_cv_t<std::remove_reference_t<E>>, std::in_place_t> &&
                 !std::is_same_v<std::remove_cv_t<std::remove_reference_t<E>>, unexpected>)>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr unexpected(Err&& e) : val_(std::forward<Err>(e)) {}
 
   template<class U, class... Args _ENABLE_IF(
@@ -660,6 +670,7 @@
     !std::is_convertible_v<const unexpected<Err>, E> &&
     std::is_convertible_v<Err, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr unexpected(const unexpected<Err>& rhs)
   : val_(rhs.value()) {}
 
@@ -690,6 +701,7 @@
     !std::is_convertible_v<const unexpected<Err>, E> &&
     std::is_convertible_v<Err, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr unexpected(unexpected<Err>&& rhs)
   : val_(std::move(rhs.value())) {}
 
diff --git a/base/include/android-base/result.h b/base/include/android-base/result.h
index 1b763af..b6d26e7 100644
--- a/base/include/android-base/result.h
+++ b/base/include/android-base/result.h
@@ -90,6 +90,7 @@
   ResultError(T&& message, int code) : message_(std::forward<T>(message)), code_(code) {}
 
   template <typename T>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator android::base::expected<T, ResultError>() {
     return android::base::unexpected(ResultError(message_, code_));
   }
@@ -118,9 +119,11 @@
 class Error {
  public:
   Error() : errno_(0), append_errno_(false) {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Error(int errno_to_append) : errno_(errno_to_append), append_errno_(true) {}
 
   template <typename T>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator android::base::expected<T, ResultError>() {
     return android::base::unexpected(ResultError(str(), errno_));
   }
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 181e8ba..9180a06 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -86,6 +86,7 @@
 #define ZRAM_BACK_DEV   "/sys/block/zram0/backing_dev"
 
 #define SYSFS_EXT4_VERITY "/sys/fs/ext4/features/verity"
+#define SYSFS_EXT4_CASEFOLD "/sys/fs/ext4/features/casefold"
 
 // FIXME: this should be in system/extras
 #define EXT4_FEATURE_COMPAT_STABLE_INODES 0x0800
@@ -124,6 +125,7 @@
     FS_STAT_SET_RESERVED_BLOCKS_FAILED = 0x20000,
     FS_STAT_ENABLE_ENCRYPTION_FAILED = 0x40000,
     FS_STAT_ENABLE_VERITY_FAILED = 0x80000,
+    FS_STAT_ENABLE_CASEFOLD_FAILED = 0x100000,
 };
 
 static void log_fs_stat(const std::string& blk_device, int fs_stat) {
@@ -345,6 +347,7 @@
                        const struct ext4_super_block* sb, int* fs_stat) {
     bool has_quota = (sb->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0;
     bool want_quota = entry.fs_mgr_flags.quota;
+    bool want_projid = android::base::GetBoolProperty("ro.emulated_storage.projid", false);
 
     if (has_quota == want_quota) {
         return;
@@ -361,12 +364,16 @@
     if (want_quota) {
         LINFO << "Enabling quotas on " << blk_device;
         argv[1] = "-Oquota";
-        argv[2] = "-Qusrquota,grpquota";
+        // Once usr/grp unneeded, make just prjquota to save overhead
+        if (want_projid)
+            argv[2] = "-Qusrquota,grpquota,prjquota";
+        else
+            argv[2] = "-Qusrquota,grpquota";
         *fs_stat |= FS_STAT_QUOTA_ENABLED;
     } else {
         LINFO << "Disabling quotas on " << blk_device;
         argv[1] = "-O^quota";
-        argv[2] = "-Q^usrquota,^grpquota";
+        argv[2] = "-Q^usrquota,^grpquota,^prjquota";
     }
 
     if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
@@ -499,6 +506,42 @@
     }
 }
 
+// Enable casefold if needed.
+static void tune_casefold(const std::string& blk_device, const struct ext4_super_block* sb,
+                          int* fs_stat) {
+    bool has_casefold =
+            (sb->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_CASEFOLD)) != 0;
+    bool wants_casefold = android::base::GetBoolProperty("ro.emulated_storage.casefold", false);
+
+    if (!wants_casefold || has_casefold) return;
+
+    std::string casefold_support;
+    if (!android::base::ReadFileToString(SYSFS_EXT4_CASEFOLD, &casefold_support)) {
+        LERROR << "Failed to open " << SYSFS_EXT4_CASEFOLD;
+        return;
+    }
+
+    if (!(android::base::Trim(casefold_support) == "supported")) {
+        LERROR << "Current ext4 casefolding not supported by kernel";
+        return;
+    }
+
+    if (!tune2fs_available()) {
+        LERROR << "Unable to enable ext4 casefold on " << blk_device
+               << " because " TUNE2FS_BIN " is missing";
+        return;
+    }
+
+    LINFO << "Enabling ext4 casefold on " << blk_device;
+
+    const char* argv[] = {TUNE2FS_BIN, "-O", "casefold", "-E", "encoding=utf8", blk_device.c_str()};
+    if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
+        LERROR << "Failed to run " TUNE2FS_BIN " to enable "
+               << "ext4 casefold on " << blk_device;
+        *fs_stat |= FS_STAT_ENABLE_CASEFOLD_FAILED;
+    }
+}
+
 // Read the primary superblock from an f2fs filesystem.  On failure return
 // false.  If it's not an f2fs filesystem, also set FS_STAT_INVALID_MAGIC.
 #define F2FS_BLKSIZE 4096
@@ -596,6 +639,7 @@
             tune_reserved_size(blk_device, entry, &sb, &fs_stat);
             tune_encrypt(blk_device, entry, &sb, &fs_stat);
             tune_verity(blk_device, entry, &sb, &fs_stat);
+            tune_casefold(blk_device, &sb, &fs_stat);
         }
     }
 
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index 65c59bd..fd9a3eb 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -196,6 +196,7 @@
     { 00750, AID_ROOT,      AID_SHELL,     CAP_MASK_LONG(CAP_SETUID) |
                                            CAP_MASK_LONG(CAP_SETGID),
                                               "system/bin/simpleperf_app_runner" },
+    { 00755, AID_ROOT,      AID_ROOT,      0, "first_stage_ramdisk/system/bin/e2fsck" },
     // generic defaults
     { 00755, AID_ROOT,      AID_ROOT,      0, "bin/*" },
     { 00640, AID_ROOT,      AID_SHELL,     0, "fstab.*" },
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index f9a3df9..ff6b036 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -130,6 +130,7 @@
 #define AID_GSID 1074            /* GSI service daemon */
 #define AID_FSVERITY_CERT 1075   /* fs-verity key ownership in keystore */
 #define AID_CREDSTORE 1076       /* identity credential manager service */
+#define AID_EXTERNAL_STORAGE 1077 /* Full external storage access including USB OTG volumes */
 /* Changes to this file must be made in AOSP, *not* in internal branches. */
 
 #define AID_SHELL 2000 /* adb and debug shell user */
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 58c96b6..2e87b5b 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -39,6 +39,7 @@
     name: "liblog_headers",
     host_supported: true,
     vendor_available: true,
+    ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
     export_include_dirs: ["include"],
@@ -62,6 +63,7 @@
 cc_library {
     name: "liblog",
     host_supported: true,
+    ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
     srcs: liblog_sources,
diff --git a/libsparse/Android.bp b/libsparse/Android.bp
index 88146e9..135904b 100644
--- a/libsparse/Android.bp
+++ b/libsparse/Android.bp
@@ -3,6 +3,7 @@
 cc_library {
     name: "libsparse",
     host_supported: true,
+    ramdisk_available: true,
     recovery_available: true,
     unique_host_soname: true,
     srcs: [
diff --git a/libunwindstack/RegsArm64.cpp b/libunwindstack/RegsArm64.cpp
index 1df1dff..00b3367 100644
--- a/libunwindstack/RegsArm64.cpp
+++ b/libunwindstack/RegsArm64.cpp
@@ -100,8 +100,8 @@
   fn("x27", regs_[ARM64_REG_R27]);
   fn("x28", regs_[ARM64_REG_R28]);
   fn("x29", regs_[ARM64_REG_R29]);
-  fn("sp", regs_[ARM64_REG_SP]);
   fn("lr", regs_[ARM64_REG_LR]);
+  fn("sp", regs_[ARM64_REG_SP]);
   fn("pc", regs_[ARM64_REG_PC]);
   fn("pst", regs_[ARM64_REG_PSTATE]);
 }
@@ -110,10 +110,10 @@
   arm64_user_regs* user = reinterpret_cast<arm64_user_regs*>(remote_data);
 
   RegsArm64* regs = new RegsArm64();
-  memcpy(regs->RawData(), &user->regs[0], (ARM64_REG_R31 + 1) * sizeof(uint64_t));
+  memcpy(regs->RawData(), &user->regs[0], (ARM64_REG_R30 + 1) * sizeof(uint64_t));
   uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData());
-  reg_data[ARM64_REG_PC] = user->pc;
   reg_data[ARM64_REG_SP] = user->sp;
+  reg_data[ARM64_REG_PC] = user->pc;
   reg_data[ARM64_REG_PSTATE] = user->pstate;
   return regs;
 }
diff --git a/libunwindstack/tests/RegsIterateTest.cpp b/libunwindstack/tests/RegsIterateTest.cpp
index bc95851..47e605a 100644
--- a/libunwindstack/tests/RegsIterateTest.cpp
+++ b/libunwindstack/tests/RegsIterateTest.cpp
@@ -111,8 +111,8 @@
   result.push_back({"x27", ARM64_REG_R27});
   result.push_back({"x28", ARM64_REG_R28});
   result.push_back({"x29", ARM64_REG_R29});
-  result.push_back({"sp", ARM64_REG_SP});
   result.push_back({"lr", ARM64_REG_LR});
+  result.push_back({"sp", ARM64_REG_SP});
   result.push_back({"pc", ARM64_REG_PC});
   result.push_back({"pst", ARM64_REG_PSTATE});
   return result;
diff --git a/property_service/libpropertyinfoparser/Android.bp b/property_service/libpropertyinfoparser/Android.bp
index ac802b5..108d15a 100644
--- a/property_service/libpropertyinfoparser/Android.bp
+++ b/property_service/libpropertyinfoparser/Android.bp
@@ -2,6 +2,7 @@
     name: "libpropertyinfoparser",
     host_supported: true,
     vendor_available: true,
+    ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
     srcs: ["property_info_parser.cpp"],
diff --git a/rootdir/init.rc b/rootdir/init.rc
index e575808..7d27c3a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -165,7 +165,7 @@
     mkdir /mnt/secure/asec 0700 root root
     mkdir /mnt/asec 0755 root system
     mkdir /mnt/obb 0755 root system
-    mkdir /mnt/media_rw 0750 root media_rw
+    mkdir /mnt/media_rw 0750 root external_storage
     mkdir /mnt/user 0755 root root
     mkdir /mnt/user/0 0755 root root
     mkdir /mnt/user/0/self 0755 root root