diff --git a/common.h b/common.h index d99daaf..e6e8f85 100644 --- a/common.h +++ b/common.h @@ -99,6 +99,12 @@ typedef struct { const char* device2; // alternative device to try if fs_type // == "ext4" or "vfat" and mounting // 'device' fails + + long long length; // (ext4 partition only) when + // formatting, size to use for the + // partition. 0 or negative number + // means to format all but the last + // (that much). } Volume; #endif // RECOVERY_COMMON_H diff --git a/roots.c b/roots.c index 5731d74..cb7e067 100644 --- a/roots.c +++ b/roots.c @@ -31,6 +31,21 @@ static int num_volumes = 0; static Volume* device_volumes = NULL; +static int parse_options(char* options, Volume* volume) { + char* option; + while (option = strtok(options, ",")) { + options = NULL; + + if (strncmp(option, "length=", 7) == 0) { + volume->length = strtoll(option+7, NULL, 10); + } else { + LOGE("bad option \"%s\"\n", option); + return -1; + } + } + return 0; +} + void load_volume_table() { int alloc = 2; device_volumes = malloc(alloc * sizeof(Volume)); @@ -40,6 +55,7 @@ void load_volume_table() { device_volumes[0].fs_type = "ramdisk"; device_volumes[0].device = NULL; device_volumes[0].device2 = NULL; + device_volumes[0].length = 0; num_volumes = 1; FILE* fstab = fopen("/etc/recovery.fstab", "r"); @@ -61,7 +77,16 @@ void load_volume_table() { char* device = strtok(NULL, " \t\n"); // lines may optionally have a second device, to use if // mounting the first one fails. + char* options = NULL; char* device2 = strtok(NULL, " \t\n"); + if (device2) { + if (device2[0] == '/') { + options = strtok(NULL, " \t\n"); + } else { + options = device2; + device2 = NULL; + } + } if (mount_point && fs_type && device) { while (num_volumes >= alloc) { @@ -73,7 +98,13 @@ void load_volume_table() { device_volumes[num_volumes].device = strdup(device); device_volumes[num_volumes].device2 = device2 ? strdup(device2) : NULL; - ++num_volumes; + + device_volumes[num_volumes].length = 0; + if (parse_options(options, device_volumes + num_volumes) != 0) { + LOGE("skipping malformed recovery.fstab line: %s\n", original); + } else { + ++num_volumes; + } } else { LOGE("skipping malformed recovery.fstab line: %s\n", original); } @@ -86,8 +117,8 @@ void load_volume_table() { printf("=========================\n"); for (i = 0; i < num_volumes; ++i) { Volume* v = &device_volumes[i]; - printf(" %d %s %s %s %s\n", i, v->mount_point, v->fs_type, - v->device, v->device2); + printf(" %d %s %s %s %s %lld\n", i, v->mount_point, v->fs_type, + v->device, v->device2, v->length); } printf("\n"); } @@ -238,12 +269,7 @@ int format_volume(const char* volume) { } if (strcmp(v->fs_type, "ext4") == 0) { - s64 len = 0; - - if (strcmp(volume, "/data") == 0) { - len = -16384; /* Reserve 16 Kbytes for the crypto footer */ - } - int result = make_ext4fs(v->device, len); + int result = make_ext4fs(v->device, v->length); if (result != 0) { LOGE("format_volume: make_extf4fs failed on %s\n", v->device); return -1;