/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "fs_mgr.h"

#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/swap.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#include <chrono>
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <thread>
#include <utility>
#include <vector>

#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <cutils/android_filesystem_config.h>
#include <cutils/android_reboot.h>
#include <cutils/partition_utils.h>
#include <cutils/properties.h>
#include <ext4_utils/ext4.h>
#include <ext4_utils/ext4_sb.h>
#include <ext4_utils/ext4_utils.h>
#include <ext4_utils/wipe.h>
#include <fs_avb/fs_avb.h>
#include <fs_mgr/file_wait.h>
#include <fs_mgr_overlayfs.h>
#include <fscrypt/fscrypt.h>
#include <libdm/dm.h>
#include <libdm/loop_control.h>
#include <liblp/metadata_format.h>
#include <linux/fs.h>
#include <linux/loop.h>
#include <linux/magic.h>
#include <log/log_properties.h>
#include <logwrap/logwrap.h>

#include "fs_mgr_priv.h"

#define KEY_LOC_PROP   "ro.crypto.keyfile.userdata"
#define KEY_IN_FOOTER  "footer"

#define E2FSCK_BIN      "/system/bin/e2fsck"
#define F2FS_FSCK_BIN   "/system/bin/fsck.f2fs"
#define MKSWAP_BIN      "/system/bin/mkswap"
#define TUNE2FS_BIN     "/system/bin/tune2fs"
#define RESIZE2FS_BIN "/system/bin/resize2fs"

#define FSCK_LOG_FILE   "/dev/fscklogs/log"

#define ZRAM_CONF_DEV   "/sys/block/zram0/disksize"
#define ZRAM_CONF_MCS   "/sys/block/zram0/max_comp_streams"
#define ZRAM_BACK_DEV   "/sys/block/zram0/backing_dev"

#define SYSFS_EXT4_VERITY "/sys/fs/ext4/features/verity"
#define SYSFS_EXT4_CASEFOLD "/sys/fs/ext4/features/casefold"

// FIXME: this should be in system/extras
#define EXT4_FEATURE_COMPAT_STABLE_INODES 0x0800

#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))

using android::base::Basename;
using android::base::GetBoolProperty;
using android::base::GetUintProperty;
using android::base::Realpath;
using android::base::SetProperty;
using android::base::StartsWith;
using android::base::Timer;
using android::base::unique_fd;
using android::dm::DeviceMapper;
using android::dm::DmDeviceState;
using android::dm::DmTargetLinear;
using android::dm::LoopControl;

// Realistically, this file should be part of the android::fs_mgr namespace;
using namespace android::fs_mgr;

using namespace std::literals;

// record fs stat
enum FsStatFlags {
    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_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_INVALID_MAGIC = 0x0800,
    FS_STAT_TOGGLE_QUOTAS_FAILED = 0x10000,
    FS_STAT_SET_RESERVED_BLOCKS_FAILED = 0x20000,
    FS_STAT_ENABLE_ENCRYPTION_FAILED = 0x40000,
    FS_STAT_ENABLE_VERITY_FAILED = 0x80000,
    FS_STAT_ENABLE_CASEFOLD_FAILED = 0x100000,
    FS_STAT_ENABLE_METADATA_CSUM_FAILED = 0x200000,
};

static void log_fs_stat(const std::string& blk_device, int fs_stat) {
    if ((fs_stat & FS_STAT_IS_EXT4) == 0) return; // only log ext4
    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)));
    if (fd == -1 || !android::base::WriteStringToFd(msg, fd)) {
        LWARNING << __FUNCTION__ << "() cannot log " << msg;
    }
}

static bool is_extfs(const std::string& fs_type) {
    return fs_type == "ext4" || fs_type == "ext3" || fs_type == "ext2";
}

static bool is_f2fs(const std::string& fs_type) {
    return fs_type == "f2fs";
}

static std::string realpath(const std::string& blk_device) {
    std::string real_path;
    if (!Realpath(blk_device, &real_path)) {
        real_path = blk_device;
    }
    return real_path;
}

static bool should_force_check(int fs_stat) {
    return fs_stat &
           (FS_STAT_E2FSCK_F_ALWAYS | FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED |
            FS_STAT_RO_MOUNT_FAILED | FS_STAT_RO_UNMOUNT_FAILED | FS_STAT_FULL_MOUNT_FAILED |
            FS_STAT_E2FSCK_FAILED | FS_STAT_TOGGLE_QUOTAS_FAILED |
            FS_STAT_SET_RESERVED_BLOCKS_FAILED | FS_STAT_ENABLE_ENCRYPTION_FAILED);
}

static void check_fs(const std::string& blk_device, const std::string& fs_type,
                     const std::string& target, int* fs_stat) {
    int status;
    int ret;
    long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
    auto tmpmnt_opts = "errors=remount-ro"s;
    const char* e2fsck_argv[] = {E2FSCK_BIN, "-y", blk_device.c_str()};
    const char* e2fsck_forced_argv[] = {E2FSCK_BIN, "-f", "-y", blk_device.c_str()};

    if (*fs_stat & FS_STAT_INVALID_MAGIC) {  // will fail, so do not try
        return;
    }

    Timer t;
    /* Check for the types of filesystems we know how to check */
    if (is_extfs(fs_type)) {
        /*
         * First try to mount and unmount the filesystem.  We do this because
         * the kernel is more efficient than e2fsck in running the journal and
         * processing orphaned inodes, and on at least one device with a
         * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes
         * to do what the kernel does in about a second.
         *
         * After mounting and unmounting the filesystem, run e2fsck, and if an
         * error is recorded in the filesystem superblock, e2fsck will do a full
         * check.  Otherwise, it does nothing.  If the kernel cannot mount the
         * filesytsem due to an error, e2fsck is still run to do a full check
         * fix the filesystem.
         */
        if (!(*fs_stat & FS_STAT_FULL_MOUNT_FAILED)) {  // already tried if full mount failed
            errno = 0;
            if (fs_type == "ext4") {
                // This option is only valid with ext4
                tmpmnt_opts += ",nomblk_io_submit";
            }
            ret = mount(blk_device.c_str(), target.c_str(), fs_type.c_str(), tmpmnt_flags,
                        tmpmnt_opts.c_str());
            PINFO << __FUNCTION__ << "(): mount(" << blk_device << "," << target << "," << fs_type
                  << ")=" << ret;
            if (!ret) {
                bool umounted = false;
                int retry_count = 5;
                while (retry_count-- > 0) {
                    umounted = umount(target.c_str()) == 0;
                    if (umounted) {
                        LINFO << __FUNCTION__ << "(): unmount(" << target << ") succeeded";
                        break;
                    }
                    PERROR << __FUNCTION__ << "(): umount(" << target << ") failed";
                    if (retry_count) sleep(1);
                }
                if (!umounted) {
                    // boot may fail but continue and leave it to later stage for now.
                    PERROR << __FUNCTION__ << "(): umount(" << target << ") timed out";
                    *fs_stat |= FS_STAT_RO_UNMOUNT_FAILED;
                }
            } else {
                *fs_stat |= FS_STAT_RO_MOUNT_FAILED;
            }
        }

        /*
         * Some system images do not have e2fsck for licensing reasons
         * (e.g. recent SDK system images). Detect these and skip the check.
         */
        if (access(E2FSCK_BIN, X_OK)) {
            LINFO << "Not running " << E2FSCK_BIN << " on " << realpath(blk_device)
                  << " (executable not in system image)";
        } else {
            LINFO << "Running " << E2FSCK_BIN << " on " << realpath(blk_device);
            if (should_force_check(*fs_stat)) {
                ret = logwrap_fork_execvp(ARRAY_SIZE(e2fsck_forced_argv), e2fsck_forced_argv,
                                          &status, false, LOG_KLOG | LOG_FILE, false,
                                          FSCK_LOG_FILE);
            } else {
                ret = logwrap_fork_execvp(ARRAY_SIZE(e2fsck_argv), e2fsck_argv, &status, false,
                                          LOG_KLOG | LOG_FILE, false, FSCK_LOG_FILE);
            }

            if (ret < 0) {
                /* No need to check for error in fork, we can't really handle it now */
                LERROR << "Failed trying to run " << E2FSCK_BIN;
                *fs_stat |= FS_STAT_E2FSCK_FAILED;
            } else if (status != 0) {
                LINFO << "e2fsck returned status 0x" << std::hex << status;
                *fs_stat |= FS_STAT_E2FSCK_FS_FIXED;
            }
        }
    } else if (is_f2fs(fs_type)) {
        const char* f2fs_fsck_argv[] = {F2FS_FSCK_BIN,     "-a", "-c", "10000", "--debug-cache",
                                        blk_device.c_str()};
        const char* f2fs_fsck_forced_argv[] = {
                F2FS_FSCK_BIN, "-f", "-c", "10000", "--debug-cache", blk_device.c_str()};

        if (should_force_check(*fs_stat)) {
            LINFO << "Running " << F2FS_FSCK_BIN << " -f -c 10000 --debug-cache"
                  << realpath(blk_device);
            ret = logwrap_fork_execvp(ARRAY_SIZE(f2fs_fsck_forced_argv), f2fs_fsck_forced_argv,
                                      &status, false, LOG_KLOG | LOG_FILE, false, FSCK_LOG_FILE);
        } else {
            LINFO << "Running " << F2FS_FSCK_BIN << " -a -c 10000 --debug-cache"
                  << realpath(blk_device);
            ret = logwrap_fork_execvp(ARRAY_SIZE(f2fs_fsck_argv), f2fs_fsck_argv, &status, false,
                                      LOG_KLOG | LOG_FILE, false, FSCK_LOG_FILE);
        }
        if (ret < 0) {
            /* No need to check for error in fork, we can't really handle it now */
            LERROR << "Failed trying to run " << F2FS_FSCK_BIN;
        }
    }
    android::base::SetProperty("ro.boottime.init.fsck." + Basename(target),
                               std::to_string(t.duration().count()));
    return;
}

