Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4c69bf9 authored by philz-cwm6's avatar philz-cwm6 Committed by Gerrit Code Review
Browse files

fix the following bugs to better handle new vold code

- do not show partition sdcard entries for vold managed volumes until we have a valid blk_device2. That also caused a memory overflow
- make it possible again to partition old style blk_device volumes
- enable format voldmanaged devices to ext2 and ext3 with existing binaries by using optional blk_device2 (defined in recovery to NULL but not currently implemented by fs_mgr
- fix unexpected behavior when in format/partition menus and insert an usb key (REFRESH return code)
- ensure_path_unmounted() could not unmount /sdcard path on /data/media devices
- format_device() and format_volume() properly handle /sdcard path argument on /data/media devices

Change-Id: I2d5872690805e70175ba1346fd03978e3c2b879e
parent cd352084
Loading
Loading
Loading
Loading
+42 −15
Original line number Diff line number Diff line
@@ -1197,8 +1197,13 @@ out:
}

void format_sdcard(const char* volume) {
    // datamedia check is probably useless, but added for extra care
    if (!can_partition(volume) || is_data_media_volume_path(volume))
    if (is_data_media_volume_path(volume))
        return;

    Volume *vol = volume_for_path(volume);
    if (vol == NULL || strcmp(vol->fs_type, "auto") != 0)
        return;
    if (!fs_mgr_is_voldmanaged(vol) && !can_partition(volume))
        return;

    char* headers[] = {"Format device:", volume, "", NULL };
@@ -1216,7 +1221,7 @@ void format_sdcard(const char* volume) {
    int ret = -1;
    char cmd[PATH_MAX];
    int chosen_item = get_menu_selection(headers, list, 0, 0);
    if (chosen_item == GO_BACK)
    if (chosen_item < 0) // REFRESH or GO_BACK
        return;
    if (!confirm_selection( "Confirm formatting?", "Yes - Format device"))
        return;
@@ -1251,9 +1256,15 @@ void format_sdcard(const char* volume) {
            break;
        case 5:
        case 6:
            ret = format_unknown_device(v->blk_device, v->mount_point, list[chosen_item]);
            {
                // workaround for new vold managed volumes that cannot be recognized by prebuilt ext2/ext3 bins
                const char *device = v->blk_device2;
                if (device == NULL)
                    device = v->blk_device;
                ret = format_unknown_device(device, v->mount_point, list[chosen_item]);
                break;
            }
    }

    if (ret)
        ui_print("Could not format %s (%s)\n", volume, list[chosen_item]);
@@ -1292,20 +1303,25 @@ static void partition_sdcard(const char* volume) {
    static const char* fstype_headers[] = {"Partition Type", "", NULL };

    int ext_size = get_menu_selection(ext_headers, ext_sizes, 0, 0);
    if (ext_size == GO_BACK)
    if (ext_size < 0)
        return;

    int swap_size = get_menu_selection(swap_headers, swap_sizes, 0, 0);
    if (swap_size == GO_BACK)
    if (swap_size < 0)
        return;

    int partition_type = get_menu_selection(fstype_headers, partition_types, 0, 0);
    if (partition_type == GO_BACK)
    if (partition_type < 0)
        return;

    char sddevice[256];
    Volume *vol = volume_for_path(volume);

    // can_partition() ensured either blk_device or blk_device2 has /dev/block/mmcblk format
    if (strstr(vol->blk_device, "/dev/block/mmcblk") != NULL)
        strcpy(sddevice, vol->blk_device);
    else strcpy(sddevice, vol->blk_device2);

    // we only want the mmcblk, not the partition
    sddevice[strlen("/dev/block/mmcblkX")] = '\0';
    char cmd[PATH_MAX];
@@ -1327,16 +1343,27 @@ int can_partition(const char* volume) {
        LOGI("Can't format unknown volume: %s\n", volume);
        return 0;
    }
    if (strcmp(vol->fs_type, "auto") != 0) {
        LOGI("Can't partition non-vfat: %s (%s)\n", volume, vol->fs_type);
        return 0;
    }

    int vol_len = strlen(vol->blk_device);
    // do not allow partitioning of a device that isn't mmcblkX or mmcblkXp1
    if (vol->blk_device[vol_len - 2] == 'p' && vol->blk_device[vol_len - 1] != '1') {
        LOGI("Can't partition unsafe device: %s\n", vol->blk_device);
    // needed with new vold managed volumes and virtual device path links
    int vol_len;
    char *device = NULL;
    if (strstr(vol->blk_device, "/dev/block/mmcblk") != NULL) {
        device = vol->blk_device;
    } else if (vol->blk_device2 != NULL && strstr(vol->blk_device2, "/dev/block/mmcblk") != NULL) {
        device = vol->blk_device2;
    } else {
        LOGI("Can't partition non mmcblk device: %s\n", vol->blk_device);
        return 0;
    }

    if (strcmp(vol->fs_type, "auto") != 0) {
        LOGI("Can't partition non-vfat: %s\n", vol->fs_type);
    vol_len = strlen(device);
    if (device[vol_len - 2] == 'p' && device[vol_len - 1] != '1') {
        LOGI("Can't partition unsafe device: %s\n", device);
        return 0;
    }

+16 −14
Original line number Diff line number Diff line
@@ -283,6 +283,9 @@ static int ignore_data_media = 0;

int ensure_path_unmounted(const char* path) {
    // if we are using /data/media, do not ever unmount volumes /data or /sdcard
    if (is_data_media_volume_path(path)) {
        return ensure_path_unmounted("/data");
    }
    if (strstr(path, "/data") == path && is_data_media() && !ignore_data_media) {
        return 0;
    }
@@ -292,9 +295,7 @@ int ensure_path_unmounted(const char* path) {
        LOGE("unknown volume for path [%s]\n", path);
        return -1;
    }
    if (is_data_media_volume_path(path)) {
        return ensure_path_unmounted("/data");
    }

    if (strcmp(v->fs_type, "ramdisk") == 0) {
        // the ramdisk is always mounted; you can't unmount it.
        return -1;
@@ -323,11 +324,20 @@ int ensure_path_unmounted(const char* path) {
extern struct selabel_handle *sehandle;

int format_volume(const char* volume) {
    if (is_data_media_volume_path(volume)) {
        return format_unknown_device(NULL, volume, NULL);
    }
    // check to see if /data is being formatted, and if it is /data/media
    // Note: the /sdcard check is redundant probably, just being safe.
    if (strstr(volume, "/data") == volume && is_data_media() && !ignore_data_media) {
        return format_unknown_device(NULL, volume, NULL);
    }

    Volume* v = volume_for_path(volume);
    if (v == NULL) {
        // silent failure for sd-ext
        if (strcmp(volume, "/sd-ext") != 0)
            LOGE("unknown volume \"%s\"\n", volume);
            LOGE("unknown volume '%s'\n", volume);
        return -1;
    }
    // silent failure to format non existing sd-ext when defined in recovery.fstab
@@ -339,8 +349,8 @@ int format_volume(const char* volume) {
        }
    }

    // Only use vold format for exact matches (otherwise /sdcard will be
    // formatted instead of /sdcard/.android_secure)
    // Only use vold format for exact matches otherwise /sdcard will be
    // formatted instead of /storage/sdcard0/.android_secure
    if (fs_mgr_is_voldmanaged(v) && strcmp(volume, v->mount_point) == 0) {
        if (ensure_path_unmounted(volume) != 0) {
            LOGE("format_volume failed to unmount %s", v->mount_point);
@@ -348,14 +358,6 @@ int format_volume(const char* volume) {
        return vold_format_volume(v->mount_point, 1) == CommandOkay ? 0 : -1;
    }

    if (is_data_media_volume_path(volume)) {
        return format_unknown_device(NULL, volume, NULL);
    }
    // check to see if /data is being formatted, and if it is /data/media
    // Note: the /sdcard check is redundant probably, just being safe.
    if (strstr(volume, "/data") == volume && is_data_media() && !ignore_data_media) {
        return format_unknown_device(NULL, volume, NULL);
    }
    if (strcmp(v->fs_type, "ramdisk") == 0) {
        // you can't format the ramdisk.
        LOGE("can't format_volume \"%s\"", volume);