diff options
author | Justin DeMartino <jjdemartino@google.com> | 2020-10-14 19:39:53 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-10-14 19:39:53 +0000 |
commit | 0d11af03e43f110b0bb160f7e20436d0043e3038 (patch) | |
tree | 48f8bcca856276ec73a86dd3fb26143d3ca64578 /fs_mgr/fs_mgr.cpp | |
parent | 075666ebd0dee8d0c4a2efa54f7c324a3f67ee2a (diff) | |
parent | a6c01e4e98d2b343dcecfc99611e2e6250c730db (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-x | fs_mgr/fs_mgr.cpp | 89 |
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(¤t_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; } |