static ext4_fsblk_t ext4_blocks_count(const struct ext4_super_block* es) {
    return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
           le32_to_cpu(es->s_blocks_count_lo);
}

static ext4_fsblk_t ext4_r_blocks_count(const struct ext4_super_block* es) {
    return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
           le32_to_cpu(es->s_r_blocks_count_lo);
}

static bool is_ext4_superblock_valid(const struct ext4_super_block* es) {
    if (es->s_magic != EXT4_SUPER_MAGIC) return false;
    if (es->s_rev_level != EXT4_DYNAMIC_REV && es->s_rev_level != EXT4_GOOD_OLD_REV) return false;
    if (EXT4_INODES_PER_GROUP(es) == 0) return false;
    return true;
}

// 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, 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) {
        PERROR << "Failed to open '" << blk_device << "'";
        return false;
    }

    if (TEMP_FAILURE_RETRY(pread(fd, sb, sizeof(*sb), 1024)) != sizeof(*sb)) {
        PERROR << "Can't read '" << blk_device << "' superblock";
        return false;
    }

    if (!is_ext4_superblock_valid(sb)) {
        LINFO << "Invalid ext4 superblock on '" << blk_device << "'";
        // not a valid fs, tune2fs, fsck, and mount  will all fail.
        *fs_stat |= FS_STAT_INVALID_MAGIC;
        return false;
    }
    *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
        *fs_stat |= FS_STAT_NEW_IMAGE_VERSION;
    }
    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) {
    return access(TUNE2FS_BIN, X_OK) == 0;
}

static bool run_command(const char* argv[], int argc) {
    int ret;

    ret = logwrap_fork_execvp(argc, argv, nullptr, false, LOG_KLOG, false, nullptr);
    return ret == 0;
}

// Enable/disable quota support on the filesystem if needed.
static void tune_quota(const std::string& blk_device, const FstabEntry& entry,
                       const struct ext4_super_block* sb, int* fs_stat) {
    bool has_quota = (sb->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0;
    bool want_quota = entry.fs_mgr_flags.quota;
    bool want_projid = android::base::GetBoolProperty("external_storage.projid.enabled", false);

    if (has_quota == want_quota) {
        return;
    }

    if (!tune2fs_available()) {
        LERROR << "Unable to " << (want_quota ? "enable" : "disable") << " quotas on " << blk_device
               << " because " TUNE2FS_BIN " is missing";
        return;
    }

    const char* argv[] = {TUNE2FS_BIN, nullptr, nullptr, blk_device.c_str()};

    if (want_quota) {
        LINFO << "Enabling quotas on " << blk_device;
        argv[1] = "-Oquota";
        // Once usr/grp unneeded, make just prjquota to save overhead
        if (want_projid)
            argv[2] = "-Qusrquota,grpquota,prjquota";
        else
            argv[2] = "-Qusrquota,grpquota";
        *fs_stat |= FS_STAT_QUOTA_ENABLED;
    } else {
        LINFO << "Disabling quotas on " << blk_device;
        argv[1] = "-O^quota";
        argv[2] = "-Q^usrquota,^grpquota,^prjquota";
    }

    if (!run_command(argv, ARRAY_SIZE(argv))) {
        LERROR << "Failed to run " TUNE2FS_BIN " to " << (want_quota ? "enable" : "disable")
               << " quotas on " << blk_device;
        *fs_stat |= FS_STAT_TOGGLE_QUOTAS_FAILED;
    }
}

// Set the number of reserved filesystem blocks if needed.
static void tune_reserved_size(const std::string& blk_device, const FstabEntry& entry,
                               const struct ext4_super_block* sb, int* fs_stat) {
    if (entry.reserved_size == 0) {
        return;
    }

    // The size to reserve is given in the fstab, but we won't reserve more
    // than 2% of the filesystem.
    const uint64_t max_reserved_blocks = ext4_blocks_count(sb) * 0.02;
    uint64_t reserved_blocks = entry.reserved_size / EXT4_BLOCK_SIZE(sb);

    if (reserved_blocks > max_reserved_blocks) {
        LWARNING << "Reserved blocks " << reserved_blocks << " is too large; "
                 << "capping to " << max_reserved_blocks;
        reserved_blocks = max_reserved_blocks;
    }

    if ((ext4_r_blocks_count(sb) == reserved_blocks) && (sb->s_def_resgid == AID_RESERVED_DISK)) {
        return;
    }

    if (!tune2fs_available()) {
        LERROR << "Unable to set the number of reserved blocks on " << blk_device
               << " because " TUNE2FS_BIN " is missing";
        return;
    }

    LINFO << "Setting reserved block count on " << blk_device << " to " << reserved_blocks;

    auto reserved_blocks_str = std::to_string(reserved_blocks);
    auto reserved_gid_str = std::to_string(AID_RESERVED_DISK);
    const char* argv[] = {
            TUNE2FS_BIN,       "-r", reserved_blocks_str.c_str(), "-g", reserved_gid_str.c_str(),
            blk_device.c_str()};
    if (!run_command(argv, ARRAY_SIZE(argv))) {
        LERROR << "Failed to run " TUNE2FS_BIN " to set the number of reserved blocks on "
               << blk_device;
        *fs_stat |= FS_STAT_SET_RESERVED_BLOCKS_FAILED;
    }
}

// Enable file-based encryption if needed.
static void tune_encrypt(const std::string& blk_device, const FstabEntry& entry,
                         const struct ext4_super_block* sb, int* fs_stat) {
    if (!entry.fs_mgr_flags.file_encryption) {
        return;  // Nothing needs done.
    }
    std::vector<std::string> features_needed;
    if ((sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_ENCRYPT)) == 0) {
        features_needed.emplace_back("encrypt");
    }
    android::fscrypt::EncryptionOptions options;
    if (!android::fscrypt::ParseOptions(entry.encryption_options, &options)) {
        LERROR << "Unable to parse encryption options on " << blk_device << ": "
               << entry.encryption_options;
        return;
    }
    if ((options.flags &
         (FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 | FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) != 0) {
        // We can only use this policy on ext4 if the "stable_inodes" feature
        // is set on the filesystem, otherwise shrinking will break encrypted files.
        if ((sb->s_feature_compat & cpu_to_le32(EXT4_FEATURE_COMPAT_STABLE_INODES)) == 0) {
            features_needed.emplace_back("stable_inodes");
        }
    }
    if (features_needed.size() == 0) {
        return;
    }
    if (!tune2fs_available()) {
        LERROR << "Unable to enable ext4 encryption on " << blk_device
               << " because " TUNE2FS_BIN " is missing";
        return;
    }

    auto flags = android::base::Join(features_needed, ',');
    auto flag_arg = "-O"s + flags;
    const char* argv[] = {TUNE2FS_BIN, flag_arg.c_str(), blk_device.c_str()};

    LINFO << "Enabling ext4 flags " << flags << " on " << blk_device;
    if (!run_command(argv, ARRAY_SIZE(argv))) {
        LERROR << "Failed to run " TUNE2FS_BIN " to enable "
               << "ext4 flags " << flags << " on " << blk_device;
        *fs_stat |= FS_STAT_ENABLE_ENCRYPTION_FAILED;
    }
}

// Enable fs-verity if needed.
static void tune_verity(const std::string& blk_device, const FstabEntry& entry,
                        const struct ext4_super_block* sb, int* fs_stat) {
    bool has_verity = (sb->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_VERITY)) != 0;
    bool want_verity = entry.fs_mgr_flags.fs_verity;

    if (has_verity || !want_verity) {
        return;
    }

    std::string verity_support;
    if (!android::base::ReadFileToString(SYSFS_EXT4_VERITY, &verity_support)) {
        LERROR << "Failed to open " << SYSFS_EXT4_VERITY;
        return;
    }

    if (!(android::base::Trim(verity_support) == "supported")) {
        LERROR << "Current ext4 verity not supported by kernel";
        return;
    }

    if (!tune2fs_available()) {
        LERROR << "Unable to enable ext4 verity on " << blk_device
               << " because " TUNE2FS_BIN " is missing";
        return;
    }

    LINFO << "Enabling ext4 verity on " << blk_device;

    const char* argv[] = {TUNE2FS_BIN, "-O", "verity", blk_device.c_str()};
    if (!run_command(argv, ARRAY_SIZE(argv))) {
        LERROR << "Failed to run " TUNE2FS_BIN " to enable "
               << "ext4 verity on " << blk_device;
        *fs_stat |= FS_STAT_ENABLE_VERITY_FAILED;
    }
}

// Enable casefold if needed.
static void tune_casefold(const std::string& blk_device, 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;

    std::string casefold_support;
    if (!android::base::ReadFileToString(SYSFS_EXT4_CASEFOLD, &casefold_support)) {
        LERROR << "Failed to open " << SYSFS_EXT4_CASEFOLD;
        return;
    }

    if (!(android::base::Trim(casefold_support) == "supported")) {
        LERROR << "Current ext4 casefolding not supported by kernel";
        return;
    }

    if (!tune2fs_available()) {
        LERROR << "Unable to enable ext4 casefold on " << blk_device
               << " because " TUNE2FS_BIN " is missing";
        return;
    }

    LINFO << "Enabling ext4 casefold on " << blk_device;

    const char* argv[] = {TUNE2FS_BIN, "-O", "casefold", "-E", "encoding=utf8", blk_device.c_str()};
    if (!run_command(argv, ARRAY_SIZE(argv))) {
        LERROR << "Failed to run " TUNE2FS_BIN " to enable "
               << "ext4 casefold on " << blk_device;
        *fs_stat |= FS_STAT_ENABLE_CASEFOLD_FAILED;
    }
}

