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

Commit 29bc5d49 authored by Daniel Rosenberg's avatar Daniel Rosenberg
Browse files

Add support for casefold and product ID to format

Product ID Quotas require wider inodes. For Ext4, quotas and casefolding
are enabled later via tune2fs

Bug: 138322712
Bug: 138321217
Test: Build with and without casefolding and quotas. Verify fs features
Change-Id: I99819f6c38adabcf7a1f944085f9005134e6fc5f
parent 1fad2b39
Loading
Loading
Loading
Loading
+44 −19
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <cutils/partition_utils.h>
#include <sys/mount.h>

#include <android-base/properties.h>
#include <android-base/unique_fd.h>
#include <ext4_utils/ext4.h>
#include <ext4_utils/ext4_utils.h>
@@ -57,7 +58,7 @@ static int get_dev_sz(const std::string& fs_blkdev, uint64_t* dev_sz) {
}

static int format_ext4(const std::string& fs_blkdev, const std::string& fs_mnt_point,
                       bool crypt_footer) {
                       bool crypt_footer, bool needs_projid) {
    uint64_t dev_sz;
    int rc = 0;

@@ -72,11 +73,20 @@ static int format_ext4(const std::string& fs_blkdev, const std::string& fs_mnt_p
    }

    std::string size_str = std::to_string(dev_sz / 4096);
    const char* const mke2fs_args[] = {
            "/system/bin/mke2fs", "-t",   "ext4", "-b", "4096", fs_blkdev.c_str(),
            size_str.c_str(),     nullptr};

    rc = logwrap_fork_execvp(arraysize(mke2fs_args), mke2fs_args, nullptr, false, LOG_KLOG, true,
    std::vector<const char*> mke2fs_args = {"/system/bin/mke2fs", "-t", "ext4", "-b", "4096"};

    // Project ID's require wider inodes. The Quotas themselves are enabled by tune2fs during boot.
    if (needs_projid) {
        mke2fs_args.push_back("-I");
        mke2fs_args.push_back("512");
    }
    // casefolding is enabled via tune2fs during boot.

    mke2fs_args.push_back(fs_blkdev.c_str());
    mke2fs_args.push_back(size_str.c_str());

    rc = logwrap_fork_execvp(mke2fs_args.size(), mke2fs_args.data(), nullptr, false, LOG_KLOG, true,
                             nullptr);
    if (rc) {
        LERROR << "mke2fs returned " << rc;
@@ -95,7 +105,8 @@ static int format_ext4(const std::string& fs_blkdev, const std::string& fs_mnt_p
    return rc;
}

static int format_f2fs(const std::string& fs_blkdev, uint64_t dev_sz, bool crypt_footer) {
static int format_f2fs(const std::string& fs_blkdev, uint64_t dev_sz, bool crypt_footer,
                       bool needs_projid, bool needs_casefold) {
    if (!dev_sz) {
        int rc = get_dev_sz(fs_blkdev, &dev_sz);
        if (rc) {
@@ -109,26 +120,40 @@ static int format_f2fs(const std::string& fs_blkdev, uint64_t dev_sz, bool crypt
    }

    std::string size_str = std::to_string(dev_sz / 4096);
    // clang-format off
    const char* const args[] = {
        "/system/bin/make_f2fs",
        "-g", "android",
        fs_blkdev.c_str(),
        size_str.c_str(),
        nullptr
    };
    // clang-format on

    return logwrap_fork_execvp(arraysize(args), args, nullptr, false, LOG_KLOG, true, nullptr);
    std::vector<const char*> args = {"/system/bin/make_f2fs", "-g", "android"};
    if (needs_projid) {
        args.push_back("-O");
        args.push_back("project_quota,extra_attr");
    }
    if (needs_casefold) {
        args.push_back("-O");
        args.push_back("casefold");
        args.push_back("-C");
        args.push_back("utf8");
    }
    args.push_back(fs_blkdev.c_str());
    args.push_back(size_str.c_str());

    return logwrap_fork_execvp(args.size(), args.data(), nullptr, false, LOG_KLOG, true, nullptr);
}

int fs_mgr_do_format(const FstabEntry& entry, bool crypt_footer) {
    LERROR << __FUNCTION__ << ": Format " << entry.blk_device << " as '" << entry.fs_type << "'";

    bool needs_casefold = false;
    bool needs_projid = false;

    if (entry.mount_point == "/data") {
        needs_casefold = android::base::GetBoolProperty("ro.emulated_storage.casefold", false);
        needs_projid = android::base::GetBoolProperty("ro.emulated_storage.projid", false);
    }

    if (entry.fs_type == "f2fs") {
        return format_f2fs(entry.blk_device, entry.length, crypt_footer);
        return format_f2fs(entry.blk_device, entry.length, crypt_footer, needs_projid,
                           needs_casefold);
    } else if (entry.fs_type == "ext4") {
        return format_ext4(entry.blk_device, entry.mount_point, crypt_footer);
        return format_ext4(entry.blk_device, entry.mount_point, crypt_footer, needs_projid);
    } else {
        LERROR << "File system type '" << entry.fs_type << "' is not supported";
        return -EINVAL;