Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2f2263b authored by Kelvin Zhang's avatar Kelvin Zhang
Browse files

Skip F2FS formatting for dev option enabled devices

F2FS does not support page_size!=block_size configuration, and
dev option devices need to toggle between 4K/16K mode, hence F2FS
requires a data wipe every time page size changes. This is inconveinent,
skip F2FS formatting instead.

Test: th
Bug: 353436188
Change-Id: Ic33dbc39c16db3aee4c47349a9693aacec240de8
parent ad6ec1e3
Loading
Loading
Loading
Loading
+46 −18
Original line number Diff line number Diff line
@@ -38,10 +38,8 @@

#include <array>
#include <chrono>
#include <functional>
#include <map>
#include <memory>
#include <numeric>
#include <string>
#include <string_view>
#include <thread>
@@ -66,6 +64,7 @@
#include <fs_mgr/file_wait.h>
#include <fs_mgr_overlayfs.h>
#include <fscrypt/fscrypt.h>
#include <fstab/fstab.h>
#include <libdm/dm.h>
#include <libdm/loop_control.h>
#include <liblp/metadata_format.h>
@@ -138,8 +137,8 @@ enum FsStatFlags {
static void log_fs_stat(const std::string& blk_device, int fs_stat) {
    std::string msg =
            android::base::StringPrintf("\nfs_stat,%s,0x%x\n", blk_device.c_str(), fs_stat);
    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(FSCK_LOG_FILE, O_WRONLY | O_CLOEXEC |
                                                        O_APPEND | O_CREAT, 0664)));
    android::base::unique_fd fd(TEMP_FAILURE_RETRY(
            open(FSCK_LOG_FILE, O_WRONLY | O_CLOEXEC | O_APPEND | O_CREAT, 0664)));
    if (fd == -1 || !android::base::WriteStringToFd(msg, fd)) {
        LWARNING << __FUNCTION__ << "() cannot log " << msg;
    }
@@ -1430,6 +1429,34 @@ bool WasMetadataEncryptionInterrupted(const FstabEntry& entry) {
    return access(fs_mgr_metadata_encryption_in_progress_file_name(entry).c_str(), R_OK) == 0;
}

FstabEntry* LocateFormattableEntry(FstabEntry* const begin, FstabEntry* const end) {
    const bool dev_option_enabled =
            android::base::GetBoolProperty("ro.product.build.16k_page.enabled", false);
    FstabEntry* f2fs_entry = nullptr;
    for (auto iter = begin; iter->blk_device == begin->blk_device && iter < end; iter++) {
        if (iter->fs_mgr_flags.formattable) {
            if (getpagesize() != 4096 && is_f2fs(iter->fs_type) && dev_option_enabled) {
                f2fs_entry = iter;
                continue;
            }
            if (f2fs_entry) {
                LOG(INFO) << "Skipping F2FS format for block device " << iter->blk_device << " @ "
                          << iter->mount_point
                          << " in non-4K mode for dev option enabled devices, "
                             "as these devices need to toggle between 4K/16K mode, and F2FS does "
                             "not support page_size != block_size configuration.";
            }
            return iter;
        }
    }
    if (f2fs_entry) {
        LOG(INFO) << "Using F2FS for " << f2fs_entry->blk_device << " @ " << f2fs_entry->mount_point
                  << " even though we are in non-4K mode. Device might require a data wipe after "
                     "going back to 4K mode, as F2FS does not support page_size != block_size";
    }
    return f2fs_entry;
}

// 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.
@@ -1540,8 +1567,8 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
            }
        }

        int last_idx_inspected;
        int top_idx = i;
        int last_idx_inspected = -1;
        const int top_idx = i;
        int attempted_idx = -1;

        bool encryption_interrupted = WasMetadataEncryptionInterrupted(current_entry);
@@ -1591,7 +1618,8 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
            // Success!  Go get the next one.
            continue;
        }

        auto formattable_entry =
                LocateFormattableEntry(fstab->data() + top_idx, fstab->data() + fstab->size());
        // Mounting failed, understand why and retry.
        wiped = partition_wiped(current_entry.blk_device.c_str());
        if (mount_errno != EBUSY && mount_errno != EACCES &&
@@ -1619,12 +1647,12 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
                encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED;
                set_type_property(encryptable);

                if (!call_vdc({"cryptfs", "encryptFstab", current_entry.blk_device,
                               current_entry.mount_point, "true" /* shouldFormat */,
                               current_entry.fs_type,
                               current_entry.fs_mgr_flags.is_zoned ? "true" : "false",
                               std::to_string(current_entry.length),
                               android::base::Join(current_entry.user_devices, ' ')},
                if (!call_vdc({"cryptfs", "encryptFstab", formattable_entry->blk_device,
                               formattable_entry->mount_point, "true" /* shouldFormat */,
                               formattable_entry->fs_type,
                               formattable_entry->fs_mgr_flags.is_zoned ? "true" : "false",
                               std::to_string(formattable_entry->length),
                               android::base::Join(formattable_entry->user_devices, ' ')},
                              nullptr)) {
                    LERROR << "Encryption failed";
                } else {
@@ -1633,7 +1661,7 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
                }
            }

            if (fs_mgr_do_format(current_entry) == 0) {
            if (fs_mgr_do_format(*formattable_entry) == 0) {
                // Let's replay the mount actions.
                i = top_idx - 1;
                continue;