static bool resize2fs_available(void) {
    return access(RESIZE2FS_BIN, X_OK) == 0;
}

// Enable metadata_csum
static void tune_metadata_csum(const std::string& blk_device, const FstabEntry& entry,
                               const struct ext4_super_block* sb, int* fs_stat) {
    bool has_meta_csum =
            (sb->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) != 0;
    bool want_meta_csum = entry.fs_mgr_flags.ext_meta_csum;

    if (has_meta_csum || !want_meta_csum) return;

    if (!tune2fs_available()) {
        LERROR << "Unable to enable metadata_csum on " << blk_device
               << " because " TUNE2FS_BIN " is missing";
        return;
    }
    if (!resize2fs_available()) {
        LERROR << "Unable to enable metadata_csum on " << blk_device
               << " because " RESIZE2FS_BIN " is missing";
        return;
    }

    LINFO << "Enabling ext4 metadata_csum on " << blk_device;

    // requires to give last_fsck_time to current to avoid insane time.
    // otherwise, tune2fs won't enable metadata_csum.
    std::string now = std::to_string(time(0));
    const char* tune2fs_args[] = {TUNE2FS_BIN, "-O",        "metadata_csum,64bit,extent",
                                  "-T",        now.c_str(), blk_device.c_str()};
    const char* resize2fs_args[] = {RESIZE2FS_BIN, "-b", blk_device.c_str()};

    if (!run_command(tune2fs_args, ARRAY_SIZE(tune2fs_args))) {
        LERROR << "Failed to run " TUNE2FS_BIN " to enable "
               << "ext4 metadata_csum on " << blk_device;
        *fs_stat |= FS_STAT_ENABLE_METADATA_CSUM_FAILED;
    } else if (!run_command(resize2fs_args, ARRAY_SIZE(resize2fs_args))) {
        LERROR << "Failed to run " RESIZE2FS_BIN " to enable "
               << "ext4 metadata_csum on " << blk_device;
        *fs_stat |= FS_STAT_ENABLE_METADATA_CSUM_FAILED;
    }
}

// Read the primary superblock from an f2fs filesystem.  On failure return
// false.  If it's not an f2fs filesystem, also set FS_STAT_INVALID_MAGIC.
#define F2FS_BLKSIZE 4096
#define F2FS_SUPER_OFFSET 1024
static bool read_f2fs_superblock(const std::string& blk_device, int* fs_stat) {
    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(blk_device.c_str(), O_RDONLY | O_CLOEXEC)));
    __le32 sb1, sb2;

    if (fd < 0) {
        PERROR << "Failed to open '" << blk_device << "'";
        return false;
    }

    if (TEMP_FAILURE_RETRY(pread(fd, &sb1, sizeof(sb1), F2FS_SUPER_OFFSET)) != sizeof(sb1)) {
        PERROR << "Can't read '" << blk_device << "' superblock1";
        return false;
    }
    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;
    }

    if (sb1 != cpu_to_le32(F2FS_SUPER_MAGIC) && sb2 != cpu_to_le32(F2FS_SUPER_MAGIC)) {
        LINFO << "Invalid f2fs superblock on '" << blk_device << "'";
        *fs_stat |= FS_STAT_INVALID_MAGIC;
        return false;
    }
    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.
//
// If the "check" option was given in the fstab record, or it seems that the
// filesystem was uncleanly shut down, we'll run fsck on the filesystem.
//
// If needed, we'll also enable (or disable) filesystem features as specified by
// the fstab record.
//
static int prepare_fs_for_mount(const std::string& blk_device, const FstabEntry& entry) {
    int fs_stat = 0;

    if (is_extfs(entry.fs_type)) {
        struct ext4_super_block sb;

        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; "
                      << "state flags: 0x" << std::hex << sb.s_state << ", "
                      << "incompat feature flags: 0x" << std::hex << sb.s_feature_incompat;
                fs_stat |= FS_STAT_UNCLEAN_SHUTDOWN;
            }

            // Note: quotas should be enabled before running fsck.
            tune_quota(blk_device, entry, &sb, &fs_stat);
        } else {
            return fs_stat;
        }
    } else if (is_f2fs(entry.fs_type)) {
        if (!read_f2fs_superblock(blk_device, &fs_stat)) {
            return fs_stat;
        }
    }

    if (entry.fs_mgr_flags.check ||
        (fs_stat & (FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED))) {
        check_fs(blk_device, entry.fs_type, entry.mount_point, &fs_stat);
    }

    if (is_extfs(entry.fs_type) &&
        (entry.reserved_size != 0 || entry.fs_mgr_flags.file_encryption ||
         entry.fs_mgr_flags.fs_verity || entry.fs_mgr_flags.ext_meta_csum)) {
        struct ext4_super_block sb;

        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_metadata_csum(blk_device, entry, &sb, &fs_stat);
        }
    }

    return fs_stat;
}

// Mark the given block device as read-only, using the BLKROSET ioctl.
bool fs_mgr_set_blk_ro(const std::string& blockdev, bool readonly) {
    unique_fd fd(TEMP_FAILURE_RETRY(open(blockdev.c_str(), O_RDONLY | O_CLOEXEC)));
    if (fd < 0) {
        return false;
    }

    int ON = readonly;
    return ioctl(fd, BLKROSET, &ON) == 0;
}

// Orange state means the device is unlocked, see the following link for details.
// https://source.android.com/security/verifiedboot/verified-boot#device_state
bool fs_mgr_is_device_unlocked() {
    std::string verified_boot_state;
    if (fs_mgr_get_boot_config("verifiedbootstate", &verified_boot_state)) {
        return verified_boot_state == "orange";
    }
    return false;
}

// __mount(): wrapper around the mount() system call which also
// sets the underlying block device to read-only if the mount is read-only.
// See "man 2 mount" for return values.
static int __mount(const std::string& source, const std::string& target, const FstabEntry& entry) {
    // We need this because sometimes we have legacy symlinks that are
    // lingering around and need cleaning up.
    struct stat info;
    if (lstat(target.c_str(), &info) == 0 && (info.st_mode & S_IFMT) == S_IFLNK) {
        unlink(target.c_str());
    }
    mkdir(target.c_str(), 0755);
    errno = 0;
    unsigned long mountflags = entry.flags;
    int ret = 0;
    int save_errno = 0;
    int gc_allowance = 0;
    std::string opts;
    bool try_f2fs_gc_allowance = is_f2fs(entry.fs_type) && entry.fs_checkpoint_opts.length() > 0;
    Timer t;

    do {
        if (save_errno == EINVAL && try_f2fs_gc_allowance) {
            PINFO << "Kernel does not support checkpoint=disable:[n]%, trying without.";
            try_f2fs_gc_allowance = false;
        }
        if (try_f2fs_gc_allowance) {
            opts = entry.fs_options + entry.fs_checkpoint_opts + ":" +
                   std::to_string(gc_allowance) + "%";
        } else {
            opts = entry.fs_options;
        }
        if (save_errno == EAGAIN) {
            PINFO << "Retrying mount (source=" << source << ",target=" << target
                  << ",type=" << entry.fs_type << ", gc_allowance=" << gc_allowance << "%)=" << ret
                  << "(" << save_errno << ")";
        }
        ret = mount(source.c_str(), target.c_str(), entry.fs_type.c_str(), mountflags,
                    opts.c_str());
        save_errno = errno;
        if (try_f2fs_gc_allowance) gc_allowance += 10;
    } while ((ret && save_errno == EAGAIN && gc_allowance <= 100) ||
             (ret && save_errno == EINVAL && try_f2fs_gc_allowance));
    const char* target_missing = "";
    const char* source_missing = "";
    if (save_errno == ENOENT) {
        if (access(target.c_str(), F_OK)) {
            target_missing = "(missing)";
        } else if (access(source.c_str(), F_OK)) {
            source_missing = "(missing)";
        }
        errno = save_errno;
    }
    PINFO << __FUNCTION__ << "(source=" << source << source_missing << ",target=" << target
          << target_missing << ",type=" << entry.fs_type << ")=" << ret;
    if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
        fs_mgr_set_blk_ro(source);
    }
    android::base::SetProperty("ro.boottime.init.mount." + Basename(target),
                               std::to_string(t.duration().count()));
    errno = save_errno;
    return ret;
}

static bool fs_match(const std::string& in1, const std::string& in2) {
    if (in1.empty() || in2.empty()) {
        return false;
    }

    auto in1_end = in1.size() - 1;
    while (in1_end > 0 && in1[in1_end] == '/') {
        in1_end--;
    }

    auto in2_end = in2.size() - 1;
    while (in2_end > 0 && in2[in2_end] == '/') {
        in2_end--;
    }

    if (in1_end != in2_end) {
        return false;
    }

    for (size_t i = 0; i <= in1_end; ++i) {
        if (in1[i] != in2[i]) {
            return false;
        }
    }

    return true;
}

