summaryrefslogtreecommitdiff
path: root/fs_mgr/fs_mgr.cpp
diff options
context:
space:
mode:
authorJustin DeMartino <jjdemartino@google.com>2020-10-14 19:39:53 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2020-10-14 19:39:53 +0000
commit0d11af03e43f110b0bb160f7e20436d0043e3038 (patch)
tree48f8bcca856276ec73a86dd3fb26143d3ca64578 /fs_mgr/fs_mgr.cpp
parent075666ebd0dee8d0c4a2efa54f7c324a3f67ee2a (diff)
parenta6c01e4e98d2b343dcecfc99611e2e6250c730db (diff)
Merge changes from topic "SP1A.200921.001" into s-keystone-qcom-dev
* changes: fs_mgr: adb-remount-test.sh: filter out more administrivia mounts. Merge SP1A.200921.001 Change-Id: I90b97c4e9fb10b1f45e74def404823eed5b1aaa8
Diffstat (limited to 'fs_mgr/fs_mgr.cpp')
-rwxr-xr-xfs_mgr/fs_mgr.cpp89
1 files changed, 42 insertions, 47 deletions
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index a7087e7af..a8ba68c3c 100755
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -308,13 +308,10 @@ static bool is_ext4_superblock_valid(const struct ext4_super_block* es) {
return true;
}
-static bool needs_block_encryption(const FstabEntry& entry);
-static bool should_use_metadata_encryption(const FstabEntry& entry);
-
// Read the primary superblock from an ext4 filesystem. On failure return
// false. If it's not an ext4 filesystem, also set FS_STAT_INVALID_MAGIC.
-static bool read_ext4_superblock(const std::string& blk_device, const FstabEntry& entry,
- struct ext4_super_block* sb, int* fs_stat) {
+static bool read_ext4_superblock(const std::string& blk_device, struct ext4_super_block* sb,
+ int* fs_stat) {
android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(blk_device.c_str(), O_RDONLY | O_CLOEXEC)));
if (fd < 0) {
@@ -331,29 +328,7 @@ static bool read_ext4_superblock(const std::string& blk_device, const FstabEntry
LINFO << "Invalid ext4 superblock on '" << blk_device << "'";
// not a valid fs, tune2fs, fsck, and mount will all fail.
*fs_stat |= FS_STAT_INVALID_MAGIC;
-
- bool encrypted = should_use_metadata_encryption(entry) || needs_block_encryption(entry);
- if (entry.mount_point == "/data" &&
- (!encrypted || android::base::StartsWith(blk_device, "/dev/block/dm-"))) {
- // try backup superblock, if main superblock is corrupted
- for (unsigned int blocksize = EXT4_MIN_BLOCK_SIZE; blocksize <= EXT4_MAX_BLOCK_SIZE;
- blocksize *= 2) {
- uint64_t superblock = blocksize * 8;
- if (blocksize == EXT4_MIN_BLOCK_SIZE) superblock++;
-
- if (TEMP_FAILURE_RETRY(pread(fd, sb, sizeof(*sb), superblock * blocksize)) !=
- sizeof(*sb)) {
- PERROR << "Can't read '" << blk_device << "' superblock";
- return false;
- }
- if (is_ext4_superblock_valid(sb) &&
- (1 << (10 + sb->s_log_block_size) == blocksize)) {
- *fs_stat &= ~FS_STAT_INVALID_MAGIC;
- break;
- }
- }
- }
- if (*fs_stat & FS_STAT_INVALID_MAGIC) return false;
+ return false;
}
*fs_stat |= FS_STAT_IS_EXT4;
LINFO << "superblock s_max_mnt_count:" << sb->s_max_mnt_count << "," << blk_device;
@@ -553,13 +528,13 @@ static void tune_verity(const std::string& blk_device, const FstabEntry& entry,
}
// Enable casefold if needed.
-static void tune_casefold(const std::string& blk_device, const struct ext4_super_block* sb,
- int* fs_stat) {
+static void tune_casefold(const std::string& blk_device, const FstabEntry& entry,
+ const struct ext4_super_block* sb, int* fs_stat) {
bool has_casefold = (sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_CASEFOLD)) != 0;
bool wants_casefold =
android::base::GetBoolProperty("external_storage.casefold.enabled", false);
- if (!wants_casefold || has_casefold) return;
+ if (entry.mount_point != "data" || !wants_casefold || has_casefold ) return;
std::string casefold_support;
if (!android::base::ReadFileToString(SYSFS_EXT4_CASEFOLD, &casefold_support)) {
@@ -614,7 +589,7 @@ static void tune_metadata_csum(const std::string& blk_device, const FstabEntry&
LINFO << "Enabling ext4 metadata_csum on " << blk_device;
- // requires to give last_fsck_time to current to avoid insane time.
+ // Must give `-T now` to prevent last_fsck_time from growing too large,
// otherwise, tune2fs won't enable metadata_csum.
const char* tune2fs_args[] = {TUNE2FS_BIN, "-O", "metadata_csum,64bit,extent",
"-T", "now", blk_device.c_str()};
@@ -694,7 +669,7 @@ static int prepare_fs_for_mount(const std::string& blk_device, const FstabEntry&
if (is_extfs(entry.fs_type)) {
struct ext4_super_block sb;
- if (read_ext4_superblock(blk_device, entry, &sb, &fs_stat)) {
+ if (read_ext4_superblock(blk_device, &sb, &fs_stat)) {
if ((sb.s_feature_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) != 0 ||
(sb.s_state & EXT4_VALID_FS) == 0) {
LINFO << "Filesystem on " << blk_device << " was not cleanly shutdown; "
@@ -724,11 +699,11 @@ static int prepare_fs_for_mount(const std::string& blk_device, const FstabEntry&
entry.fs_mgr_flags.fs_verity || entry.fs_mgr_flags.ext_meta_csum)) {
struct ext4_super_block sb;
- if (read_ext4_superblock(blk_device, entry, &sb, &fs_stat)) {
+ if (read_ext4_superblock(blk_device, &sb, &fs_stat)) {
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);
+ tune_casefold(blk_device, entry, &sb, &fs_stat);
tune_metadata_csum(blk_device, entry, &sb, &fs_stat);
}
}
@@ -1028,6 +1003,19 @@ static int handle_encryptable(const FstabEntry& entry) {
}
}
+static void set_type_property(int status) {
+ switch (status) {
+ case FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED:
+ SetProperty("ro.crypto.type", "block");
+ break;
+ case FS_MGR_MNTALL_DEV_FILE_ENCRYPTED:
+ case FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED:
+ case FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION:
+ SetProperty("ro.crypto.type", "file");
+ break;
+ }
+}
+
static bool call_vdc(const std::vector<std::string>& args, int* ret) {
std::vector<char const*> argv;
argv.emplace_back("/system/bin/vdc");
@@ -1165,10 +1153,9 @@ class CheckpointManager {
// metadata-encrypted device with smaller blocks, we must not change this for
// devices shipped with Q or earlier unless they explicitly selected dm-default-key
// v2
- constexpr unsigned int pre_gki_level = __ANDROID_API_Q__;
unsigned int options_format_version = android::base::GetUintProperty<unsigned int>(
"ro.crypto.dm_default_key.options_format.version",
- (android::fscrypt::GetFirstApiLevel() <= pre_gki_level ? 1 : 2));
+ (android::fscrypt::GetFirstApiLevel() <= __ANDROID_API_Q__ ? 1 : 2));
if (options_format_version > 1) {
bowTarget->SetBlockSize(4096);
}
@@ -1336,7 +1323,7 @@ static bool IsMountPointMounted(const std::string& mount_point) {
// When multiple fstab records share the same mount_point, it will try to mount each
// one in turn, and ignore any duplicates after a first successful mount.
// Returns -1 on error, and FS_MGR_MNTALL_* otherwise.
-int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
+MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
int error_count = 0;
CheckpointManager checkpoint_manager;
@@ -1344,8 +1331,9 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
bool is_ffbm = false;
AvbUniquePtr avb_handle(nullptr);
+ bool userdata_mounted = false;
if (fstab->empty()) {
- return FS_MGR_MNTALL_FAIL;
+ return {FS_MGR_MNTALL_FAIL, userdata_mounted};
}
/**get boot mode*/
property_get("ro.bootmode", propbuf, "");
@@ -1393,7 +1381,7 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
}
// Terrible hack to make it possible to remount /data.
- // TODO: refact fs_mgr_mount_all and get rid of this.
+ // TODO: refactor fs_mgr_mount_all and get rid of this.
if (mount_mode == MOUNT_MODE_ONLY_USERDATA && current_entry.mount_point != "/data") {
continue;
}
@@ -1429,7 +1417,8 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
avb_handle = AvbHandle::Open();
if (!avb_handle) {
LERROR << "Failed to open AvbHandle";
- return FS_MGR_MNTALL_FAIL;
+ set_type_property(encryptable);
+ return {FS_MGR_MNTALL_FAIL, userdata_mounted};
}
}
if (avb_handle->SetUpAvbHashtree(&current_entry, true /* wait_for_verity_dev */) ==
@@ -1471,7 +1460,7 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
if (status == FS_MGR_MNTALL_FAIL) {
// Fatal error - no point continuing.
- return status;
+ return {status, userdata_mounted};
}
if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
@@ -1485,11 +1474,15 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
attempted_entry.mount_point},
nullptr)) {
LERROR << "Encryption failed";
- return FS_MGR_MNTALL_FAIL;
+ set_type_property(encryptable);
+ return {FS_MGR_MNTALL_FAIL, userdata_mounted};
}
}
}
+ if (current_entry.mount_point == "/data") {
+ userdata_mounted = true;
+ }
// Success! Go get the next one.
continue;
}
@@ -1588,14 +1581,16 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
}
}
+ set_type_property(encryptable);
+
#if ALLOW_ADBD_DISABLE_VERITY == 1 // "userdebug" build
fs_mgr_overlayfs_mount_all(fstab);
#endif
if (error_count) {
- return FS_MGR_MNTALL_FAIL;
+ return {FS_MGR_MNTALL_FAIL, userdata_mounted};
} else {
- return encryptable;
+ return {encryptable, userdata_mounted};
}
}
@@ -1817,8 +1812,8 @@ int fs_mgr_remount_userdata_into_checkpointing(Fstab* fstab) {
}
LINFO << "Remounting /data";
// TODO(b/143970043): remove this hack after fs_mgr_mount_all is refactored.
- int result = fs_mgr_mount_all(fstab, MOUNT_MODE_ONLY_USERDATA);
- return result == FS_MGR_MNTALL_FAIL ? -1 : 0;
+ auto result = fs_mgr_mount_all(fstab, MOUNT_MODE_ONLY_USERDATA);
+ return result.code == FS_MGR_MNTALL_FAIL ? -1 : 0;
}
return 0;
}