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
This commit is contained in:
Daniel Rosenberg 2020-01-31 18:27:41 -08:00
parent 1fad2b39a3
commit 29bc5d4924
1 changed files with 43 additions and 18 deletions

View File

@ -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;