// Tries to mount any of the consecutive fstab entries that match
// the mountpoint of the one given by fstab[start_idx].
//
// end_idx: On return, will be the last entry that was looked at.
// attempted_idx: On return, will indicate which fstab entry
//     succeeded. In case of failure, it will be the start_idx.
// Sets errno to match the 1st mount failure on failure.
static bool mount_with_alternatives(const Fstab& fstab, int start_idx, int* end_idx,
                                    int* attempted_idx) {
    unsigned long i;
    int mount_errno = 0;
    bool mounted = false;

    // Hunt down an fstab entry for the same mount point that might succeed.
    for (i = start_idx;
         // We required that fstab entries for the same mountpoint be consecutive.
         i < fstab.size() && fstab[start_idx].mount_point == fstab[i].mount_point; i++) {
        // Don't try to mount/encrypt the same mount point again.
        // Deal with alternate entries for the same point which are required to be all following
        // each other.
        if (mounted) {
            LERROR << __FUNCTION__ << "(): skipping fstab dup mountpoint=" << fstab[i].mount_point
                   << " rec[" << i << "].fs_type=" << fstab[i].fs_type << " already mounted as "
                   << fstab[*attempted_idx].fs_type;
            continue;
        }

        int fs_stat = prepare_fs_for_mount(fstab[i].blk_device, fstab[i]);
        if (fs_stat & FS_STAT_INVALID_MAGIC) {
            LERROR << __FUNCTION__
                   << "(): skipping mount due to invalid magic, mountpoint=" << fstab[i].mount_point
                   << " blk_dev=" << realpath(fstab[i].blk_device) << " rec[" << i
                   << "].fs_type=" << fstab[i].fs_type;
            mount_errno = EINVAL;  // continue bootup for FDE
            continue;
        }

        int retry_count = 2;
        while (retry_count-- > 0) {
            if (!__mount(fstab[i].blk_device, fstab[i].mount_point, fstab[i])) {
                *attempted_idx = i;
                mounted = true;
                if (i != start_idx) {
                    LERROR << __FUNCTION__ << "(): Mounted " << fstab[i].blk_device << " on "
                           << fstab[i].mount_point << " with fs_type=" << fstab[i].fs_type
                           << " instead of " << fstab[start_idx].fs_type;
                }
                fs_stat &= ~FS_STAT_FULL_MOUNT_FAILED;
                mount_errno = 0;
                break;
            } else {
                if (retry_count <= 0) break;  // run check_fs only once
                fs_stat |= FS_STAT_FULL_MOUNT_FAILED;
                // back up the first errno for crypto decisions.
                if (mount_errno == 0) {
                    mount_errno = errno;
                }
                // retry after fsck
                check_fs(fstab[i].blk_device, fstab[i].fs_type, fstab[i].mount_point, &fs_stat);
            }
        }
        log_fs_stat(fstab[i].blk_device, fs_stat);
    }

    /* Adjust i for the case where it was still withing the recs[] */
    if (i < fstab.size()) --i;

    *end_idx = i;
    if (!mounted) {
        *attempted_idx = start_idx;
        errno = mount_errno;
        return false;
    }
    return true;
}

static bool TranslateExtLabels(FstabEntry* entry) {
    if (!StartsWith(entry->blk_device, "LABEL=")) {
        return true;
    }

    std::string label = entry->blk_device.substr(6);
    if (label.size() > 16) {
        LERROR << "FS label is longer than allowed by filesystem";
        return false;
    }

    auto blockdir = std::unique_ptr<DIR, decltype(&closedir)>{opendir("/dev/block"), closedir};
    if (!blockdir) {
        LERROR << "couldn't open /dev/block";
        return false;
    }

    struct dirent* ent;
    while ((ent = readdir(blockdir.get()))) {
        if (ent->d_type != DT_BLK)
            continue;

        unique_fd fd(TEMP_FAILURE_RETRY(
                openat(dirfd(blockdir.get()), ent->d_name, O_RDONLY | O_CLOEXEC)));
        if (fd < 0) {
            LERROR << "Cannot open block device /dev/block/" << ent->d_name;
            return false;
        }

        ext4_super_block super_block;
        if (TEMP_FAILURE_RETRY(lseek(fd, 1024, SEEK_SET)) < 0 ||
            TEMP_FAILURE_RETRY(read(fd, &super_block, sizeof(super_block))) !=
                    sizeof(super_block)) {
            // Probably a loopback device or something else without a readable superblock.
            continue;
        }

        if (super_block.s_magic != EXT4_SUPER_MAGIC) {
            LINFO << "/dev/block/" << ent->d_name << " not ext{234}";
            continue;
        }

        if (label == super_block.s_volume_name) {
            std::string new_blk_device = "/dev/block/"s + ent->d_name;

            LINFO << "resolved label " << entry->blk_device << " to " << new_blk_device;

            entry->blk_device = new_blk_device;
            return true;
        }
    }

    return false;
}

static bool needs_block_encryption(const FstabEntry& entry) {
    if (android::base::GetBoolProperty("ro.vold.forceencryption", false) && entry.is_encryptable())
        return true;
    if (entry.fs_mgr_flags.force_crypt) return true;
    if (entry.fs_mgr_flags.crypt) {
        // Check for existence of convert_fde breadcrumb file.
        auto convert_fde_name = entry.mount_point + "/misc/vold/convert_fde";
        if (access(convert_fde_name.c_str(), F_OK) == 0) return true;
    }
    if (entry.fs_mgr_flags.force_fde_or_fbe) {
        // Check for absence of convert_fbe breadcrumb file.
        auto convert_fbe_name = entry.mount_point + "/convert_fbe";
        if (access(convert_fbe_name.c_str(), F_OK) != 0) return true;
    }
    return false;
}

static bool should_use_metadata_encryption(const FstabEntry& entry) {
    return !entry.metadata_key_dir.empty() &&
           (entry.fs_mgr_flags.file_encryption || entry.fs_mgr_flags.force_fde_or_fbe);
}

// Check to see if a mountable volume has encryption requirements
static int handle_encryptable(const FstabEntry& entry) {
    // If this is block encryptable, need to trigger encryption.
    if (needs_block_encryption(entry)) {
        if (umount(entry.mount_point.c_str()) == 0) {
            return FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION;
        } else {
            PWARNING << "Could not umount " << entry.mount_point << " - allow continue unencrypted";
            return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
        }
    } else if (should_use_metadata_encryption(entry)) {
        if (umount(entry.mount_point.c_str()) == 0) {
            return FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION;
        } else {
            PERROR << "Could not umount " << entry.mount_point << " - fail since can't encrypt";
            return FS_MGR_MNTALL_FAIL;
        }
    } else if (entry.fs_mgr_flags.file_encryption || entry.fs_mgr_flags.force_fde_or_fbe) {
        LINFO << entry.mount_point << " is file encrypted";
        return FS_MGR_MNTALL_DEV_FILE_ENCRYPTED;
    } else if (entry.is_encryptable()) {
        return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
    } else {
        return FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
    }
}

static bool call_vdc(const std::vector<std::string>& args, int* ret) {
    std::vector<char const*> argv;
    argv.emplace_back("/system/bin/vdc");
    for (auto& arg : args) {
        argv.emplace_back(arg.c_str());
    }
    LOG(INFO) << "Calling: " << android::base::Join(argv, ' ');
    int err = logwrap_fork_execvp(argv.size(), argv.data(), ret, false, LOG_ALOG, false, nullptr);
    if (err != 0) {
        LOG(ERROR) << "vdc call failed with error code: " << err;
        return false;
    }
    LOG(DEBUG) << "vdc finished successfully";
    if (ret != nullptr) {
        *ret = WEXITSTATUS(*ret);
    }
    return true;
}

bool fs_mgr_update_logical_partition(FstabEntry* entry) {
    // Logical partitions are specified with a named partition rather than a
    // block device, so if the block device is a path, then it has already
    // been updated.
    if (entry->blk_device[0] == '/') {
        return true;
    }

    DeviceMapper& dm = DeviceMapper::Instance();
    std::string device_name;
    if (!dm.GetDmDevicePathByName(entry->blk_device, &device_name)) {
        return false;
    }

    entry->blk_device = device_name;
    return true;
}

static bool SupportsCheckpoint(FstabEntry* entry) {
    return entry->fs_mgr_flags.checkpoint_blk || entry->fs_mgr_flags.checkpoint_fs;
}

class CheckpointManager {
  public:
    CheckpointManager(int needs_checkpoint = -1, bool metadata_encrypted = false)
        : needs_checkpoint_(needs_checkpoint), metadata_encrypted_(metadata_encrypted) {}

    bool NeedsCheckpoint() {
        if (needs_checkpoint_ != UNKNOWN) {
            return needs_checkpoint_ == YES;
        }
        if (!call_vdc({"checkpoint", "needsCheckpoint"}, &needs_checkpoint_)) {
            LERROR << "Failed to find if checkpointing is needed. Assuming no.";
            needs_checkpoint_ = NO;
        }
        return needs_checkpoint_ == YES;
    }

    bool Update(FstabEntry* entry, const std::string& block_device = std::string()) {
        if (!SupportsCheckpoint(entry)) {
            return true;
        }

        if (entry->fs_mgr_flags.checkpoint_blk && !metadata_encrypted_) {
            call_vdc({"checkpoint", "restoreCheckpoint", entry->blk_device}, nullptr);
        }

        if (!NeedsCheckpoint()) {
            return true;
        }

        if (!UpdateCheckpointPartition(entry, block_device)) {
            LERROR << "Could not set up checkpoint partition, skipping!";
            return false;
        }

        return true;
    }

