diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index 272190e33..d26f2d519 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -307,7 +307,7 @@ static bool read_ext4_superblock(const std::string& blk_device, struct ext4_supe return false; } - if (pread(fd, sb, sizeof(*sb), 1024) != sizeof(*sb)) { + if (TEMP_FAILURE_RETRY(pread(fd, sb, sizeof(*sb), 1024)) != sizeof(*sb)) { PERROR << "Can't read '" << blk_device << "' superblock"; return false; } @@ -326,6 +326,17 @@ static bool read_ext4_superblock(const std::string& blk_device, struct ext4_supe return true; } +// exported silent version of the above that just answer the question is_ext4 +bool fs_mgr_is_ext4(const std::string& blk_device) { + android::base::ErrnoRestorer restore; + android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(blk_device.c_str(), O_RDONLY | O_CLOEXEC))); + if (fd < 0) return false; + ext4_super_block sb; + if (TEMP_FAILURE_RETRY(pread(fd, &sb, sizeof(sb), 1024)) != sizeof(sb)) return false; + if (!is_ext4_superblock_valid(&sb)) return false; + return true; +} + // Some system images do not have tune2fs for licensing reasons. // Detect these and skip running it. static bool tune2fs_available(void) { @@ -494,11 +505,12 @@ static bool read_f2fs_superblock(const std::string& blk_device, int* fs_stat) { return false; } - if (pread(fd, &sb1, sizeof(sb1), F2FS_SUPER_OFFSET) != sizeof(sb1)) { + if (TEMP_FAILURE_RETRY(pread(fd, &sb1, sizeof(sb1), F2FS_SUPER_OFFSET)) != sizeof(sb1)) { PERROR << "Can't read '" << blk_device << "' superblock1"; return false; } - if (pread(fd, &sb2, sizeof(sb2), F2FS_BLKSIZE + F2FS_SUPER_OFFSET) != sizeof(sb2)) { + if (TEMP_FAILURE_RETRY(pread(fd, &sb2, sizeof(sb2), F2FS_BLKSIZE + F2FS_SUPER_OFFSET)) != + sizeof(sb2)) { PERROR << "Can't read '" << blk_device << "' superblock2"; return false; } @@ -511,6 +523,23 @@ static bool read_f2fs_superblock(const std::string& blk_device, int* fs_stat) { return true; } +// exported silent version of the above that just answer the question is_f2fs +bool fs_mgr_is_f2fs(const std::string& blk_device) { + android::base::ErrnoRestorer restore; + android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(blk_device.c_str(), O_RDONLY | O_CLOEXEC))); + if (fd < 0) return false; + __le32 sb; + if (TEMP_FAILURE_RETRY(pread(fd, &sb, sizeof(sb), F2FS_SUPER_OFFSET)) != sizeof(sb)) { + return false; + } + if (sb == cpu_to_le32(F2FS_SUPER_MAGIC)) return true; + if (TEMP_FAILURE_RETRY(pread(fd, &sb, sizeof(sb), F2FS_BLKSIZE + F2FS_SUPER_OFFSET)) != + sizeof(sb)) { + return false; + } + return sb == cpu_to_le32(F2FS_SUPER_MAGIC); +} + // // Prepare the filesystem on the given block device to be mounted. // diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index e61f58838..dea484406 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -543,6 +543,10 @@ bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::s if (!fs_mgr_rw_access(device_path)) return false; } + auto f2fs = fs_mgr_is_f2fs(device_path); + auto ext4 = fs_mgr_is_ext4(device_path); + if (!f2fs && !ext4) return false; + if (setfscreatecon(kOverlayfsFileContext)) { PERROR << "setfscreatecon " << kOverlayfsFileContext; } @@ -554,6 +558,8 @@ bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::s entry.blk_device = device_path; entry.mount_point = kScratchMountPoint; entry.fs_type = mnt_type; + if ((mnt_type == "f2fs") && !f2fs) entry.fs_type = "ext4"; + if ((mnt_type == "ext4") && !ext4) entry.fs_type = "f2fs"; entry.flags = MS_RELATIME; if (readonly) { entry.flags |= MS_RDONLY; @@ -563,12 +569,13 @@ bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::s auto save_errno = errno; auto mounted = fs_mgr_do_mount_one(entry) == 0; if (!mounted) { - if (mnt_type == "f2fs") { + if ((entry.fs_type == "f2fs") && ext4) { entry.fs_type = "ext4"; - } else { + mounted = fs_mgr_do_mount_one(entry) == 0; + } else if ((entry.fs_type == "ext4") && f2fs) { entry.fs_type = "f2fs"; + mounted = fs_mgr_do_mount_one(entry) == 0; } - mounted = fs_mgr_do_mount_one(entry) == 0; if (!mounted) save_errno = errno; } setfscreatecon(nullptr); diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index 166c32b30..11602ea61 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -100,3 +100,6 @@ bool fs_mgr_is_device_unlocked(); const std::string& get_android_dt_dir(); bool is_dt_compatible(); int load_verity_state(const android::fs_mgr::FstabEntry& entry, int* mode); + +bool fs_mgr_is_ext4(const std::string& blk_device); +bool fs_mgr_is_f2fs(const std::string& blk_device); diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh index bd5a4fe58..ec6eb5252 100755 --- a/fs_mgr/tests/adb-remount-test.sh +++ b/fs_mgr/tests/adb-remount-test.sh @@ -951,7 +951,7 @@ echo "${GREEN}[ RUN ]${NORMAL} reboot to confirm content persistent" >&2 adb_reboot && adb_wait 2m || - die "reboot after override content added failed" + die "reboot after override content added failed `usb_status`" if ${overlayfs_needed}; then D=`adb_su df -k