From 37aedb3fafcccd0da5bd9089987f05895c27492d Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Mon, 16 Jun 2014 19:07:39 -0700 Subject: Support F2FS for the data partition This adds F2FS support - for wiping a device - for the install "format" command. Note: crypto data in "footer" with a default/negative length is not supported, unlike with "ext4". Change-Id: I8d141a0d4d14df9fe84d3b131484e9696fcd8870 Signed-off-by: JP Abgrall --- Android.mk | 6 ++++++ roots.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++------------ updater/install.c | 37 +++++++++++++++++++++++++++++++-- 3 files changed, 90 insertions(+), 15 deletions(-) diff --git a/Android.mk b/Android.mk index 577679c06..1970956b5 100644 --- a/Android.mk +++ b/Android.mk @@ -32,6 +32,12 @@ LOCAL_MODULE := recovery LOCAL_FORCE_STATIC_EXECUTABLE := true +# Not working as expected? +# LOCAL_ADDITIONAL_DEPENDENCIES := mkfs.f2fs +# LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_RECOVERY_ROOT_OUT)/sbin/mkfs.f2fs +LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_ROOT_OUT_SBIN)/mkfs.f2fs + + RECOVERY_API_VERSION := 3 RECOVERY_FSTAB_VERSION := 2 LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION) diff --git a/roots.cpp b/roots.cpp index 66481a3b9..8f9901908 100644 --- a/roots.cpp +++ b/roots.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -151,6 +152,20 @@ int ensure_path_unmounted(const char* path) { return unmount_mounted_volume(mv); } +static int exec_cmd(const char* path, char* const argv[]) { + int status; + pid_t child; + if ((child = vfork()) == 0) { + execv(path, argv); + _exit(-1); + } + waitpid(child, &status, 0); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + LOGE("%s failed with status %d\n", path, WEXITSTATUS(status)); + } + return WEXITSTATUS(status); +} + int format_volume(const char* volume) { Volume* v = volume_for_path(volume); if (v == NULL) { @@ -195,19 +210,7 @@ int format_volume(const char* volume) { return 0; } - if (strcmp(v->fs_type, "ext4") == 0) { - ssize_t length = 0; - if (v->length != 0) { - length = v->length; - } else if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0) { - length = -CRYPT_FOOTER_OFFSET; - } - int result = make_ext4fs(v->blk_device, length, volume, sehandle); - if (result != 0) { - LOGE("format_volume: make_extf4fs failed on %s\n", v->blk_device); - return -1; - } - + if (strcmp(v->fs_type, "ext4") == 0 || strcmp(v->fs_type, "f2fs") == 0) { // if there's a key_loc that looks like a path, it should be a // block device for storing encryption metadata. wipe it too. if (v->key_loc != NULL && v->key_loc[0] == '/') { @@ -221,6 +224,39 @@ int format_volume(const char* volume) { close(fd); } + ssize_t length = 0; + if (v->length != 0) { + length = v->length; + } else if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0) { + length = -CRYPT_FOOTER_OFFSET; + } + int result; + if (strcmp(v->fs_type, "ext4") == 0) { + result = make_ext4fs(v->blk_device, length, volume, sehandle); + } else { /* Has to be f2fs because we checked earlier. */ + if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0 && length < 0) { + LOGE("format_volume: crypt footer + negative length (%lld) not supported on %s\n", v->fs_type, length); + return -1; + } + if (length < 0) { + LOGE("format_volume: negative length (%ld) not supported on %s\n", length, v->fs_type); + return -1; + } + char *num_sectors; + if (asprintf(&num_sectors, "%ld", length / 512) <= 0) { + LOGE("format_volume: failed to create %s command for %s\n", v->fs_type, v->blk_device); + return -1; + } + const char *f2fs_path = "/sbin/mkfs.f2fs"; + const char* const f2fs_argv[] = {"mkfs.f2fs", "-t", "-d1", v->blk_device, num_sectors, NULL}; + + result = exec_cmd(f2fs_path, (char* const*)f2fs_argv); + free(num_sectors); + } + if (result != 0) { + LOGE("format_volume: make %s failed on %s with %d(%s)\n", v->fs_type, v->blk_device, result, strerror(errno)); + return -1; + } return 0; } diff --git a/updater/install.c b/updater/install.c index 42f228972..edc386dc6 100644 --- a/updater/install.c +++ b/updater/install.c @@ -211,14 +211,29 @@ done: return StringValue(result); } +static int exec_cmd(const char* path, char* const argv[]) { + int status; + pid_t child; + if ((child = vfork()) == 0) { + execv(path, argv); + _exit(-1); + } + waitpid(child, &status, 0); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + printf("%s failed with status %d\n", path, WEXITSTATUS(status)); + } + return WEXITSTATUS(status); +} + // format(fs_type, partition_type, location, fs_size, mount_point) // // fs_type="yaffs2" partition_type="MTD" location=partition fs_size= mount_point= // fs_type="ext4" partition_type="EMMC" location=device fs_size= mount_point= -// if fs_size == 0, then make_ext4fs uses the entire partition. +// fs_type="f2fs" partition_type="EMMC" location=device fs_size= mount_point= +// if fs_size == 0, then make fs uses the entire partition. // if fs_size > 0, that is the size to use -// if fs_size < 0, then reserve that many bytes at the end of the partition +// if fs_size < 0, then reserve that many bytes at the end of the partition (not for "f2fs") Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; if (argc != 5) { @@ -290,6 +305,24 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } result = location; + } else if (strcmp(fs_type, "f2fs") == 0) { + char *num_sectors; + if (asprintf(&num_sectors, "%lld", atoll(fs_size) / 512) <= 0) { + printf("format_volume: failed to create %s command for %s\n", fs_type, location); + result = strdup(""); + goto done; + } + const char *f2fs_path = "/sbin/mkfs.f2fs"; + const char* const f2fs_argv[] = {"mkfs.f2fs", "-t", "-d1", location, num_sectors, NULL}; + int status = exec_cmd(f2fs_path, (char* const*)f2fs_argv); + free(num_sectors); + if (status != 0) { + printf("%s: mkfs.f2fs failed (%d) on %s", + name, status, location); + result = strdup(""); + goto done; + } + result = location; #endif } else { printf("%s: unsupported fs_type \"%s\" partition_type \"%s\"", -- cgit v1.2.3