    bool Revert(FstabEntry* entry) {
        if (!SupportsCheckpoint(entry)) {
            return true;
        }

        if (device_map_.find(entry->blk_device) == device_map_.end()) {
            return true;
        }

        std::string bow_device = entry->blk_device;
        entry->blk_device = device_map_[bow_device];
        device_map_.erase(bow_device);

        DeviceMapper& dm = DeviceMapper::Instance();
        if (!dm.DeleteDevice("bow")) {
            PERROR << "Failed to remove bow device";
        }

        return true;
    }

  private:
    bool UpdateCheckpointPartition(FstabEntry* entry, const std::string& block_device) {
        if (entry->fs_mgr_flags.checkpoint_fs) {
            if (is_f2fs(entry->fs_type)) {
                entry->fs_checkpoint_opts = ",checkpoint=disable";
            } else {
                LERROR << entry->fs_type << " does not implement checkpoints.";
            }
        } else if (entry->fs_mgr_flags.checkpoint_blk) {
            auto actual_block_device = block_device.empty() ? entry->blk_device : block_device;
            if (fs_mgr_find_bow_device(actual_block_device).empty()) {
                unique_fd fd(
                        TEMP_FAILURE_RETRY(open(entry->blk_device.c_str(), O_RDONLY | O_CLOEXEC)));
                if (fd < 0) {
                    PERROR << "Cannot open device " << entry->blk_device;
                    return false;
                }

                uint64_t size = get_block_device_size(fd) / 512;
                if (!size) {
                    PERROR << "Cannot get device size";
                    return false;
                }

                android::dm::DmTable table;
                auto bowTarget =
                        std::make_unique<android::dm::DmTargetBow>(0, size, entry->blk_device);

                // dm-bow uses the first block as a log record, and relocates the real first block
                // elsewhere. For metadata encrypted devices, dm-bow sits below dm-default-key, and
                // for post Android Q devices dm-default-key uses a block size of 4096 always.
                // So if dm-bow's block size, which by default is the block size of the underlying
                // hardware, is less than dm-default-key's, blocks will get broken up and I/O will
                // fail as it won't be data_unit_size aligned.
                // However, since it is possible there is an already shipping non
                // 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));
                if (options_format_version > 1) {
                    bowTarget->SetBlockSize(4096);
                }

                if (!table.AddTarget(std::move(bowTarget))) {
                    LERROR << "Failed to add bow target";
                    return false;
                }

                DeviceMapper& dm = DeviceMapper::Instance();
                if (!dm.CreateDevice("bow", table)) {
                    PERROR << "Failed to create bow device";
                    return false;
                }

                std::string name;
                if (!dm.GetDmDevicePathByName("bow", &name)) {
                    PERROR << "Failed to get bow device name";
                    return false;
                }

                device_map_[name] = entry->blk_device;
                entry->blk_device = name;
            }
        }
        return true;
    }

    enum { UNKNOWN = -1, NO = 0, YES = 1 };
    int needs_checkpoint_;
    bool metadata_encrypted_;
    std::map<std::string, std::string> device_map_;
};

std::string fs_mgr_find_bow_device(const std::string& block_device) {
    if (block_device.substr(0, 5) != "/dev/") {
        LOG(ERROR) << "Expected block device, got " << block_device;
        return std::string();
    }

    std::string sys_dir = std::string("/sys/") + block_device.substr(5);

    for (;;) {
        std::string name;
        if (!android::base::ReadFileToString(sys_dir + "/dm/name", &name)) {
            PLOG(ERROR) << block_device << " is not dm device";
            return std::string();
        }

        if (name == "bow\n") return sys_dir;

        std::string slaves = sys_dir + "/slaves";
        std::unique_ptr<DIR, decltype(&closedir)> directory(opendir(slaves.c_str()), closedir);
        if (!directory) {
            PLOG(ERROR) << "Can't open slave directory " << slaves;
            return std::string();
        }

        int count = 0;
        for (dirent* entry = readdir(directory.get()); entry; entry = readdir(directory.get())) {
            if (entry->d_type != DT_LNK) continue;

            if (count == 1) {
                LOG(ERROR) << "Too many slaves in " << slaves;
                return std::string();
            }

            ++count;
            sys_dir = std::string("/sys/block/") + entry->d_name;
        }

        if (count != 1) {
            LOG(ERROR) << "No slave in " << slaves;
            return std::string();
        }
    }
}

static constexpr const char* kUserdataWrapperName = "userdata-wrapper";

static void WrapUserdata(FstabEntry* entry, dev_t dev, const std::string& block_device) {
    DeviceMapper& dm = DeviceMapper::Instance();
    if (dm.GetState(kUserdataWrapperName) != DmDeviceState::INVALID) {
        // This will report failure for us. If we do fail to get the path,
        // we leave the device unwrapped.
        dm.GetDmDevicePathByName(kUserdataWrapperName, &entry->blk_device);
        return;
    }

    unique_fd fd(open(block_device.c_str(), O_RDONLY | O_CLOEXEC));
    if (fd < 0) {
        PLOG(ERROR) << "open failed: " << entry->blk_device;
        return;
    }

    auto dev_str = android::base::StringPrintf("%u:%u", major(dev), minor(dev));
    uint64_t sectors = get_block_device_size(fd) / 512;

    android::dm::DmTable table;
    table.Emplace<DmTargetLinear>(0, sectors, dev_str, 0);

    std::string dm_path;
    if (!dm.CreateDevice(kUserdataWrapperName, table, &dm_path, 20s)) {
        LOG(ERROR) << "Failed to create userdata wrapper device";
        return;
    }
    entry->blk_device = dm_path;
}

// When using Virtual A/B, partitions can be backed by /data and mapped with
// device-mapper in first-stage init. This can happen when merging an OTA or
// when using adb remount to house "scratch". In this case, /data cannot be
// mounted directly off the userdata block device, and e2fsck will refuse to
// scan it, because the kernel reports the block device as in-use.
//
// As a workaround, when mounting /data, we create a trivial dm-linear wrapper
// if the underlying block device already has dependencies. Note that we make
// an exception for metadata-encrypted devices, since dm-default-key is already
// a wrapper.
static void WrapUserdataIfNeeded(FstabEntry* entry, const std::string& actual_block_device = {}) {
    const auto& block_device =
            actual_block_device.empty() ? entry->blk_device : actual_block_device;
    if (entry->mount_point != "/data" || !entry->metadata_key_dir.empty() ||
        android::base::StartsWith(block_device, "/dev/block/dm-")) {
        return;
    }

    struct stat st;
    if (stat(block_device.c_str(), &st) < 0) {
        PLOG(ERROR) << "stat failed: " << block_device;
        return;
    }

    std::string path = android::base::StringPrintf("/sys/dev/block/%u:%u/holders",
                                                   major(st.st_rdev), minor(st.st_rdev));
    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
    if (!dir) {
        PLOG(ERROR) << "opendir failed: " << path;
        return;
    }

    struct dirent* d;
    bool has_holders = false;
    while ((d = readdir(dir.get())) != nullptr) {
        if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) {
            has_holders = true;
            break;
        }
    }

    if (has_holders) {
        WrapUserdata(entry, st.st_rdev, block_device);
    }
}

static bool IsMountPointMounted(const std::string& mount_point) {
    // Check if this is already mounted.
    Fstab fstab;
    if (!ReadFstabFromFile("/proc/mounts", &fstab)) {
        return false;
    }
    return GetEntryForMountPoint(&fstab, mount_point) != nullptr;
}

