diff options
author | Keun-young Park <keunyoung@google.com> | 2017-04-11 18:59:56 -0700 |
---|---|---|
committer | Keun-young Park <keunyoung@google.com> | 2017-04-13 17:11:11 -0700 |
commit | 6000a3f65720757279707193d940c0942abfe9c7 (patch) | |
tree | 47236abe90593f14ff2d8d0e6ba93a796b485938 /fs_mgr | |
parent | 659b78ed10fb9116e5dbbf6971fc2e36ca88a465 (diff) | |
download | core-6000a3f65720757279707193d940c0942abfe9c7.tar.gz core-6000a3f65720757279707193d940c0942abfe9c7.tar.bz2 core-6000a3f65720757279707193d940c0942abfe9c7.zip |
check ext4 magic before running next steps
- mount, e2fsck, tune2fs will all fail if magic number does not match.
- mismatch always happen for FDE and is wasting boot-up time to try
all and fail always.
- skip mount steps if it has invalid magic number and do not record
fs_stat either.
- For ext4 fs with corrupt superblock, e2fsck refuses to do anything if
superblock magic is invalid. So simply running e2fsck does not help
anyway.
bug: 36231950
Test: reboot ane check fs_mgr log from dmesg
Change-Id: I9ad9e0cd30fd074b3bbf8f450bd401b133d5771a
Diffstat (limited to 'fs_mgr')
-rw-r--r-- | fs_mgr/fs_mgr.cpp | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index 78d0c070f..a6e13442d 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -44,6 +44,7 @@ #include <ext4_utils/wipe.h> #include <linux/fs.h> #include <linux/loop.h> +#include <linux/magic.h> #include <logwrap/logwrap.h> #include <private/android_logger.h> // for __android_log_is_debuggable() @@ -67,17 +68,18 @@ // record fs stat enum FsStatFlags { - FS_STAT_IS_EXT4 = 0x0001, + FS_STAT_IS_EXT4 = 0x0001, FS_STAT_NEW_IMAGE_VERSION = 0x0002, - FS_STAT_E2FSCK_F_ALWAYS = 0x0004, - FS_STAT_UNCLEAN_SHUTDOWN = 0x0008, - FS_STAT_QUOTA_ENABLED = 0x0010, - FS_STAT_TUNE2FS_FAILED = 0x0020, - FS_STAT_RO_MOUNT_FAILED = 0x0040, + FS_STAT_E2FSCK_F_ALWAYS = 0x0004, + FS_STAT_UNCLEAN_SHUTDOWN = 0x0008, + FS_STAT_QUOTA_ENABLED = 0x0010, + FS_STAT_TUNE2FS_FAILED = 0x0020, + FS_STAT_RO_MOUNT_FAILED = 0x0040, FS_STAT_RO_UNMOUNT_FAILED = 0x0080, FS_STAT_FULL_MOUNT_FAILED = 0x0100, - FS_STAT_E2FSCK_FAILED = 0x0200, - FS_STAT_E2FSCK_FS_FIXED = 0x0400, + FS_STAT_E2FSCK_FAILED = 0x0200, + FS_STAT_E2FSCK_FS_FIXED = 0x0400, + FS_STAT_EXT4_INVALID_MAGIC = 0x0800, }; /* @@ -136,6 +138,9 @@ static void check_fs(const char *blk_device, char *fs_type, char *target, int *f /* Check for the types of filesystems we know how to check */ if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) { + if (*fs_stat & FS_STAT_EXT4_INVALID_MAGIC) { // will fail, so do not try + return; + } /* * First try to mount and unmount the filesystem. We do this because * the kernel is more efficient than e2fsck in running the journal and @@ -282,6 +287,11 @@ static int do_quota_with_shutdown_check(char *blk_device, char *fs_type, PERROR << "Can't read '" << blk_device << "' super block"; return force_check; } + if (sb.s_magic != EXT4_SUPER_MAGIC) { + LINFO << "Invalid ext4 magic:0x" << std::hex << sb.s_magic << "," << blk_device; + *fs_stat |= FS_STAT_EXT4_INVALID_MAGIC; + return 0; // not a valid fs, tune2fs, fsck, and mount will all fail. + } *fs_stat |= FS_STAT_IS_EXT4; LINFO << "superblock s_max_mnt_count:" << sb.s_max_mnt_count << "," << blk_device; if (sb.s_max_mnt_count == 0xffff) { // -1 (int16) in ext2, but uint16 in ext4 @@ -542,7 +552,13 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_ int force_check = do_quota_with_shutdown_check(fstab->recs[i].blk_device, fstab->recs[i].fs_type, &fstab->recs[i], &fs_stat); - + if (fs_stat & FS_STAT_EXT4_INVALID_MAGIC) { + LERROR << __FUNCTION__ << "(): skipping mount, invalid ext4, mountpoint=" + << fstab->recs[i].mount_point << " rec[" << i + << "].fs_type=" << fstab->recs[i].fs_type; + mount_errno = EINVAL; // continue bootup for FDE + continue; + } if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) { check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point, &fs_stat); |