summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common.h6
-rw-r--r--roots.c44
2 files changed, 41 insertions, 9 deletions
diff --git a/common.h b/common.h
index d99daaf86..e6e8f8564 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 5731d7407..cb7e067a1 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;