// 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) {
    int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
    int error_count = 0;
    CheckpointManager checkpoint_manager;
    AvbUniquePtr avb_handle(nullptr);

    if (fstab->empty()) {
        return FS_MGR_MNTALL_FAIL;
    }

    // Keep i int to prevent unsigned integer overflow from (i = top_idx - 1),
    // where top_idx is 0. It will give SIGABRT
    for (int i = 0; i < static_cast<int>(fstab->size()); i++) {
        auto& current_entry = (*fstab)[i];

        // If a filesystem should have been mounted in the first stage, we
        // ignore it here. With one exception, if the filesystem is
        // formattable, then it can only be formatted in the second stage,
        // so we allow it to mount here.
        if (current_entry.fs_mgr_flags.first_stage_mount &&
            (!current_entry.fs_mgr_flags.formattable ||
             IsMountPointMounted(current_entry.mount_point))) {
            continue;
        }

        // Don't mount entries that are managed by vold or not for the mount mode.
        if (current_entry.fs_mgr_flags.vold_managed || current_entry.fs_mgr_flags.recovery_only ||
            ((mount_mode == MOUNT_MODE_LATE) && !current_entry.fs_mgr_flags.late_mount) ||
            ((mount_mode == MOUNT_MODE_EARLY) && current_entry.fs_mgr_flags.late_mount)) {
            continue;
        }

        // Skip swap and raw partition entries such as boot, recovery, etc.
        if (current_entry.fs_type == "swap" || current_entry.fs_type == "emmc" ||
            current_entry.fs_type == "mtd") {
            continue;
        }

        // Skip mounting the root partition, as it will already have been mounted.
        if (current_entry.mount_point == "/" || current_entry.mount_point == "/system") {
            if ((current_entry.flags & MS_RDONLY) != 0) {
                fs_mgr_set_blk_ro(current_entry.blk_device);
            }
            continue;
        }

        // Terrible hack to make it possible to remount /data.
        // TODO: refact fs_mgr_mount_all and get rid of this.
        if (mount_mode == MOUNT_MODE_ONLY_USERDATA && current_entry.mount_point != "/data") {
            continue;
        }

        // Translate LABEL= file system labels into block devices.
        if (is_extfs(current_entry.fs_type)) {
            if (!TranslateExtLabels(&current_entry)) {
                LERROR << "Could not translate label to block device";
                continue;
            }
        }

        if (current_entry.fs_mgr_flags.logical) {
            if (!fs_mgr_update_logical_partition(&current_entry)) {
                LERROR << "Could not set up logical partition, skipping!";
                continue;
            }
        }

        WrapUserdataIfNeeded(&current_entry);

        if (!checkpoint_manager.Update(&current_entry)) {
            continue;
        }

        if (current_entry.fs_mgr_flags.wait && !WaitForFile(current_entry.blk_device, 20s)) {
            LERROR << "Skipping '" << current_entry.blk_device << "' during mount_all";
            continue;
        }

        if (current_entry.fs_mgr_flags.avb) {
            if (!avb_handle) {
                avb_handle = AvbHandle::Open();
                if (!avb_handle) {
                    LERROR << "Failed to open AvbHandle";
                    return FS_MGR_MNTALL_FAIL;
                }
            }
            if (avb_handle->SetUpAvbHashtree(&current_entry, true /* wait_for_verity_dev */) ==
                AvbHashtreeResult::kFail) {
                LERROR << "Failed to set up AVB on partition: " << current_entry.mount_point
                       << ", skipping!";
                // Skips mounting the device.
                continue;
            }
        } else if (!current_entry.avb_keys.empty()) {
            if (AvbHandle::SetUpStandaloneAvbHashtree(&current_entry) == AvbHashtreeResult::kFail) {
                LERROR << "Failed to set up AVB on standalone partition: "
                       << current_entry.mount_point << ", skipping!";
                // Skips mounting the device.
                continue;
            }
        } else if ((current_entry.fs_mgr_flags.verify)) {
            int rc = fs_mgr_setup_verity(&current_entry, true);
            if (rc == FS_MGR_SETUP_VERITY_DISABLED || rc == FS_MGR_SETUP_VERITY_SKIPPED) {
                LINFO << "Verity disabled";
            } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
                LERROR << "Could not set up verified partition, skipping!";
                continue;
            }
        }

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

        bool mret = mount_with_alternatives(*fstab, i, &last_idx_inspected, &attempted_idx);
        auto& attempted_entry = (*fstab)[attempted_idx];
        i = last_idx_inspected;
        int mount_errno = errno;

        // Handle success and deal with encryptability.
        if (mret) {
            int status = handle_encryptable(attempted_entry);

            if (status == FS_MGR_MNTALL_FAIL) {
                // Fatal error - no point continuing.
                return status;
            }

            if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
                if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
                    // Log and continue
                    LERROR << "Only one encryptable/encrypted partition supported";
                }
                encryptable = status;
                if (status == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
                    if (!call_vdc({"cryptfs", "encryptFstab", attempted_entry.blk_device,
                                   attempted_entry.mount_point},
                                  nullptr)) {
                        LERROR << "Encryption failed";
                        return FS_MGR_MNTALL_FAIL;
                    }
                }
            }

            // Success!  Go get the next one.
            continue;
        }

        // Mounting failed, understand why and retry.
        bool wiped = partition_wiped(current_entry.blk_device.c_str());
        bool crypt_footer = false;
        if (mount_errno != EBUSY && mount_errno != EACCES &&
            current_entry.fs_mgr_flags.formattable && wiped) {
            // current_entry and attempted_entry point at the same partition, but sometimes
            // at two different lines in the fstab.  Use current_entry for formatting
            // as that is the preferred one.
            LERROR << __FUNCTION__ << "(): " << realpath(current_entry.blk_device)
                   << " is wiped and " << current_entry.mount_point << " " << current_entry.fs_type
                   << " is formattable. Format it.";

            checkpoint_manager.Revert(&current_entry);

            if (current_entry.is_encryptable() && current_entry.key_loc != KEY_IN_FOOTER) {
                unique_fd fd(TEMP_FAILURE_RETRY(
                        open(current_entry.key_loc.c_str(), O_WRONLY | O_CLOEXEC)));
                if (fd >= 0) {
                    LINFO << __FUNCTION__ << "(): also wipe " << current_entry.key_loc;
                    wipe_block_device(fd, get_file_size(fd));
                } else {
                    PERROR << __FUNCTION__ << "(): " << current_entry.key_loc << " wouldn't open";
                }
            } else if (current_entry.is_encryptable() && current_entry.key_loc == KEY_IN_FOOTER) {
                crypt_footer = true;
            }
            if (fs_mgr_do_format(current_entry, crypt_footer) == 0) {
                // Let's replay the mount actions.
                i = top_idx - 1;
                continue;
            } else {
                LERROR << __FUNCTION__ << "(): Format failed. "
                       << "Suggest recovery...";
                encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
                continue;
            }
        }

        // mount(2) returned an error, handle the encryptable/formattable case.
        if (mount_errno != EBUSY && mount_errno != EACCES && attempted_entry.is_encryptable()) {
            if (wiped) {
                LERROR << __FUNCTION__ << "(): " << attempted_entry.blk_device << " is wiped and "
                       << attempted_entry.mount_point << " " << attempted_entry.fs_type
                       << " is encryptable. Suggest recovery...";
                encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
                continue;
            } else {
                // Need to mount a tmpfs at this mountpoint for now, and set
                // properties that vold will query later for decrypting
                LERROR << __FUNCTION__ << "(): possibly an encryptable blkdev "
                       << attempted_entry.blk_device << " for mount " << attempted_entry.mount_point
                       << " type " << attempted_entry.fs_type;
                if (fs_mgr_do_tmpfs_mount(attempted_entry.mount_point.c_str()) < 0) {
                    ++error_count;
                    continue;
                }
            }
            encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
        } else if (mount_errno != EBUSY && mount_errno != EACCES &&
                   should_use_metadata_encryption(attempted_entry)) {
            if (!call_vdc({"cryptfs", "mountFstab", attempted_entry.blk_device,
                           attempted_entry.mount_point},
                          nullptr)) {
                ++error_count;
            }
            encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED;
            continue;
        } else {
            // fs_options might be null so we cannot use PERROR << directly.
            // Use StringPrintf to output "(null)" instead.
            if (attempted_entry.fs_mgr_flags.no_fail) {
                PERROR << android::base::StringPrintf(
                        "Ignoring failure to mount an un-encryptable or wiped "
                        "partition on %s at %s options: %s",
                        attempted_entry.blk_device.c_str(), attempted_entry.mount_point.c_str(),
                        attempted_entry.fs_options.c_str());
            } else {
                PERROR << android::base::StringPrintf(
                        "Failed to mount an un-encryptable or wiped partition "
                        "on %s at %s options: %s",
                        attempted_entry.blk_device.c_str(), attempted_entry.mount_point.c_str(),
                        attempted_entry.fs_options.c_str());
                ++error_count;
            }
            continue;
        }
    }

#if ALLOW_ADBD_DISABLE_VERITY == 1  // "userdebug" build
    fs_mgr_overlayfs_mount_all(fstab);
#endif

    if (error_count) {
        return FS_MGR_MNTALL_FAIL;
    } else {
        return encryptable;
    }
}

int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab) {
    AvbUniquePtr avb_handle(nullptr);
    int ret = FsMgrUmountStatus::SUCCESS;
    for (auto& current_entry : *fstab) {
        if (!IsMountPointMounted(current_entry.mount_point)) {
            continue;
        }

        if (umount(current_entry.mount_point.c_str()) == -1) {
            PERROR << "Failed to umount " << current_entry.mount_point;
            ret |= FsMgrUmountStatus::ERROR_UMOUNT;
            continue;
        }

        if (current_entry.fs_mgr_flags.logical) {
            if (!fs_mgr_update_logical_partition(&current_entry)) {
                LERROR << "Could not get logical partition blk_device, skipping!";
                ret |= FsMgrUmountStatus::ERROR_DEVICE_MAPPER;
                continue;
            }
        }

        if (current_entry.fs_mgr_flags.avb || !current_entry.avb_keys.empty()) {
            if (!AvbHandle::TearDownAvbHashtree(&current_entry, true /* wait */)) {
                LERROR << "Failed to tear down AVB on mount point: " << current_entry.mount_point;
                ret |= FsMgrUmountStatus::ERROR_VERITY;
                continue;
            }
        } else if ((current_entry.fs_mgr_flags.verify)) {
            if (!fs_mgr_teardown_verity(&current_entry)) {
                LERROR << "Failed to tear down verified partition on mount point: "
                       << current_entry.mount_point;
                ret |= FsMgrUmountStatus::ERROR_VERITY;
                continue;
            }
        }
    }
    return ret;
}

static std::chrono::milliseconds GetMillisProperty(const std::string& name,
                                                   std::chrono::milliseconds default_value) {
    auto value = GetUintProperty(name, static_cast<uint64_t>(default_value.count()));
    return std::chrono::milliseconds(std::move(value));
}

