summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2020-08-04 11:11:13 -0700
committerHung-ying Tyan <tyanh@google.com>2020-08-06 15:52:51 +0800
commit7a6e6204470e81c15a534cc0cac47939a1b3b1bc (patch)
treea409f21894f69e06a2e399bde1755fa528417a21
parent3a7a8b871aae47ead363e6493a01d2e26bc2a2f3 (diff)
downloadcore-7a6e6204470e81c15a534cc0cac47939a1b3b1bc.tar.gz
fs_mgr: Revert "Try to recover corrupted ext4 /data with backup superblock"
This reverts commit 72abd7b246f733e5f417e2bc529c9b482c4a778b (change Ia39af3340c0e241f62557b7c2cc8b800443342f9). When vold enables either FDE or metadata encryption, it encrypts the filesystem in-place. Unfortunately, due to a bug, for ext4 filesystems it hasn't been encrypting the backup superblocks. Also, in read_ext4_superblock(), the check for StartsWith(blk_device, "/dev/block/dm-") can return true even if the encryption mapping hasn't been added yet, since when a GSI image is booted the userdata block device is a logical volume using dm-linear. The result is that read_ext4_superblock() can recognize a backup superblock when the encryption mapping hasn't been added yet, causing e2fsck to run without the encryption mapping and corrupt the filesystem. https://android-review.googlesource.com/c/platform/system/vold/+/1385029 will fix this for new or factory-reset devices. However, there probably are many existing devices that already have their backup superblocks unencrypted. Therefore, the EncryptInPlace fix isn't enough and we have to revert the change that started using the backup superblocks too. Bug: 161871210 Bug: 162479411 Change-Id: I279f84c072bc6c8d3e251a5e95c78f8d6c0d50ba Merged-In: I279f84c072bc6c8d3e251a5e95c78f8d6c0d50ba (cherry picked from dc3e897a881291c7803dd1fc517915952396dd98)
-rw-r--r--fs_mgr/fs_mgr.cpp35
1 files changed, 5 insertions, 30 deletions
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 956147198..30db652ed 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -301,13 +301,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) {
@@ -324,29 +321,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;
@@ -688,7 +663,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; "
@@ -718,7 +693,7 @@ 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);