diff --git a/Android.mk b/Android.mk index 5348e365..344d5ad3 100644 --- a/Android.mk +++ b/Android.mk @@ -84,9 +84,11 @@ LOCAL_MODULE := recovery LOCAL_FORCE_STATIC_EXECUTABLE := true +LOCAL_REQUIRED_MODULES := e2fsdroid_static mke2fs_static mke2fs.conf + ifeq ($(TARGET_USERIMAGES_USE_F2FS),true) ifeq ($(HOST_OS),linux) -LOCAL_REQUIRED_MODULES := mkfs.f2fs +LOCAL_REQUIRED_MODULES += mkfs.f2fs endif endif @@ -101,6 +103,7 @@ LOCAL_STATIC_LIBRARIES := \ libverifier \ libbatterymonitor \ libbootloader_message \ + libfs_mgr \ libext4_utils \ libsparse \ libziparchive \ @@ -111,7 +114,6 @@ LOCAL_STATIC_LIBRARIES := \ libfusesideload \ libminui \ libpng \ - libfs_mgr \ libcrypto_utils \ libcrypto \ libvintf_recovery \ @@ -140,7 +142,7 @@ else endif ifeq ($(BOARD_CACHEIMAGE_PARTITION_SIZE),) -LOCAL_REQUIRED_MODULES := recovery-persist recovery-refresh +LOCAL_REQUIRED_MODULES += recovery-persist recovery-refresh endif include $(BUILD_EXECUTABLE) diff --git a/roots.cpp b/roots.cpp index 9b427025..e98dfd44 100644 --- a/roots.cpp +++ b/roots.cpp @@ -27,7 +27,8 @@ #include #include -#include +#include +#include #include #include @@ -215,11 +216,60 @@ int format_volume(const char* volume, const char* directory) { } int result; if (strcmp(v->fs_type, "ext4") == 0) { - if (v->erase_blk_size != 0 && v->logical_blk_size != 0) { - result = make_ext4fs_directory_align(v->blk_device, length, volume, sehandle, - directory, v->erase_blk_size, v->logical_blk_size); - } else { - result = make_ext4fs_directory(v->blk_device, length, volume, sehandle, directory); + static constexpr int block_size = 4096; + int raid_stride = v->logical_blk_size / block_size; + int raid_stripe_width = v->erase_blk_size / block_size; + + // stride should be the max of 8kb and logical block size + if (v->logical_blk_size != 0 && v->logical_blk_size < 8192) { + raid_stride = 8192 / block_size; + } + + const char* mke2fs_argv[] = { "/sbin/mke2fs_static", + "-F", + "-t", + "ext4", + "-b", + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr }; + + int i = 5; + std::string block_size_str = std::to_string(block_size); + mke2fs_argv[i++] = block_size_str.c_str(); + + std::string ext_args; + if (v->erase_blk_size != 0 && v->logical_blk_size != 0) { + ext_args = android::base::StringPrintf("stride=%d,stripe-width=%d", raid_stride, + raid_stripe_width); + mke2fs_argv[i++] = "-E"; + mke2fs_argv[i++] = ext_args.c_str(); + } + + mke2fs_argv[i++] = v->blk_device; + + std::string size_str = std::to_string(length / block_size); + if (length != 0) { + mke2fs_argv[i++] = size_str.c_str(); + } + + result = exec_cmd(mke2fs_argv[0], const_cast(mke2fs_argv)); + if (result == 0 && directory != nullptr) { + const char* e2fsdroid_argv[] = { "/sbin/e2fsdroid_static", + "-e", + "-S", + "/file_contexts", + "-f", + directory, + "-a", + volume, + v->blk_device, + nullptr }; + + result = exec_cmd(e2fsdroid_argv[0], const_cast(e2fsdroid_argv)); } } else { /* Has to be f2fs because we checked earlier. */ if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0 && length < 0) { diff --git a/updater/install.cpp b/updater/install.cpp index ff79edce..c9a3a079 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -302,9 +302,32 @@ Value* FormatFn(const char* name, State* state, const std::vector(mke2fs_argv)); if (status != 0) { - LOG(ERROR) << name << ": make_ext4fs failed (" << status << ") on " << location; + LOG(WARNING) << name << ": mke2fs failed (" << status << ") on " << location + << ", falling back to make_ext4fs"; + status = make_ext4fs(location.c_str(), size, mount_point.c_str(), sehandle); + if (status != 0) { + LOG(ERROR) << name << ": make_ext4fs failed (" << status << ") on " << location; + return StringValue(""); + } + return StringValue(location); + } + + const char* e2fsdroid_argv[] = { "/sbin/e2fsdroid_static", "-e", "-S", + "/file_contexts", "-a", mount_point.c_str(), + location.c_str(), nullptr }; + status = exec_cmd(e2fsdroid_argv[0], const_cast(e2fsdroid_argv)); + if (status != 0) { + LOG(ERROR) << name << ": e2fsdroid failed (" << status << ") on " << location; return StringValue(""); } return StringValue(location);