static bool fs_mgr_unmount_all_data_mounts(const std::string& data_block_device) {
    LINFO << __FUNCTION__ << "(): about to umount everything on top of " << data_block_device;
    Timer t;
    auto timeout = GetMillisProperty("init.userspace_reboot.userdata_remount.timeoutmillis", 5s);
    while (true) {
        bool umount_done = true;
        Fstab proc_mounts;
        if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) {
            LERROR << __FUNCTION__ << "(): Can't read /proc/mounts";
            return false;
        }
        // Now proceed with other bind mounts on top of /data.
        for (const auto& entry : proc_mounts) {
            std::string block_device;
            if (StartsWith(entry.blk_device, "/dev/block") &&
                !Realpath(entry.blk_device, &block_device)) {
                PWARNING << __FUNCTION__ << "(): failed to realpath " << entry.blk_device;
                block_device = entry.blk_device;
            }
            if (data_block_device == block_device) {
                if (umount2(entry.mount_point.c_str(), 0) != 0) {
                    PERROR << __FUNCTION__ << "(): Failed to umount " << entry.mount_point;
                    umount_done = false;
                }
            }
        }
        if (umount_done) {
            LINFO << __FUNCTION__ << "(): Unmounting /data took " << t;
            return true;
        }
        if (t.duration() > timeout) {
            LERROR << __FUNCTION__ << "(): Timed out unmounting all mounts on "
                   << data_block_device;
            Fstab remaining_mounts;
            if (!ReadFstabFromFile("/proc/mounts", &remaining_mounts)) {
                LERROR << __FUNCTION__ << "(): Can't read /proc/mounts";
            } else {
                LERROR << __FUNCTION__ << "(): Following mounts remaining";
                for (const auto& e : remaining_mounts) {
                    LERROR << __FUNCTION__ << "(): mount point: " << e.mount_point
                           << " block device: " << e.blk_device;
                }
            }
            return false;
        }
        std::this_thread::sleep_for(50ms);
    }
}

static bool UnwindDmDeviceStack(const std::string& block_device,
                                std::vector<std::string>* dm_stack) {
    if (!StartsWith(block_device, "/dev/block/")) {
        LWARNING << block_device << " is not a block device";
        return false;
    }
    std::string current = block_device;
    DeviceMapper& dm = DeviceMapper::Instance();
    while (true) {
        dm_stack->push_back(current);
        if (!dm.IsDmBlockDevice(current)) {
            break;
        }
        auto parent = dm.GetParentBlockDeviceByPath(current);
        if (!parent) {
            return false;
        }
        current = *parent;
    }
    return true;
}

FstabEntry* fs_mgr_get_mounted_entry_for_userdata(Fstab* fstab,
                                                  const std::string& data_block_device) {
    std::vector<std::string> dm_stack;
    if (!UnwindDmDeviceStack(data_block_device, &dm_stack)) {
        LERROR << "Failed to unwind dm-device stack for " << data_block_device;
        return nullptr;
    }
    for (auto& entry : *fstab) {
        if (entry.mount_point != "/data") {
            continue;
        }
        std::string block_device;
        if (entry.fs_mgr_flags.logical) {
            if (!fs_mgr_update_logical_partition(&entry)) {
                LERROR << "Failed to update logic partition " << entry.blk_device;
                continue;
            }
            block_device = entry.blk_device;
        } else if (!Realpath(entry.blk_device, &block_device)) {
            PWARNING << "Failed to realpath " << entry.blk_device;
            block_device = entry.blk_device;
        }
        if (std::find(dm_stack.begin(), dm_stack.end(), block_device) != dm_stack.end()) {
            return &entry;
        }
    }
    LERROR << "Didn't find entry that was used to mount /data onto " << data_block_device;
    return nullptr;
}

// TODO(b/143970043): return different error codes based on which step failed.
int fs_mgr_remount_userdata_into_checkpointing(Fstab* fstab) {
    Fstab proc_mounts;
    if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) {
        LERROR << "Can't read /proc/mounts";
        return -1;
    }
    auto mounted_entry = GetEntryForMountPoint(&proc_mounts, "/data");
    if (mounted_entry == nullptr) {
        LERROR << "/data is not mounted";
        return -1;
    }
    std::string block_device;
    if (!Realpath(mounted_entry->blk_device, &block_device)) {
        PERROR << "Failed to realpath " << mounted_entry->blk_device;
        return -1;
    }
    auto fstab_entry = fs_mgr_get_mounted_entry_for_userdata(fstab, block_device);
    if (fstab_entry == nullptr) {
        LERROR << "Can't find /data in fstab";
        return -1;
    }
    bool force_umount = GetBoolProperty("sys.init.userdata_remount.force_umount", false);
    if (force_umount) {
        LINFO << "Will force an umount of userdata even if it's not required";
    }
    if (!force_umount && !SupportsCheckpoint(fstab_entry)) {
        LINFO << "Userdata doesn't support checkpointing. Nothing to do";
        return 0;
    }
    CheckpointManager checkpoint_manager;
    if (!force_umount && !checkpoint_manager.NeedsCheckpoint()) {
        LINFO << "Checkpointing not needed. Don't remount";
        return 0;
    }
    if (!force_umount && fstab_entry->fs_mgr_flags.checkpoint_fs) {
        // Userdata is f2fs, simply remount it.
        if (!checkpoint_manager.Update(fstab_entry)) {
            LERROR << "Failed to remount userdata in checkpointing mode";
            return -1;
        }
        if (mount(block_device.c_str(), fstab_entry->mount_point.c_str(), "none",
                  MS_REMOUNT | fstab_entry->flags, fstab_entry->fs_options.c_str()) != 0) {
            PERROR << "Failed to remount userdata in checkpointing mode";
            return -1;
        }
    } else {
        LINFO << "Unmounting /data before remounting into checkpointing mode";
        if (!fs_mgr_unmount_all_data_mounts(block_device)) {
            LERROR << "Failed to umount /data";
            return -1;
        }
        DeviceMapper& dm = DeviceMapper::Instance();
        while (dm.IsDmBlockDevice(block_device)) {
            auto next_device = dm.GetParentBlockDeviceByPath(block_device);
            auto name = dm.GetDmDeviceNameByPath(block_device);
            if (!name) {
                LERROR << "Failed to get dm-name for " << block_device;
                return -1;
            }
            LINFO << "Deleting " << block_device << " named " << *name;
            if (!dm.DeleteDevice(*name, 3s)) {
                return -1;
            }
            if (!next_device) {
                LERROR << "Failed to find parent device for " << block_device;
            }
            block_device = *next_device;
        }
        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;
    }
    return 0;
}

// wrapper to __mount() and expects a fully prepared fstab_rec,
// unlike fs_mgr_do_mount which does more things with avb / verity etc.
int fs_mgr_do_mount_one(const FstabEntry& entry, const std::string& mount_point) {
    // First check the filesystem if requested.
    if (entry.fs_mgr_flags.wait && !WaitForFile(entry.blk_device, 20s)) {
        LERROR << "Skipping mounting '" << entry.blk_device << "'";
    }

    // Run fsck if needed
    prepare_fs_for_mount(entry.blk_device, entry);

    int ret =
            __mount(entry.blk_device, mount_point.empty() ? entry.mount_point : mount_point, entry);
    if (ret) {
      ret = (errno == EBUSY) ? FS_MGR_DOMNT_BUSY : FS_MGR_DOMNT_FAILED;
    }

    return ret;
}

// If tmp_mount_point is non-null, mount the filesystem there.  This is for the
// tmp mount we do to check the user password
// If multiple fstab entries are to be mounted on "n_name", it will try to mount each one
// in turn, and stop on 1st success, or no more match.
static int fs_mgr_do_mount_helper(Fstab* fstab, const std::string& n_name,
                                  const std::string& n_blk_device, const char* tmp_mount_point,
                                  int needs_checkpoint, bool metadata_encrypted) {
    int mount_errors = 0;
    int first_mount_errno = 0;
    std::string mount_point;
    CheckpointManager checkpoint_manager(needs_checkpoint, metadata_encrypted);
    AvbUniquePtr avb_handle(nullptr);

    if (!fstab) {
        return FS_MGR_DOMNT_FAILED;
    }

    for (auto& fstab_entry : *fstab) {
        if (!fs_match(fstab_entry.mount_point, n_name)) {
            continue;
        }

        // We found our match.
        // If this swap or a raw partition, report an error.
        if (fstab_entry.fs_type == "swap" || fstab_entry.fs_type == "emmc" ||
            fstab_entry.fs_type == "mtd") {
            LERROR << "Cannot mount filesystem of type " << fstab_entry.fs_type << " on "
                   << n_blk_device;
            return FS_MGR_DOMNT_FAILED;
        }

        if (fstab_entry.fs_mgr_flags.logical) {
            if (!fs_mgr_update_logical_partition(&fstab_entry)) {
                LERROR << "Could not set up logical partition, skipping!";
                continue;
            }
        }

        WrapUserdataIfNeeded(&fstab_entry, n_blk_device);

        if (!checkpoint_manager.Update(&fstab_entry, n_blk_device)) {
            LERROR << "Could not set up checkpoint partition, skipping!";
            continue;
        }

        // First check the filesystem if requested.
        if (fstab_entry.fs_mgr_flags.wait && !WaitForFile(n_blk_device, 20s)) {
            LERROR << "Skipping mounting '" << n_blk_device << "'";
            continue;
        }

        int fs_stat = prepare_fs_for_mount(n_blk_device, fstab_entry);

        if (fstab_entry.fs_mgr_flags.avb) {
            if (!avb_handle) {
                avb_handle = AvbHandle::Open();
                if (!avb_handle) {
                    LERROR << "Failed to open AvbHandle";
                    return FS_MGR_DOMNT_FAILED;
                }
            }
            if (avb_handle->SetUpAvbHashtree(&fstab_entry, true /* wait_for_verity_dev */) ==
                AvbHashtreeResult::kFail) {
                LERROR << "Failed to set up AVB on partition: " << fstab_entry.mount_point
                       << ", skipping!";
                // Skips mounting the device.
                continue;
            }
        } else if (!fstab_entry.avb_keys.empty()) {
            if (AvbHandle::SetUpStandaloneAvbHashtree(&fstab_entry) == AvbHashtreeResult::kFail) {
                LERROR << "Failed to set up AVB on standalone partition: "
                       << fstab_entry.mount_point << ", skipping!";
                // Skips mounting the device.
                continue;
            }
        } else if (fstab_entry.fs_mgr_flags.verify) {
            int rc = fs_mgr_setup_verity(&fstab_entry, true);
            if (rc == FS_MGR_SETUP_VERITY_DISABLED || rc == FS_MGR_SETUP_VERITY_SKIPPED) {
                LINFO << "Verity disabled";
            } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
                LERROR << "Could not set up verified partition, skipping!";
                continue;
            }
        }

        // Now mount it where requested */
        if (tmp_mount_point) {
            mount_point = tmp_mount_point;
        } else {
            mount_point = fstab_entry.mount_point;
        }
        int retry_count = 2;
        while (retry_count-- > 0) {
            if (!__mount(n_blk_device, mount_point, fstab_entry)) {
                fs_stat &= ~FS_STAT_FULL_MOUNT_FAILED;
                return FS_MGR_DOMNT_SUCCESS;
            } else {
                if (retry_count <= 0) break;  // run check_fs only once
                if (!first_mount_errno) first_mount_errno = errno;
                mount_errors++;
                fs_stat |= FS_STAT_FULL_MOUNT_FAILED;
                // try again after fsck
                check_fs(n_blk_device, fstab_entry.fs_type, fstab_entry.mount_point, &fs_stat);
            }
        }
        log_fs_stat(fstab_entry.blk_device, fs_stat);
    }

    // Reach here means the mount attempt fails.
    if (mount_errors) {
        PERROR << "Cannot mount filesystem on " << n_blk_device << " at " << mount_point;
        if (first_mount_errno == EBUSY) return FS_MGR_DOMNT_BUSY;
    } else {
        // We didn't find a match, say so and return an error.
        LERROR << "Cannot find mount point " << n_name << " in fstab";
    }
    return FS_MGR_DOMNT_FAILED;
}

int fs_mgr_do_mount(Fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point) {
    return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, -1, false);
}

int fs_mgr_do_mount(Fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point,
                    bool needs_checkpoint, bool metadata_encrypted) {
    return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, needs_checkpoint,
                                  metadata_encrypted);
}

/*
 * mount a tmpfs filesystem at the given point.
 * return 0 on success, non-zero on failure.
 */
int fs_mgr_do_tmpfs_mount(const char *n_name)
{
    int ret;

    ret = mount("tmpfs", n_name, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV | MS_NOEXEC,
                CRYPTO_TMPFS_OPTIONS);
    if (ret < 0) {
        LERROR << "Cannot mount tmpfs filesystem at " << n_name;
        return -1;
    }

    /* Success */
    return 0;
}

static bool InstallZramDevice(const std::string& device) {
    if (!android::base::WriteStringToFile(device, ZRAM_BACK_DEV)) {
        PERROR << "Cannot write " << device << " in: " << ZRAM_BACK_DEV;
        return false;
    }
    LINFO << "Success to set " << device << " to " << ZRAM_BACK_DEV;
    return true;
}

static bool PrepareZramBackingDevice(off64_t size) {

    constexpr const char* file_path = "/data/per_boot/zram_swap";
    if (size == 0) return true;

    // Prepare target path
    unique_fd target_fd(TEMP_FAILURE_RETRY(open(file_path, O_RDWR | O_CREAT | O_CLOEXEC, 0600)));
    if (target_fd.get() == -1) {
        PERROR << "Cannot open target path: " << file_path;
        return false;
    }
    if (fallocate(target_fd.get(), 0, 0, size) < 0) {
        PERROR << "Cannot truncate target path: " << file_path;
        return false;
    }

    // Allocate loop device and attach it to file_path.
    LoopControl loop_control;
    std::string device;
    if (!loop_control.Attach(target_fd.get(), 5s, &device)) {
        return false;
    }

    // set block size & direct IO
    unique_fd device_fd(TEMP_FAILURE_RETRY(open(device.c_str(), O_RDWR | O_CLOEXEC)));
    if (device_fd.get() == -1) {
        PERROR << "Cannot open " << device;
        return false;
    }
    if (!LoopControl::EnableDirectIo(device_fd.get())) {
        return false;
    }

    return InstallZramDevice(device);
}

bool fs_mgr_swapon_all(const Fstab& fstab) {
    bool ret = true;
    for (const auto& entry : fstab) {
        // Skip non-swap entries.
        if (entry.fs_type != "swap") {
            continue;
        }

        if (entry.zram_size > 0) {
	    if (!PrepareZramBackingDevice(entry.zram_backingdev_size)) {
                LERROR << "Failure of zram backing device file for '" << entry.blk_device << "'";
            }
            // A zram_size was specified, so we need to configure the
            // device.  There is no point in having multiple zram devices
            // on a system (all the memory comes from the same pool) so
            // we can assume the device number is 0.
            if (entry.max_comp_streams >= 0) {
                auto zram_mcs_fp = std::unique_ptr<FILE, decltype(&fclose)>{
                        fopen(ZRAM_CONF_MCS, "re"), fclose};
                if (zram_mcs_fp == nullptr) {
                    LERROR << "Unable to open zram conf comp device " << ZRAM_CONF_MCS;
                    ret = false;
                    continue;
                }
                fprintf(zram_mcs_fp.get(), "%d\n", entry.max_comp_streams);
            }

            auto zram_fp =
                    std::unique_ptr<FILE, decltype(&fclose)>{fopen(ZRAM_CONF_DEV, "re+"), fclose};
            if (zram_fp == nullptr) {
                LERROR << "Unable to open zram conf device " << ZRAM_CONF_DEV;
                ret = false;
                continue;
            }
            fprintf(zram_fp.get(), "%" PRId64 "\n", entry.zram_size);
        }

        if (entry.fs_mgr_flags.wait && !WaitForFile(entry.blk_device, 20s)) {
            LERROR << "Skipping mkswap for '" << entry.blk_device << "'";
            ret = false;
            continue;
        }

        // Initialize the swap area.
        const char* mkswap_argv[2] = {
                MKSWAP_BIN,
                entry.blk_device.c_str(),
        };
        int err = logwrap_fork_execvp(ARRAY_SIZE(mkswap_argv), mkswap_argv, nullptr, false,
                                      LOG_KLOG, false, nullptr);
        if (err) {
            LERROR << "mkswap failed for " << entry.blk_device;
            ret = false;
            continue;
        }

        /* If -1, then no priority was specified in fstab, so don't set
         * SWAP_FLAG_PREFER or encode the priority */
        int flags = 0;
        if (entry.swap_prio >= 0) {
            flags = (entry.swap_prio << SWAP_FLAG_PRIO_SHIFT) & SWAP_FLAG_PRIO_MASK;
            flags |= SWAP_FLAG_PREFER;
        } else {
            flags = 0;
        }
        err = swapon(entry.blk_device.c_str(), flags);
        if (err) {
            LERROR << "swapon failed for " << entry.blk_device;
            ret = false;
        }
    }

    return ret;
}

bool fs_mgr_is_verity_enabled(const FstabEntry& entry) {
    if (!entry.fs_mgr_flags.verify && !entry.fs_mgr_flags.avb) {
        return false;
    }

    DeviceMapper& dm = DeviceMapper::Instance();

    std::string mount_point = GetVerityDeviceName(entry);
    if (dm.GetState(mount_point) == DmDeviceState::INVALID) {
        return false;
    }

    const char* status;
    std::vector<DeviceMapper::TargetInfo> table;
    if (!dm.GetTableStatus(mount_point, &table) || table.empty() || table[0].data.empty()) {
        if (!entry.fs_mgr_flags.verify_at_boot) {
            return false;
        }
        status = "V";
    } else {
        status = table[0].data.c_str();
    }

    if (*status == 'C' || *status == 'V') {
        return true;
    }

    return false;
}

bool fs_mgr_verity_is_check_at_most_once(const android::fs_mgr::FstabEntry& entry) {
    if (!entry.fs_mgr_flags.verify && !entry.fs_mgr_flags.avb) {
        return false;
    }

    DeviceMapper& dm = DeviceMapper::Instance();
    std::string device = GetVerityDeviceName(entry);

    std::vector<DeviceMapper::TargetInfo> table;
    if (dm.GetState(device) == DmDeviceState::INVALID || !dm.GetTableInfo(device, &table)) {
        return false;
    }
    for (const auto& target : table) {
        if (strcmp(target.spec.target_type, "verity") == 0 &&
            target.data.find("check_at_most_once") != std::string::npos) {
            return true;
        }
    }
    return false;
}

std::string fs_mgr_get_super_partition_name(int slot) {
    // Devices upgrading to dynamic partitions are allowed to specify a super
    // partition name. This includes cuttlefish, which is a non-A/B device.
    std::string super_partition;
    if (fs_mgr_get_boot_config_from_kernel_cmdline("super_partition", &super_partition)) {
        if (fs_mgr_get_slot_suffix().empty()) {
            return super_partition;
        }
        std::string suffix;
        if (slot == 0) {
            suffix = "_a";
        } else if (slot == 1) {
            suffix = "_b";
        } else if (slot == -1) {
            suffix = fs_mgr_get_slot_suffix();
        }
        return super_partition + suffix;
    }
    return LP_METADATA_DEFAULT_PARTITION_NAME;
}
