diff --git a/crypto/lollipop/cryptfs.c b/crypto/lollipop/cryptfs.c
index 0277c78..90f1523 100644
--- a/crypto/lollipop/cryptfs.c
+++ b/crypto/lollipop/cryptfs.c
@@ -37,27 +37,17 @@
 #include <sys/mount.h>
 #include <openssl/evp.h>
 #include <errno.h>
-#include <ext4.h>
 #include <linux/kdev_t.h>
-#include <fs_mgr.h>
 #include <time.h>
 #include "cryptfs.h"
-#define LOG_TAG "Cryptfs"
-#include "cutils/log.h"
 #include "cutils/properties.h"
-#include "cutils/android_reboot.h"
-#include "hardware_legacy/power.h"
-#include <logwrap/logwrap.h>
-//#include "VolumeManager.h"
-//#include "VoldUtil.h"
 #include "crypto_scrypt.h"
-#include "ext4_utils.h"
-#include "f2fs_sparseblock.h"
-//#include "CheckBattery.h"
-//#include "Process.h"
-
 #include <hardware/keymaster.h>
 
+#ifndef min /* already defined by windows.h */
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
 #define UNUSED __attribute__((unused))
 
 #define UNUSED __attribute__((unused))
@@ -91,6 +81,16 @@
 static char *saved_mount_point;
 static int  master_key_saved = 0;
 static struct crypt_persist_data *persist_data = NULL;
+static char key_fname[PROPERTY_VALUE_MAX] = "";
+static char real_blkdev[PROPERTY_VALUE_MAX] = "";
+static char file_system[PROPERTY_VALUE_MAX] = "";
+
+void set_partition_data(const char* block_device, const char* key_location, const char* fs)
+{
+  strcpy(key_fname, key_location);
+  strcpy(real_blkdev, block_device);
+  strcpy(file_system, fs);
+}
 
 static int keymaster_init(keymaster_device_t **keymaster_dev)
 {
@@ -291,31 +291,6 @@
 static int password_expiry_time = 0;
 static const int password_max_age_seconds = 60;
 
-struct fstab *fstab;
-
-enum RebootType {reboot, recovery, shutdown};
-static void cryptfs_reboot(enum RebootType rt)
-{
-  switch(rt) {
-      case reboot:
-          property_set(ANDROID_RB_PROPERTY, "reboot");
-          break;
-
-      case recovery:
-          property_set(ANDROID_RB_PROPERTY, "reboot,recovery");
-          break;
-
-      case shutdown:
-          property_set(ANDROID_RB_PROPERTY, "shutdown");
-          break;
-    }
-
-    sleep(20);
-
-    /* Shouldn't get here, reboot should happen before sleep times out */
-    return;
-}
-
 static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags)
 {
     memset(io, 0, dataSize);
@@ -380,41 +355,6 @@
     ftr->p_factor = params[2];
 }
 
-static unsigned int get_fs_size(char *dev)
-{
-    int fd, block_size;
-    struct ext4_super_block sb;
-    off64_t len;
-
-    if ((fd = open(dev, O_RDONLY)) < 0) {
-        printf("Cannot open device to get filesystem size ");
-        return 0;
-    }
-
-    if (lseek64(fd, 1024, SEEK_SET) < 0) {
-        printf("Cannot seek to superblock");
-        return 0;
-    }
-
-    if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) {
-        printf("Cannot read superblock");
-        return 0;
-    }
-
-    close(fd);
-
-    if (le32_to_cpu(sb.s_magic) != EXT4_SUPER_MAGIC) {
-        printf("Not a valid ext4 superblock");
-        return 0;
-    }
-    block_size = 1024 << sb.s_log_block_size;
-    /* compute length in bytes */
-    len = ( ((off64_t)sb.s_blocks_count_hi << 32) + sb.s_blocks_count_lo) * block_size;
-
-    /* return length in sectors */
-    return (unsigned int) (len / 512);
-}
-
 static unsigned int get_blkdev_size(int fd)
 {
   unsigned int nr_sec;
@@ -432,15 +372,12 @@
   static off64_t cached_off = 0;
   static char cached_metadata_fname[PROPERTY_VALUE_MAX] = "";
   int fd;
-  char key_loc[PROPERTY_VALUE_MAX];
-  char real_blkdev[PROPERTY_VALUE_MAX];
   unsigned int nr_sec;
   int rc = -1;
 
   if (!cached_data) {
-    fs_mgr_get_crypt_info(fstab, key_loc, real_blkdev, sizeof(key_loc));
-    printf("get_crypt_ftr_info crypto key location: '%s'\n", key_loc);
-    if (!strcmp(key_loc, KEY_IN_FOOTER)) {
+    printf("get_crypt_ftr_info crypto key location: '%s'\n", key_fname);
+    if (!strcmp(key_fname, KEY_IN_FOOTER)) {
       if ( (fd = open(real_blkdev, O_RDWR)) < 0) {
         printf("Cannot open real block device %s\n", real_blkdev);
         return -1;
@@ -459,7 +396,7 @@
       }
       close(fd);
     } else {
-      strlcpy(cached_metadata_fname, key_loc, sizeof(cached_metadata_fname));
+      strlcpy(cached_metadata_fname, key_fname, sizeof(cached_metadata_fname));
       cached_off = 0;
       cached_data = 1;
     }
@@ -478,65 +415,6 @@
   return rc;
 }
 
-/* key or salt can be NULL, in which case just skip writing that value.  Useful to
- * update the failed mount count but not change the key.
- */
-static int put_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr)
-{
-  printf("TWRP NOT putting crypt footer and key\n");
-  return 0;
-  int fd;
-  unsigned int nr_sec, cnt;
-  /* starting_off is set to the SEEK_SET offset
-   * where the crypto structure starts
-   */
-  off64_t starting_off;
-  int rc = -1;
-  char *fname = NULL;
-  struct stat statbuf;
-
-  if (get_crypt_ftr_info(&fname, &starting_off)) {
-    printf("Unable to get crypt_ftr_info\n");
-    return -1;
-  }
-  if (fname[0] != '/') {
-    printf("Unexpected value for crypto key location\n");
-    return -1;
-  }
-  if ( (fd = open(fname, O_RDWR | O_CREAT, 0600)) < 0) {
-    printf("Cannot open footer file %s for put\n", fname);
-    return -1;
-  }
-
-  /* Seek to the start of the crypt footer */
-  if (lseek64(fd, starting_off, SEEK_SET) == -1) {
-    printf("Cannot seek to real block device footer\n");
-    goto errout;
-  }
-
-  if ((cnt = write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
-    printf("Cannot write real block device footer\n");
-    goto errout;
-  }
-
-  fstat(fd, &statbuf);
-  /* If the keys are kept on a raw block device, do not try to truncate it. */
-  if (S_ISREG(statbuf.st_mode)) {
-    if (ftruncate(fd, 0x4000)) {
-      printf("Cannot set footer file size\n");
-      goto errout;
-    }
-  }
-
-  /* Success! */
-  rc = 0;
-
-errout:
-  close(fd);
-  return rc;
-
-}
-
 static inline int unix_read(int  fd, void*  buff, int  len)
 {
     return TEMP_FAILURE_RETRY(read(fd, buff, len));
@@ -554,75 +432,6 @@
     pdata->persist_valid_entries = 0;
 }
 
-/* A routine to update the passed in crypt_ftr to the lastest version.
- * fd is open read/write on the device that holds the crypto footer and persistent
- * data, crypt_ftr is a pointer to the struct to be updated, and offset is the
- * absolute offset to the start of the crypt_mnt_ftr on the passed in fd.
- */
-static void upgrade_crypt_ftr(int fd, struct crypt_mnt_ftr *crypt_ftr, off64_t offset)
-{
-    int orig_major = crypt_ftr->major_version;
-    int orig_minor = crypt_ftr->minor_version;
-printf("TWRP NOT upgrading crypto footer\n");
-return; // do not upgrade in recovery
-    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 0)) {
-        struct crypt_persist_data *pdata;
-        off64_t pdata_offset = offset + CRYPT_FOOTER_TO_PERSIST_OFFSET;
-
-        printf("upgrading crypto footer to 1.1");
-
-        pdata = malloc(CRYPT_PERSIST_DATA_SIZE);
-        if (pdata == NULL) {
-            printf("Cannot allocate persisent data\n");
-            return;
-        }
-        memset(pdata, 0, CRYPT_PERSIST_DATA_SIZE);
-
-        /* Need to initialize the persistent data area */
-        if (lseek64(fd, pdata_offset, SEEK_SET) == -1) {
-            printf("Cannot seek to persisent data offset\n");
-            return;
-        }
-        /* Write all zeros to the first copy, making it invalid */
-        unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE);
-
-        /* Write a valid but empty structure to the second copy */
-        init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
-        unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE);
-
-        /* Update the footer */
-        crypt_ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE;
-        crypt_ftr->persist_data_offset[0] = pdata_offset;
-        crypt_ftr->persist_data_offset[1] = pdata_offset + CRYPT_PERSIST_DATA_SIZE;
-        crypt_ftr->minor_version = 1;
-    }
-
-    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 1)) {
-        printf("upgrading crypto footer to 1.2");
-        /* But keep the old kdf_type.
-         * It will get updated later to KDF_SCRYPT after the password has been verified.
-         */
-        crypt_ftr->kdf_type = KDF_PBKDF2;
-        get_device_scrypt_params(crypt_ftr);
-        crypt_ftr->minor_version = 2;
-    }
-
-    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 2)) {
-        printf("upgrading crypto footer to 1.3");
-        crypt_ftr->crypt_type = CRYPT_TYPE_PASSWORD;
-        crypt_ftr->minor_version = 3;
-    }
-
-    if ((orig_major != crypt_ftr->major_version) || (orig_minor != crypt_ftr->minor_version)) {
-        if (lseek64(fd, offset, SEEK_SET) == -1) {
-            printf("Cannot seek to crypt footer\n");
-            return;
-        }
-        unix_write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr));
-    }
-}
-
-
 static int get_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr)
 {
   int fd;
@@ -682,9 +491,9 @@
   /* If this is a verion 1.0 crypt_ftr, make it a 1.1 crypt footer, and update the
    * copy on disk before returning.
    */
-  if (crypt_ftr->minor_version < CURRENT_MINOR_VERSION) {
+  /*if (crypt_ftr->minor_version < CURRENT_MINOR_VERSION) {
     upgrade_crypt_ftr(fd, crypt_ftr, starting_off);
-  }
+  }*/
 
   /* Success! */
   rc = 0;
@@ -694,229 +503,6 @@
   return rc;
 }
 
-static int validate_persistent_data_storage(struct crypt_mnt_ftr *crypt_ftr)
-{
-    if (crypt_ftr->persist_data_offset[0] + crypt_ftr->persist_data_size >
-        crypt_ftr->persist_data_offset[1]) {
-        printf("Crypt_ftr persist data regions overlap");
-        return -1;
-    }
-
-    if (crypt_ftr->persist_data_offset[0] >= crypt_ftr->persist_data_offset[1]) {
-        printf("Crypt_ftr persist data region 0 starts after region 1");
-        return -1;
-    }
-
-    if (((crypt_ftr->persist_data_offset[1] + crypt_ftr->persist_data_size) -
-        (crypt_ftr->persist_data_offset[0] - CRYPT_FOOTER_TO_PERSIST_OFFSET)) >
-        CRYPT_FOOTER_OFFSET) {
-        printf("Persistent data extends past crypto footer");
-        return -1;
-    }
-
-    return 0;
-}
-
-static int load_persistent_data(void)
-{
-    struct crypt_mnt_ftr crypt_ftr;
-    struct crypt_persist_data *pdata = NULL;
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    char *fname;
-    int found = 0;
-    int fd;
-    int ret;
-    int i;
-
-    if (persist_data) {
-        /* Nothing to do, we've already loaded or initialized it */
-        return 0;
-    }
-
-
-    /* If not encrypted, just allocate an empty table and initialize it */
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (strcmp(encrypted_state, "encrypted") ) {
-        pdata = malloc(CRYPT_PERSIST_DATA_SIZE);
-        if (pdata) {
-            init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
-            persist_data = pdata;
-            return 0;
-        }
-        return -1;
-    }
-
-    if(get_crypt_ftr_and_key(&crypt_ftr)) {
-        return -1;
-    }
-
-    if ((crypt_ftr.major_version < 1)
-        || (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) {
-        printf("Crypt_ftr version doesn't support persistent data");
-        return -1;
-    }
-
-    if (get_crypt_ftr_info(&fname, NULL)) {
-        return -1;
-    }
-
-    ret = validate_persistent_data_storage(&crypt_ftr);
-    if (ret) {
-        return -1;
-    }
-
-    fd = open(fname, O_RDONLY);
-    if (fd < 0) {
-        printf("Cannot open %s metadata file", fname);
-        return -1;
-    }
-
-    if (persist_data == NULL) {
-        pdata = malloc(crypt_ftr.persist_data_size);
-        if (pdata == NULL) {
-            printf("Cannot allocate memory for persistent data");
-            goto err;
-        }
-    }
-
-    for (i = 0; i < 2; i++) {
-        if (lseek64(fd, crypt_ftr.persist_data_offset[i], SEEK_SET) < 0) {
-            printf("Cannot seek to read persistent data on %s", fname);
-            goto err2;
-        }
-        if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0){
-            printf("Error reading persistent data on iteration %d", i);
-            goto err2;
-        }
-        if (pdata->persist_magic == PERSIST_DATA_MAGIC) {
-            found = 1;
-            break;
-        }
-    }
-
-    if (!found) {
-        printf("Could not find valid persistent data, creating");
-        init_empty_persist_data(pdata, crypt_ftr.persist_data_size);
-    }
-
-    /* Success */
-    persist_data = pdata;
-    close(fd);
-    return 0;
-
-err2:
-    free(pdata);
-
-err:
-    close(fd);
-    return -1;
-}
-
-static int save_persistent_data(void)
-{
-    struct crypt_mnt_ftr crypt_ftr;
-    struct crypt_persist_data *pdata;
-    char *fname;
-    off64_t write_offset;
-    off64_t erase_offset;
-    int found = 0;
-    int fd;
-    int ret;
-
-    if (persist_data == NULL) {
-        printf("No persistent data to save");
-        return -1;
-    }
-
-    if(get_crypt_ftr_and_key(&crypt_ftr)) {
-        return -1;
-    }
-
-    if ((crypt_ftr.major_version < 1)
-        || (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) {
-        printf("Crypt_ftr version doesn't support persistent data");
-        return -1;
-    }
-
-    ret = validate_persistent_data_storage(&crypt_ftr);
-    if (ret) {
-        return -1;
-    }
-
-    if (get_crypt_ftr_info(&fname, NULL)) {
-        return -1;
-    }
-
-    fd = open(fname, O_RDWR);
-    if (fd < 0) {
-        printf("Cannot open %s metadata file", fname);
-        return -1;
-    }
-
-    pdata = malloc(crypt_ftr.persist_data_size);
-    if (pdata == NULL) {
-        printf("Cannot allocate persistant data");
-        goto err;
-    }
-
-    if (lseek64(fd, crypt_ftr.persist_data_offset[0], SEEK_SET) < 0) {
-        printf("Cannot seek to read persistent data on %s", fname);
-        goto err2;
-    }
-
-    if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0) {
-            printf("Error reading persistent data before save");
-            goto err2;
-    }
-
-    if (pdata->persist_magic == PERSIST_DATA_MAGIC) {
-        /* The first copy is the curent valid copy, so write to
-         * the second copy and erase this one */
-       write_offset = crypt_ftr.persist_data_offset[1];
-       erase_offset = crypt_ftr.persist_data_offset[0];
-    } else {
-        /* The second copy must be the valid copy, so write to
-         * the first copy, and erase the second */
-       write_offset = crypt_ftr.persist_data_offset[0];
-       erase_offset = crypt_ftr.persist_data_offset[1];
-    }
-
-    /* Write the new copy first, if successful, then erase the old copy */
-    if (lseek(fd, write_offset, SEEK_SET) < 0) {
-        printf("Cannot seek to write persistent data");
-        goto err2;
-    }
-    if (unix_write(fd, persist_data, crypt_ftr.persist_data_size) ==
-        (int) crypt_ftr.persist_data_size) {
-        if (lseek(fd, erase_offset, SEEK_SET) < 0) {
-            printf("Cannot seek to erase previous persistent data");
-            goto err2;
-        }
-        fsync(fd);
-        memset(pdata, 0, crypt_ftr.persist_data_size);
-        if (unix_write(fd, pdata, crypt_ftr.persist_data_size) !=
-            (int) crypt_ftr.persist_data_size) {
-            printf("Cannot write to erase previous persistent data");
-            goto err2;
-        }
-        fsync(fd);
-    } else {
-        printf("Cannot write to save persistent data");
-        goto err2;
-    }
-
-    /* Success */
-    free(pdata);
-    close(fd);
-    return 0;
-
-err2:
-    free(pdata);
-err:
-    close(fd);
-    return -1;
-}
-
 static int hexdigit (char c)
 {
     if (c >= '0' && c <= '9') return c - '0';
@@ -1424,321 +1010,12 @@
     return ret;
 }
 
-static int create_encrypted_random_key(char *passwd, unsigned char *master_key, unsigned char *salt,
-        struct crypt_mnt_ftr *crypt_ftr) {
-    int fd;
-    unsigned char key_buf[KEY_LEN_BYTES];
-    EVP_CIPHER_CTX e_ctx;
-    int encrypted_len, final_len;
-
-    /* Get some random bits for a key */
-    fd = open("/dev/urandom", O_RDONLY);
-    read(fd, key_buf, sizeof(key_buf));
-    read(fd, salt, SALT_LEN);
-    close(fd);
-
-    /* Now encrypt it with the password */
-    return encrypt_master_key(passwd, salt, key_buf, master_key, crypt_ftr);
-}
-
-static int wait_and_unmount(char *mountpoint, bool kill)
-{
-    int i, err, rc;
-#define WAIT_UNMOUNT_COUNT 20
-
-    /*  Now umount the tmpfs filesystem */
-    for (i=0; i<WAIT_UNMOUNT_COUNT; i++) {
-        if (umount(mountpoint) == 0) {
-            break;
-        }
-
-        if (errno == EINVAL) {
-            /* EINVAL is returned if the directory is not a mountpoint,
-             * i.e. there is no filesystem mounted there.  So just get out.
-             */
-            break;
-        }
-
-        err = errno;
-
-        /* If allowed, be increasingly aggressive before the last two retries */
-        if (kill) {
-            if (i == (WAIT_UNMOUNT_COUNT - 3)) {
-                printf("sending SIGHUP to processes with open files\n");
-                //vold_killProcessesWithOpenFiles(mountpoint, 1);
-            } else if (i == (WAIT_UNMOUNT_COUNT - 2)) {
-                printf("sending SIGKILL to processes with open files\n");
-                //vold_killProcessesWithOpenFiles(mountpoint, 2);
-            }
-        }
-
-        sleep(1);
-    }
-
-    if (i < WAIT_UNMOUNT_COUNT) {
-      printf("unmounting %s succeeded\n", mountpoint);
-      rc = 0;
-    } else {
-      //vold_killProcessesWithOpenFiles(mountpoint, 0);
-      printf("unmounting %s failed: %s\n", mountpoint, strerror(err));
-      rc = -1;
-    }
-
-    return rc;
-}
-
-#define DATA_PREP_TIMEOUT 200
-static int prep_data_fs(void)
-{
-    int i;
-
-    /* Do the prep of the /data filesystem */
-    property_set("vold.post_fs_data_done", "0");
-    property_set("vold.decrypt", "trigger_post_fs_data");
-    printf("Just triggered post_fs_data\n");
-
-    /* Wait a max of 50 seconds, hopefully it takes much less */
-    for (i=0; i<DATA_PREP_TIMEOUT; i++) {
-        char p[PROPERTY_VALUE_MAX];
-
-        property_get("vold.post_fs_data_done", p, "0");
-        if (*p == '1') {
-            break;
-        } else {
-            usleep(250000);
-        }
-    }
-    if (i == DATA_PREP_TIMEOUT) {
-        /* Ugh, we failed to prep /data in time.  Bail. */
-        printf("post_fs_data timed out!\n");
-        return -1;
-    } else {
-        printf("post_fs_data done\n");
-        return 0;
-    }
-}
-
-static void cryptfs_set_corrupt()
-{
-    // Mark the footer as bad
-    struct crypt_mnt_ftr crypt_ftr;
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        printf("Failed to get crypto footer - panic");
-        return;
-    }
-
-    crypt_ftr.flags |= CRYPT_DATA_CORRUPT;
-    if (put_crypt_ftr_and_key(&crypt_ftr)) {
-        printf("Failed to set crypto footer - panic");
-        return;
-    }
-}
-
-static void cryptfs_trigger_restart_min_framework()
-{
-    if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) {
-      printf("Failed to mount tmpfs on data - panic");
-      return;
-    }
-
-    if (property_set("vold.decrypt", "trigger_post_fs_data")) {
-        printf("Failed to trigger post fs data - panic");
-        return;
-    }
-
-    if (property_set("vold.decrypt", "trigger_restart_min_framework")) {
-        printf("Failed to trigger restart min framework - panic");
-        return;
-    }
-}
-
-/* returns < 0 on failure */
-static int cryptfs_restart_internal(int restart_main)
-{
-    char fs_type[32];
-    char real_blkdev[MAXPATHLEN];
-    char crypto_blkdev[MAXPATHLEN];
-    char fs_options[256];
-    unsigned long mnt_flags;
-    struct stat statbuf;
-    int rc = -1, i;
-    static int restart_successful = 0;
-
-    /* Validate that it's OK to call this routine */
-    if (! master_key_saved) {
-        printf("Encrypted filesystem not validated, aborting");
-        return -1;
-    }
-
-    if (restart_successful) {
-        printf("System already restarted with encrypted disk, aborting");
-        return -1;
-    }
-
-    if (restart_main) {
-        /* Here is where we shut down the framework.  The init scripts
-         * start all services in one of three classes: core, main or late_start.
-         * On boot, we start core and main.  Now, we stop main, but not core,
-         * as core includes vold and a few other really important things that
-         * we need to keep running.  Once main has stopped, we should be able
-         * to umount the tmpfs /data, then mount the encrypted /data.
-         * We then restart the class main, and also the class late_start.
-         * At the moment, I've only put a few things in late_start that I know
-         * are not needed to bring up the framework, and that also cause problems
-         * with unmounting the tmpfs /data, but I hope to add add more services
-         * to the late_start class as we optimize this to decrease the delay
-         * till the user is asked for the password to the filesystem.
-         */
-
-        /* The init files are setup to stop the class main when vold.decrypt is
-         * set to trigger_reset_main.
-         */
-        property_set("vold.decrypt", "trigger_reset_main");
-        printf("Just asked init to shut down class main\n");
-
-        /* Ugh, shutting down the framework is not synchronous, so until it
-         * can be fixed, this horrible hack will wait a moment for it all to
-         * shut down before proceeding.  Without it, some devices cannot
-         * restart the graphics services.
-         */
-        sleep(2);
-    }
-
-    /* Now that the framework is shutdown, we should be able to umount()
-     * the tmpfs filesystem, and mount the real one.
-     */
-
-    property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "");
-    if (strlen(crypto_blkdev) == 0) {
-        printf("fs_crypto_blkdev not set\n");
-        return -1;
-    }
-
-    if (! (rc = wait_and_unmount(DATA_MNT_POINT, true)) ) {
-        /* If ro.crypto.readonly is set to 1, mount the decrypted
-         * filesystem readonly.  This is used when /data is mounted by
-         * recovery mode.
-         */
-        char ro_prop[PROPERTY_VALUE_MAX];
-        property_get("ro.crypto.readonly", ro_prop, "");
-        if (strlen(ro_prop) > 0 && atoi(ro_prop)) {
-            struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT);
-            rec->flags |= MS_RDONLY;
-        }
-
-        /* If that succeeded, then mount the decrypted filesystem */
-        int retries = RETRY_MOUNT_ATTEMPTS;
-        int mount_rc;
-        while ((mount_rc = fs_mgr_do_mount(fstab, DATA_MNT_POINT,
-                                           crypto_blkdev, 0))
-               != 0) {
-            if (mount_rc == FS_MGR_DOMNT_BUSY) {
-                /* TODO: invoke something similar to
-                   Process::killProcessWithOpenFiles(DATA_MNT_POINT,
-                                   retries > RETRY_MOUNT_ATTEMPT/2 ? 1 : 2 ) */
-                printf("Failed to mount %s because it is busy - waiting",
-                      crypto_blkdev);
-                if (--retries) {
-                    sleep(RETRY_MOUNT_DELAY_SECONDS);
-                } else {
-                    /* Let's hope that a reboot clears away whatever is keeping
-                       the mount busy */
-                    cryptfs_reboot(reboot);
-                }
-            } else {
-                printf("Failed to mount decrypted data");
-                cryptfs_set_corrupt();
-                cryptfs_trigger_restart_min_framework();
-                printf("Started framework to offer wipe");
-                return -1;
-            }
-        }
-
-        property_set("vold.decrypt", "trigger_load_persist_props");
-        /* Create necessary paths on /data */
-        if (prep_data_fs()) {
-            return -1;
-        }
-
-        /* startup service classes main and late_start */
-        property_set("vold.decrypt", "trigger_restart_framework");
-        printf("Just triggered restart_framework\n");
-
-        /* Give it a few moments to get started */
-        sleep(1);
-    }
-
-    if (rc == 0) {
-        restart_successful = 1;
-    }
-
-    return rc;
-}
-
-int cryptfs_restart(void)
-{
-    /* Call internal implementation forcing a restart of main service group */
-    return cryptfs_restart_internal(1);
-}
-
-static int do_crypto_complete(char *mount_point UNUSED)
-{
-  struct crypt_mnt_ftr crypt_ftr;
-  char encrypted_state[PROPERTY_VALUE_MAX];
-  char key_loc[PROPERTY_VALUE_MAX];
-
-  property_get("ro.crypto.state", encrypted_state, "");
-  if (strcmp(encrypted_state, "encrypted") ) {
-    printf("not running with encryption, aborting");
-    return CRYPTO_COMPLETE_NOT_ENCRYPTED;
-  }
-
-  if (get_crypt_ftr_and_key(&crypt_ftr)) {
-    fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc));
-
-    /*
-     * Only report this error if key_loc is a file and it exists.
-     * If the device was never encrypted, and /data is not mountable for
-     * some reason, returning 1 should prevent the UI from presenting the
-     * a "enter password" screen, or worse, a "press button to wipe the
-     * device" screen.
-     */
-    if ((key_loc[0] == '/') && (access("key_loc", F_OK) == -1)) {
-      printf("master key file does not exist, aborting");
-      return CRYPTO_COMPLETE_NOT_ENCRYPTED;
-    } else {
-      printf("Error getting crypt footer and key\n");
-      return CRYPTO_COMPLETE_BAD_METADATA;
-    }
-  }
-
-  // Test for possible error flags
-  if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS){
-    printf("Encryption process is partway completed\n");
-    return CRYPTO_COMPLETE_PARTIAL;
-  }
-
-  if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE){
-    printf("Encryption process was interrupted but cannot continue\n");
-    return CRYPTO_COMPLETE_INCONSISTENT;
-  }
-
-  if (crypt_ftr.flags & CRYPT_DATA_CORRUPT){
-    printf("Encryption is successful but data is corrupt\n");
-    return CRYPTO_COMPLETE_CORRUPT;
-  }
-
-  /* We passed the test! We shall diminish, and return to the west */
-  return CRYPTO_COMPLETE_ENCRYPTED;
-}
-
 static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
                                    char *passwd, char *mount_point, char *label)
 {
   /* Allocate enough space for a 256 bit key, but we may use less */
   unsigned char decrypted_master_key[32];
   char crypto_blkdev[MAXPATHLEN];
-  char real_blkdev[MAXPATHLEN];
   char tmp_mount_point[64];
   unsigned int orig_failed_decrypt_count;
   int rc;
@@ -1761,8 +1038,6 @@
     }
   }
 
-  fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
-
   // Create crypto block device - all (non fatal) code paths
   // need it
   if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key,
@@ -1795,7 +1070,7 @@
      * the footer, not the key. */
     sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point);
     mkdir(tmp_mount_point, 0755);
-    if (fs_mgr_do_mount(fstab, DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) {
+    if (mount(crypto_blkdev, tmp_mount_point, file_system, NULL, NULL) != 0) {
       printf("Error temp mounting decrypted block device '%s'\n", crypto_blkdev);
       delete_crypto_blk_dev(label);
 
@@ -1877,52 +1152,6 @@
     return delete_crypto_blk_dev((char *)label);
 }
 
-/*
- * Called by vold when it's asked to mount an encrypted, nonremovable volume.
- * Setup a dm-crypt mapping, use the saved master key from
- * setting up the /data mapping, and return the new device path.
- */
-int cryptfs_setup_volume(const char *label, int major, int minor,
-                         char *crypto_sys_path, unsigned int max_path,
-                         int *new_major, int *new_minor)
-{
-    char real_blkdev[MAXPATHLEN], crypto_blkdev[MAXPATHLEN];
-    struct crypt_mnt_ftr sd_crypt_ftr;
-    struct stat statbuf;
-    int nr_sec, fd;
-
-    sprintf(real_blkdev, "/dev/block/vold/%d:%d", major, minor);
-
-    get_crypt_ftr_and_key(&sd_crypt_ftr);
-
-    /* Update the fs_size field to be the size of the volume */
-    fd = open(real_blkdev, O_RDONLY);
-    nr_sec = get_blkdev_size(fd);
-    close(fd);
-    if (nr_sec == 0) {
-        printf("Cannot get size of volume %s\n", real_blkdev);
-        return -1;
-    }
-
-    sd_crypt_ftr.fs_size = nr_sec;
-    create_crypto_blk_dev(&sd_crypt_ftr, saved_master_key, real_blkdev, 
-                          crypto_blkdev, label);
-
-    stat(crypto_blkdev, &statbuf);
-    *new_major = MAJOR(statbuf.st_rdev);
-    *new_minor = MINOR(statbuf.st_rdev);
-
-    /* Create path to sys entry for this block device */
-    snprintf(crypto_sys_path, max_path, "/devices/virtual/block/%s", strrchr(crypto_blkdev, '/')+1);
-
-    return 0;
-}
-
-int cryptfs_crypto_complete(void)
-{
-  return do_crypto_complete("/data");
-}
-
 int check_unmounted_and_get_ftr(struct crypt_mnt_ftr* crypt_ftr)
 {
     char encrypted_state[PROPERTY_VALUE_MAX];
@@ -2034,24 +1263,11 @@
     return hex;
 }
 
-#define FSTAB_PREFIX "/fstab."
-
-int cryptfs_check_footer(void)
+int cryptfs_check_footer()
 {
     int rc = -1;
-    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
-    char propbuf[PROPERTY_VALUE_MAX];
     struct crypt_mnt_ftr crypt_ftr;
 
-    property_get("ro.hardware", propbuf, "");
-    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
-
-    fstab = fs_mgr_read_fstab(fstab_filename);
-    if (!fstab) {
-        printf("failed to open %s\n", fstab_filename);
-        return -1;
-    }
-
     rc = get_crypt_ftr_and_key(&crypt_ftr);
 
     return rc;
@@ -2061,17 +1277,6 @@
 {
     struct crypt_mnt_ftr crypt_ftr;
     int rc;
-    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
-    char propbuf[PROPERTY_VALUE_MAX];
-
-    property_get("ro.hardware", propbuf, "");
-    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
-
-    fstab = fs_mgr_read_fstab(fstab_filename);
-    if (!fstab) {
-        printf("failed to open %s\n", fstab_filename);
-        return -1;
-    }
 
     rc = check_unmounted_and_get_ftr(&crypt_ftr);
     if (rc)
@@ -2223,1366 +1428,11 @@
     return 0;
 }
 
-static int cryptfs_enable_wipe(char *crypto_blkdev, off64_t size, int type)
-{
-    const char *args[10];
-    char size_str[32]; /* Must be large enough to hold a %lld and null byte */
-    int num_args;
-    int status;
-    int tmp;
-    int rc = -1;
-
-    if (type == EXT4_FS) {
-        args[0] = "/system/bin/make_ext4fs";
-        args[1] = "-a";
-        args[2] = "/data";
-        args[3] = "-l";
-        snprintf(size_str, sizeof(size_str), "%" PRId64, size * 512);
-        args[4] = size_str;
-        args[5] = crypto_blkdev;
-        num_args = 6;
-        printf("Making empty filesystem with command %s %s %s %s %s %s\n",
-              args[0], args[1], args[2], args[3], args[4], args[5]);
-    } else if (type == F2FS_FS) {
-        args[0] = "/system/bin/mkfs.f2fs";
-        args[1] = "-t";
-        args[2] = "-d1";
-        args[3] = crypto_blkdev;
-        snprintf(size_str, sizeof(size_str), "%" PRId64, size);
-        args[4] = size_str;
-        num_args = 5;
-        printf("Making empty filesystem with command %s %s %s %s %s\n",
-              args[0], args[1], args[2], args[3], args[4]);
-    } else {
-        printf("cryptfs_enable_wipe(): unknown filesystem type %d\n", type);
-        return -1;
-    }
-
-    tmp = android_fork_execvp(num_args, (char **)args, &status, false, true);
-
-    if (tmp != 0) {
-      printf("Error creating empty filesystem on %s due to logwrap error\n", crypto_blkdev);
-    } else {
-        if (WIFEXITED(status)) {
-            if (WEXITSTATUS(status)) {
-                printf("Error creating filesystem on %s, exit status %d ",
-                      crypto_blkdev, WEXITSTATUS(status));
-            } else {
-                printf("Successfully created filesystem on %s\n", crypto_blkdev);
-                rc = 0;
-            }
-        } else {
-            printf("Error creating filesystem on %s, did not exit normally\n", crypto_blkdev);
-       }
-    }
-
-    return rc;
-}
-
-#define CRYPT_INPLACE_BUFSIZE 4096
-#define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / CRYPT_SECTOR_SIZE)
-#define CRYPT_SECTOR_SIZE 512
-
-/* aligned 32K writes tends to make flash happy.
- * SD card association recommends it.
- */
-#define BLOCKS_AT_A_TIME 8
-
-struct encryptGroupsData
-{
-    int realfd;
-    int cryptofd;
-    off64_t numblocks;
-    off64_t one_pct, cur_pct, new_pct;
-    off64_t blocks_already_done, tot_numblocks;
-    off64_t used_blocks_already_done, tot_used_blocks;
-    char* real_blkdev, * crypto_blkdev;
-    int count;
-    off64_t offset;
-    char* buffer;
-    off64_t last_written_sector;
-    int completed;
-    time_t time_started;
-    int remaining_time;
-};
-
-static void update_progress(struct encryptGroupsData* data, int is_used)
-{
-    data->blocks_already_done++;
-
-    if (is_used) {
-        data->used_blocks_already_done++;
-    }
-    if (data->tot_used_blocks) {
-        data->new_pct = data->used_blocks_already_done / data->one_pct;
-    } else {
-        data->new_pct = data->blocks_already_done / data->one_pct;
-    }
-
-    if (data->new_pct > data->cur_pct) {
-        char buf[8];
-        data->cur_pct = data->new_pct;
-        snprintf(buf, sizeof(buf), "%" PRId64, data->cur_pct);
-        property_set("vold.encrypt_progress", buf);
-    }
-
-    if (data->cur_pct >= 5) {
-        struct timespec time_now;
-        if (clock_gettime(CLOCK_MONOTONIC, &time_now)) {
-            printf("Error getting time");
-        } else {
-            double elapsed_time = difftime(time_now.tv_sec, data->time_started);
-            off64_t remaining_blocks = data->tot_used_blocks
-                                       - data->used_blocks_already_done;
-            int remaining_time = (int)(elapsed_time * remaining_blocks
-                                       / data->used_blocks_already_done);
-
-            // Change time only if not yet set, lower, or a lot higher for
-            // best user experience
-            if (data->remaining_time == -1
-                || remaining_time < data->remaining_time
-                || remaining_time > data->remaining_time + 60) {
-                char buf[8];
-                snprintf(buf, sizeof(buf), "%d", remaining_time);
-                property_set("vold.encrypt_time_remaining", buf);
-                data->remaining_time = remaining_time;
-            }
-        }
-    }
-}
-
-static void log_progress(struct encryptGroupsData const* data, bool completed)
-{
-    // Precondition - if completed data = 0 else data != 0
-
-    // Track progress so we can skip logging blocks
-    static off64_t offset = -1;
-
-    // Need to close existing 'Encrypting from' log?
-    if (completed || (offset != -1 && data->offset != offset)) {
-        printf("Encrypted to sector %" PRId64,
-              offset / info.block_size * CRYPT_SECTOR_SIZE);
-        offset = -1;
-    }
-
-    // Need to start new 'Encrypting from' log?
-    if (!completed && offset != data->offset) {
-        printf("Encrypting from sector %" PRId64,
-              data->offset / info.block_size * CRYPT_SECTOR_SIZE);
-    }
-
-    // Update offset
-    if (!completed) {
-        offset = data->offset + (off64_t)data->count * info.block_size;
-    }
-}
-
-static int flush_outstanding_data(struct encryptGroupsData* data)
-{
-    if (data->count == 0) {
-        return 0;
-    }
-
-    printf("Copying %d blocks at offset %" PRIx64, data->count, data->offset);
-
-    if (pread64(data->realfd, data->buffer,
-                info.block_size * data->count, data->offset)
-        <= 0) {
-        printf("Error reading real_blkdev %s for inplace encrypt",
-              data->real_blkdev);
-        return -1;
-    }
-
-    if (pwrite64(data->cryptofd, data->buffer,
-                 info.block_size * data->count, data->offset)
-        <= 0) {
-        printf("Error writing crypto_blkdev %s for inplace encrypt",
-              data->crypto_blkdev);
-        return -1;
-    } else {
-      log_progress(data, false);
-    }
-
-    data->count = 0;
-    data->last_written_sector = (data->offset + data->count)
-                                / info.block_size * CRYPT_SECTOR_SIZE - 1;
-    return 0;
-}
-
-static int encrypt_groups(struct encryptGroupsData* data)
-{
-    unsigned int i;
-    u8 *block_bitmap = 0;
-    unsigned int block;
-    off64_t ret;
-    int rc = -1;
-
-    data->buffer = malloc(info.block_size * BLOCKS_AT_A_TIME);
-    if (!data->buffer) {
-        printf("Failed to allocate crypto buffer");
-        goto errout;
-    }
-
-    block_bitmap = malloc(info.block_size);
-    if (!block_bitmap) {
-        printf("failed to allocate block bitmap");
-        goto errout;
-    }
-
-    for (i = 0; i < aux_info.groups; ++i) {
-        printf("Encrypting group %d", i);
-
-        u32 first_block = aux_info.first_data_block + i * info.blocks_per_group;
-        u32 block_count = min(info.blocks_per_group,
-                             aux_info.len_blocks - first_block);
-
-        off64_t offset = (u64)info.block_size
-                         * aux_info.bg_desc[i].bg_block_bitmap;
-
-        ret = pread64(data->realfd, block_bitmap, info.block_size, offset);
-        if (ret != (int)info.block_size) {
-            printf("failed to read all of block group bitmap %d", i);
-            goto errout;
-        }
-
-        offset = (u64)info.block_size * first_block;
-
-        data->count = 0;
-
-        for (block = 0; block < block_count; block++) {
-            int used = bitmap_get_bit(block_bitmap, block);
-            update_progress(data, used);
-            if (used) {
-                if (data->count == 0) {
-                    data->offset = offset;
-                }
-                data->count++;
-            } else {
-                if (flush_outstanding_data(data)) {
-                    goto errout;
-                }
-            }
-
-            offset += info.block_size;
-
-            /* Write data if we are aligned or buffer size reached */
-            if (offset % (info.block_size * BLOCKS_AT_A_TIME) == 0
-                || data->count == BLOCKS_AT_A_TIME) {
-                if (flush_outstanding_data(data)) {
-                    goto errout;
-                }
-            }
-
-            if (1) {
-                printf("Stopping encryption due to low battery");
-                rc = 0;
-                goto errout;
-            }
-
-        }
-        if (flush_outstanding_data(data)) {
-            goto errout;
-        }
-    }
-
-    data->completed = 1;
-    rc = 0;
-
-errout:
-    log_progress(0, true);
-    free(data->buffer);
-    free(block_bitmap);
-    return rc;
-}
-
-static int cryptfs_enable_inplace_ext4(char *crypto_blkdev,
-                                       char *real_blkdev,
-                                       off64_t size,
-                                       off64_t *size_already_done,
-                                       off64_t tot_size,
-                                       off64_t previously_encrypted_upto)
-{
-    u32 i;
-    struct encryptGroupsData data;
-    int rc; // Can't initialize without causing warning -Wclobbered
-
-    if (previously_encrypted_upto > *size_already_done) {
-        printf("Not fast encrypting since resuming part way through");
-        return -1;
-    }
-
-    memset(&data, 0, sizeof(data));
-    data.real_blkdev = real_blkdev;
-    data.crypto_blkdev = crypto_blkdev;
-
-    if ( (data.realfd = open(real_blkdev, O_RDWR)) < 0) {
-        printf("Error opening real_blkdev %s for inplace encrypt. err=%d(%s)\n",
-              real_blkdev, errno, strerror(errno));
-        rc = -1;
-        goto errout;
-    }
-
-    if ( (data.cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) {
-        printf("Error opening crypto_blkdev %s for ext4 inplace encrypt. err=%d(%s)\n",
-              crypto_blkdev, errno, strerror(errno));
-        rc = ENABLE_INPLACE_ERR_DEV;
-        goto errout;
-    }
-
-    if (setjmp(setjmp_env)) {
-        printf("Reading ext4 extent caused an exception\n");
-        rc = -1;
-        goto errout;
-    }
-
-    if (read_ext(data.realfd, 0) != 0) {
-        printf("Failed to read ext4 extent\n");
-        rc = -1;
-        goto errout;
-    }
-
-    data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
-    data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
-    data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
-
-    printf("Encrypting ext4 filesystem in place...");
-
-    data.tot_used_blocks = data.numblocks;
-    for (i = 0; i < aux_info.groups; ++i) {
-      data.tot_used_blocks -= aux_info.bg_desc[i].bg_free_blocks_count;
-    }
-
-    data.one_pct = data.tot_used_blocks / 100;
-    data.cur_pct = 0;
-
-    struct timespec time_started = {0};
-    if (clock_gettime(CLOCK_MONOTONIC, &time_started)) {
-        printf("Error getting time at start");
-        // Note - continue anyway - we'll run with 0
-    }
-    data.time_started = time_started.tv_sec;
-    data.remaining_time = -1;
-
-    rc = encrypt_groups(&data);
-    if (rc) {
-        printf("Error encrypting groups");
-        goto errout;
-    }
-
-    *size_already_done += data.completed ? size : data.last_written_sector;
-    rc = 0;
-
-errout:
-    close(data.realfd);
-    close(data.cryptofd);
-
-    return rc;
-}
-
-static void log_progress_f2fs(u64 block, bool completed)
-{
-    // Precondition - if completed data = 0 else data != 0
-
-    // Track progress so we can skip logging blocks
-    static u64 last_block = (u64)-1;
-
-    // Need to close existing 'Encrypting from' log?
-    if (completed || (last_block != (u64)-1 && block != last_block + 1)) {
-        printf("Encrypted to block %" PRId64, last_block);
-        last_block = -1;
-    }
-
-    // Need to start new 'Encrypting from' log?
-    if (!completed && (last_block == (u64)-1 || block != last_block + 1)) {
-        printf("Encrypting from block %" PRId64, block);
-    }
-
-    // Update offset
-    if (!completed) {
-        last_block = block;
-    }
-}
-
-static int encrypt_one_block_f2fs(u64 pos, void *data)
-{
-    struct encryptGroupsData *priv_dat = (struct encryptGroupsData *)data;
-
-    priv_dat->blocks_already_done = pos - 1;
-    update_progress(priv_dat, 1);
-
-    off64_t offset = pos * CRYPT_INPLACE_BUFSIZE;
-
-    if (pread64(priv_dat->realfd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
-        printf("Error reading real_blkdev %s for f2fs inplace encrypt", priv_dat->crypto_blkdev);
-        return -1;
-    }
-
-    if (pwrite64(priv_dat->cryptofd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
-        printf("Error writing crypto_blkdev %s for f2fs inplace encrypt", priv_dat->crypto_blkdev);
-        return -1;
-    } else {
-        log_progress_f2fs(pos, false);
-    }
-
-    return 0;
-}
-
-static int cryptfs_enable_inplace_f2fs(char *crypto_blkdev,
-                                       char *real_blkdev,
-                                       off64_t size,
-                                       off64_t *size_already_done,
-                                       off64_t tot_size,
-                                       off64_t previously_encrypted_upto)
-{
-    u32 i;
-    struct encryptGroupsData data;
-    struct f2fs_info *f2fs_info = NULL;
-    int rc = ENABLE_INPLACE_ERR_OTHER;
-    if (previously_encrypted_upto > *size_already_done) {
-        printf("Not fast encrypting since resuming part way through");
-        return ENABLE_INPLACE_ERR_OTHER;
-    }
-    memset(&data, 0, sizeof(data));
-    data.real_blkdev = real_blkdev;
-    data.crypto_blkdev = crypto_blkdev;
-    data.realfd = -1;
-    data.cryptofd = -1;
-    if ( (data.realfd = open64(real_blkdev, O_RDWR)) < 0) {
-        printf("Error opening real_blkdev %s for f2fs inplace encrypt\n",
-              real_blkdev);
-        goto errout;
-    }
-    if ( (data.cryptofd = open64(crypto_blkdev, O_WRONLY)) < 0) {
-        printf("Error opening crypto_blkdev %s for f2fs inplace encrypt. err=%d(%s)\n",
-              crypto_blkdev, errno, strerror(errno));
-        rc = ENABLE_INPLACE_ERR_DEV;
-        goto errout;
-    }
-
-    f2fs_info = generate_f2fs_info(data.realfd);
-    if (!f2fs_info)
-      goto errout;
-
-    data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
-    data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
-    data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
-
-    data.tot_used_blocks = get_num_blocks_used(f2fs_info);
-
-    data.one_pct = data.tot_used_blocks / 100;
-    data.cur_pct = 0;
-    data.time_started = time(NULL);
-    data.remaining_time = -1;
-
-    data.buffer = malloc(f2fs_info->block_size);
-    if (!data.buffer) {
-        printf("Failed to allocate crypto buffer");
-        goto errout;
-    }
-
-    data.count = 0;
-
-    /* Currently, this either runs to completion, or hits a nonrecoverable error */
-    rc = run_on_used_blocks(data.blocks_already_done, f2fs_info, &encrypt_one_block_f2fs, &data);
-
-    if (rc) {
-        printf("Error in running over f2fs blocks");
-        rc = ENABLE_INPLACE_ERR_OTHER;
-        goto errout;
-    }
-
-    *size_already_done += size;
-    rc = 0;
-
-errout:
-    if (rc)
-        printf("Failed to encrypt f2fs filesystem on %s", real_blkdev);
-
-    log_progress_f2fs(0, true);
-    free(f2fs_info);
-    free(data.buffer);
-    close(data.realfd);
-    close(data.cryptofd);
-
-    return rc;
-}
-
-static int cryptfs_enable_inplace_full(char *crypto_blkdev, char *real_blkdev,
-                                       off64_t size, off64_t *size_already_done,
-                                       off64_t tot_size,
-                                       off64_t previously_encrypted_upto)
-{
-    int realfd, cryptofd;
-    char *buf[CRYPT_INPLACE_BUFSIZE];
-    int rc = ENABLE_INPLACE_ERR_OTHER;
-    off64_t numblocks, i, remainder;
-    off64_t one_pct, cur_pct, new_pct;
-    off64_t blocks_already_done, tot_numblocks;
-
-    if ( (realfd = open(real_blkdev, O_RDONLY)) < 0) { 
-        printf("Error opening real_blkdev %s for inplace encrypt\n", real_blkdev);
-        return ENABLE_INPLACE_ERR_OTHER;
-    }
-
-    if ( (cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) { 
-        printf("Error opening crypto_blkdev %s for inplace encrypt. err=%d(%s)\n",
-              crypto_blkdev, errno, strerror(errno));
-        close(realfd);
-        return ENABLE_INPLACE_ERR_DEV;
-    }
-
-    /* This is pretty much a simple loop of reading 4K, and writing 4K.
-     * The size passed in is the number of 512 byte sectors in the filesystem.
-     * So compute the number of whole 4K blocks we should read/write,
-     * and the remainder.
-     */
-    numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
-    remainder = size % CRYPT_SECTORS_PER_BUFSIZE;
-    tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
-    blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
-
-    printf("Encrypting filesystem in place...");
-
-    i = previously_encrypted_upto + 1 - *size_already_done;
-
-    if (lseek64(realfd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) {
-        printf("Cannot seek to previously encrypted point on %s", real_blkdev);
-        goto errout;
-    }
-
-    if (lseek64(cryptofd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) {
-        printf("Cannot seek to previously encrypted point on %s", crypto_blkdev);
-        goto errout;
-    }
-
-    for (;i < size && i % CRYPT_SECTORS_PER_BUFSIZE != 0; ++i) {
-        if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
-            printf("Error reading initial sectors from real_blkdev %s for "
-                  "inplace encrypt\n", crypto_blkdev);
-            goto errout;
-        }
-        if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) {
-            printf("Error writing initial sectors to crypto_blkdev %s for "
-                  "inplace encrypt\n", crypto_blkdev);
-            goto errout;
-        } else {
-            printf("Encrypted 1 block at %" PRId64, i);
-        }
-    }
-
-    one_pct = tot_numblocks / 100;
-    cur_pct = 0;
-    /* process the majority of the filesystem in blocks */
-    for (i/=CRYPT_SECTORS_PER_BUFSIZE; i<numblocks; i++) {
-        new_pct = (i + blocks_already_done) / one_pct;
-        if (new_pct > cur_pct) {
-            char buf[8];
-
-            cur_pct = new_pct;
-            snprintf(buf, sizeof(buf), "%" PRId64, cur_pct);
-            property_set("vold.encrypt_progress", buf);
-        }
-        if (unix_read(realfd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
-            printf("Error reading real_blkdev %s for inplace encrypt", crypto_blkdev);
-            goto errout;
-        }
-        if (unix_write(cryptofd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
-            printf("Error writing crypto_blkdev %s for inplace encrypt", crypto_blkdev);
-            goto errout;
-        } else {
-            printf("Encrypted %d block at %" PRId64,
-                  CRYPT_SECTORS_PER_BUFSIZE,
-                  i * CRYPT_SECTORS_PER_BUFSIZE);
-        }
-
-       if (1) {
-            printf("Stopping encryption due to low battery");
-            *size_already_done += (i + 1) * CRYPT_SECTORS_PER_BUFSIZE - 1;
-            rc = 0;
-            goto errout;
-        }
-    }
-
-    /* Do any remaining sectors */
-    for (i=0; i<remainder; i++) {
-        if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
-            printf("Error reading final sectors from real_blkdev %s for inplace encrypt", crypto_blkdev);
-            goto errout;
-        }
-        if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) {
-            printf("Error writing final sectors to crypto_blkdev %s for inplace encrypt", crypto_blkdev);
-            goto errout;
-        } else {
-            printf("Encrypted 1 block at next location");
-        }
-    }
-
-    *size_already_done += size;
-    rc = 0;
-
-errout:
-    close(realfd);
-    close(cryptofd);
-
-    return rc;
-}
-
-/* returns on of the ENABLE_INPLACE_* return codes */
-static int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev,
-                                  off64_t size, off64_t *size_already_done,
-                                  off64_t tot_size,
-                                  off64_t previously_encrypted_upto)
-{
-    int rc_ext4, rc_f2fs, rc_full;
-    if (previously_encrypted_upto) {
-        printf("Continuing encryption from %" PRId64, previously_encrypted_upto);
-    }
-
-    if (*size_already_done + size < previously_encrypted_upto) {
-        *size_already_done += size;
-        return 0;
-    }
-
-    /* TODO: identify filesystem type.
-     * As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and
-     * then we will drop down to cryptfs_enable_inplace_f2fs.
-     * */
-    if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev,
-                                size, size_already_done,
-                                tot_size, previously_encrypted_upto)) == 0) {
-      return 0;
-    }
-    printf("cryptfs_enable_inplace_ext4()=%d\n", rc_ext4);
-
-    if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev,
-                                size, size_already_done,
-                                tot_size, previously_encrypted_upto)) == 0) {
-      return 0;
-    }
-    printf("cryptfs_enable_inplace_f2fs()=%d\n", rc_f2fs);
-
-    rc_full = cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev,
-                                       size, size_already_done, tot_size,
-                                       previously_encrypted_upto);
-    printf("cryptfs_enable_inplace_full()=%d\n", rc_full);
-
-    /* Hack for b/17898962, the following is the symptom... */
-    if (rc_ext4 == ENABLE_INPLACE_ERR_DEV
-        && rc_f2fs == ENABLE_INPLACE_ERR_DEV
-        && rc_full == ENABLE_INPLACE_ERR_DEV) {
-            return ENABLE_INPLACE_ERR_DEV;
-    }
-    return rc_full;
-}
-
-#define CRYPTO_ENABLE_WIPE 1
-#define CRYPTO_ENABLE_INPLACE 2
-
-#define FRAMEWORK_BOOT_WAIT 60
-
-static inline int should_encrypt(struct volume_info *volume)
-{
-    return (volume->flags & (VOL_ENCRYPTABLE | VOL_NONREMOVABLE)) ==
-            (VOL_ENCRYPTABLE | VOL_NONREMOVABLE);
-}
-
-static int cryptfs_SHA256_fileblock(const char* filename, __le8* buf)
-{
-    int fd = open(filename, O_RDONLY);
-    if (fd == -1) {
-        printf("Error opening file %s", filename);
-        return -1;
-    }
-
-    char block[CRYPT_INPLACE_BUFSIZE];
-    memset(block, 0, sizeof(block));
-    if (unix_read(fd, block, sizeof(block)) < 0) {
-        printf("Error reading file %s", filename);
-        close(fd);
-        return -1;
-    }
-
-    close(fd);
-
-    SHA256_CTX c;
-    SHA256_Init(&c);
-    SHA256_Update(&c, block, sizeof(block));
-    SHA256_Final(buf, &c);
-
-    return 0;
-}
-
-static int get_fs_type(struct fstab_rec *rec)
-{
-    if (!strcmp(rec->fs_type, "ext4")) {
-        return EXT4_FS;
-    } else if (!strcmp(rec->fs_type, "f2fs")) {
-        return F2FS_FS;
-    } else {
-        return -1;
-    }
-}
-
-static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr *crypt_ftr, int how,
-                                      char *crypto_blkdev, char *real_blkdev,
-                                      int previously_encrypted_upto)
-{
-    off64_t cur_encryption_done=0, tot_encryption_size=0;
-    int i, rc = -1;
-
-    if (1) {
-        printf("Not starting encryption due to low battery");
-        return 0;
-    }
-
-    /* The size of the userdata partition, and add in the vold volumes below */
-    tot_encryption_size = crypt_ftr->fs_size;
-
-    if (how == CRYPTO_ENABLE_WIPE) {
-        struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT);
-        int fs_type = get_fs_type(rec);
-        if (fs_type < 0) {
-            printf("cryptfs_enable: unsupported fs type %s\n", rec->fs_type);
-            return -1;
-        }
-        rc = cryptfs_enable_wipe(crypto_blkdev, crypt_ftr->fs_size, fs_type);
-    } else if (how == CRYPTO_ENABLE_INPLACE) {
-        rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev,
-                                    crypt_ftr->fs_size, &cur_encryption_done,
-                                    tot_encryption_size,
-                                    previously_encrypted_upto);
-
-        if (rc == ENABLE_INPLACE_ERR_DEV) {
-            /* Hack for b/17898962 */
-            printf("cryptfs_enable: crypto block dev failure. Must reboot...\n");
-            cryptfs_reboot(reboot);
-        }
-
-        if (!rc) {
-            crypt_ftr->encrypted_upto = cur_encryption_done;
-        }
-
-        if (!rc && crypt_ftr->encrypted_upto == crypt_ftr->fs_size) {
-            /* The inplace routine never actually sets the progress to 100% due
-             * to the round down nature of integer division, so set it here */
-            property_set("vold.encrypt_progress", "100");
-        }
-    } else {
-        /* Shouldn't happen */
-        printf("cryptfs_enable: internal error, unknown option\n");
-        rc = -1;
-    }
-
-    return rc;
-}
-
-int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
-                            int allow_reboot)
-{
-    int how = 0;
-    char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN];
-    unsigned long nr_sec;
-    unsigned char decrypted_master_key[KEY_LEN_BYTES];
-    int rc=-1, fd, i, ret;
-    struct crypt_mnt_ftr crypt_ftr;
-    struct crypt_persist_data *pdata;
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    char lockid[32] = { 0 };
-    char key_loc[PROPERTY_VALUE_MAX];
-    char fuse_sdcard[PROPERTY_VALUE_MAX];
-    char *sd_mnt_point;
-    int num_vols;
-    struct volume_info *vol_list = 0;
-    off64_t previously_encrypted_upto = 0;
-printf("cryptfs_enable_internal disabled by TWRP\n");
-return -1;
-    if (!strcmp(howarg, "wipe")) {
-      how = CRYPTO_ENABLE_WIPE;
-    } else if (! strcmp(howarg, "inplace")) {
-      how = CRYPTO_ENABLE_INPLACE;
-    } else {
-      /* Shouldn't happen, as CommandListener vets the args */
-      goto error_unencrypted;
-    }
-
-    /* See if an encryption was underway and interrupted */
-    if (how == CRYPTO_ENABLE_INPLACE
-          && get_crypt_ftr_and_key(&crypt_ftr) == 0
-          && (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS)) {
-        previously_encrypted_upto = crypt_ftr.encrypted_upto;
-        crypt_ftr.encrypted_upto = 0;
-        crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS;
-
-        /* At this point, we are in an inconsistent state. Until we successfully
-           complete encryption, a reboot will leave us broken. So mark the
-           encryption failed in case that happens.
-           On successfully completing encryption, remove this flag */
-        crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
-
-        put_crypt_ftr_and_key(&crypt_ftr);
-    }
-
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (!strcmp(encrypted_state, "encrypted") && !previously_encrypted_upto) {
-        printf("Device is already running encrypted, aborting");
-        goto error_unencrypted;
-    }
-
-    // TODO refactor fs_mgr_get_crypt_info to get both in one call
-    fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc));
-    fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
-
-    /* Get the size of the real block device */
-    fd = open(real_blkdev, O_RDONLY);
-    if ( (nr_sec = get_blkdev_size(fd)) == 0) {
-        printf("Cannot get size of block device %s\n", real_blkdev);
-        goto error_unencrypted;
-    }
-    close(fd);
-
-    /* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */
-    if ((how == CRYPTO_ENABLE_INPLACE) && (!strcmp(key_loc, KEY_IN_FOOTER))) {
-        unsigned int fs_size_sec, max_fs_size_sec;
-        fs_size_sec = get_fs_size(real_blkdev);
-        if (fs_size_sec == 0)
-            fs_size_sec = get_f2fs_filesystem_size_sec(real_blkdev);
-
-        max_fs_size_sec = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
-
-        if (fs_size_sec > max_fs_size_sec) {
-            printf("Orig filesystem overlaps crypto footer region.  Cannot encrypt in place.");
-            goto error_unencrypted;
-        }
-    }
-
-    /* Get a wakelock as this may take a while, and we don't want the
-     * device to sleep on us.  We'll grab a partial wakelock, and if the UI
-     * wants to keep the screen on, it can grab a full wakelock.
-     */
-    snprintf(lockid, sizeof(lockid), "enablecrypto%d", (int) getpid());
-    acquire_wake_lock(PARTIAL_WAKE_LOCK, lockid);
-
-    /* Get the sdcard mount point */
-    sd_mnt_point = getenv("EMULATED_STORAGE_SOURCE");
-    if (!sd_mnt_point) {
-       sd_mnt_point = getenv("EXTERNAL_STORAGE");
-    }
-    if (!sd_mnt_point) {
-        sd_mnt_point = "/mnt/sdcard";
-    }
-
-    /* TODO
-     * Currently do not have test devices with multiple encryptable volumes.
-     * When we acquire some, re-add support.
-     */
-    num_vols=0/*vold_getNumDirectVolumes()*/;
-    vol_list = malloc(sizeof(struct volume_info) * num_vols);
-    //vold_getDirectVolumeList(vol_list);
-
-    for (i=0; i<num_vols; i++) {
-        if (should_encrypt(&vol_list[i])) {
-            printf("Cannot encrypt if there are multiple encryptable volumes"
-                  "%s\n", vol_list[i].label);
-            goto error_unencrypted;
-        }
-    }
-
-    /* The init files are setup to stop the class main and late start when
-     * vold sets trigger_shutdown_framework.
-     */
-    property_set("vold.decrypt", "trigger_shutdown_framework");
-    printf("Just asked init to shut down class main\n");
-
-    if (1 /*vold_unmountAllAsecs()*/) {
-        /* Just report the error.  If any are left mounted,
-         * umounting /data below will fail and handle the error.
-         */
-        printf("Error unmounting internal asecs");
-    }
-
-    property_get("ro.crypto.fuse_sdcard", fuse_sdcard, "");
-    if (!strcmp(fuse_sdcard, "true")) {
-        /* This is a device using the fuse layer to emulate the sdcard semantics
-         * on top of the userdata partition.  vold does not manage it, it is managed
-         * by the sdcard service.  The sdcard service was killed by the property trigger
-         * above, so just unmount it now.  We must do this _AFTER_ killing the framework,
-         * unlike the case for vold managed devices above.
-         */
-        if (wait_and_unmount(sd_mnt_point, false)) {
-            goto error_shutting_down;
-        }
-    }
-
-    /* Now unmount the /data partition. */
-    if (wait_and_unmount(DATA_MNT_POINT, false)) {
-        if (allow_reboot) {
-            goto error_shutting_down;
-        } else {
-            goto error_unencrypted;
-        }
-    }
-
-    /* Do extra work for a better UX when doing the long inplace encryption */
-    if (how == CRYPTO_ENABLE_INPLACE) {
-        /* Now that /data is unmounted, we need to mount a tmpfs
-         * /data, set a property saying we're doing inplace encryption,
-         * and restart the framework.
-         */
-        if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) {
-            goto error_shutting_down;
-        }
-        /* Tells the framework that inplace encryption is starting */
-        property_set("vold.encrypt_progress", "0");
-
-        /* restart the framework. */
-        /* Create necessary paths on /data */
-        if (prep_data_fs()) {
-            goto error_shutting_down;
-        }
-
-        /* Ugh, shutting down the framework is not synchronous, so until it
-         * can be fixed, this horrible hack will wait a moment for it all to
-         * shut down before proceeding.  Without it, some devices cannot
-         * restart the graphics services.
-         */
-        sleep(2);
-
-        /* startup service classes main and late_start */
-        property_set("vold.decrypt", "trigger_restart_min_framework");
-        printf("Just triggered restart_min_framework\n");
-
-        /* OK, the framework is restarted and will soon be showing a
-         * progress bar.  Time to setup an encrypted mapping, and
-         * either write a new filesystem, or encrypt in place updating
-         * the progress bar as we work.
-         */
-    }
-
-    /* Start the actual work of making an encrypted filesystem */
-    /* Initialize a crypt_mnt_ftr for the partition */
-    if (previously_encrypted_upto == 0) {
-        if (cryptfs_init_crypt_mnt_ftr(&crypt_ftr)) {
-            goto error_shutting_down;
-        }
-
-        if (!strcmp(key_loc, KEY_IN_FOOTER)) {
-            crypt_ftr.fs_size = nr_sec
-              - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
-        } else {
-            crypt_ftr.fs_size = nr_sec;
-        }
-        /* At this point, we are in an inconsistent state. Until we successfully
-           complete encryption, a reboot will leave us broken. So mark the
-           encryption failed in case that happens.
-           On successfully completing encryption, remove this flag */
-        crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
-        crypt_ftr.crypt_type = crypt_type;
-        strcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256");
-
-        /* Make an encrypted master key */
-        if (create_encrypted_random_key(passwd, crypt_ftr.master_key, crypt_ftr.salt, &crypt_ftr)) {
-            printf("Cannot create encrypted master key\n");
-            goto error_shutting_down;
-        }
-
-        /* Write the key to the end of the partition */
-        put_crypt_ftr_and_key(&crypt_ftr);
-
-        /* If any persistent data has been remembered, save it.
-         * If none, create a valid empty table and save that.
-         */
-        if (!persist_data) {
-           pdata = malloc(CRYPT_PERSIST_DATA_SIZE);
-           if (pdata) {
-               init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
-               persist_data = pdata;
-           }
-        }
-        if (persist_data) {
-            save_persistent_data();
-        }
-    }
-
-    decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
-    create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev,
-                          "userdata");
-
-    /* If we are continuing, check checksums match */
-    rc = 0;
-    if (previously_encrypted_upto) {
-        __le8 hash_first_block[SHA256_DIGEST_LENGTH];
-        rc = cryptfs_SHA256_fileblock(crypto_blkdev, hash_first_block);
-
-        if (!rc && memcmp(hash_first_block, crypt_ftr.hash_first_block,
-                          sizeof(hash_first_block)) != 0) {
-            printf("Checksums do not match - trigger wipe");
-            rc = -1;
-        }
-    }
-
-    if (!rc) {
-        rc = cryptfs_enable_all_volumes(&crypt_ftr, how,
-                                        crypto_blkdev, real_blkdev,
-                                        previously_encrypted_upto);
-    }
-
-    /* Calculate checksum if we are not finished */
-    if (!rc && crypt_ftr.encrypted_upto != crypt_ftr.fs_size) {
-        rc = cryptfs_SHA256_fileblock(crypto_blkdev,
-                                      crypt_ftr.hash_first_block);
-        if (rc) {
-            printf("Error calculating checksum for continuing encryption");
-            rc = -1;
-        }
-    }
-
-    /* Undo the dm-crypt mapping whether we succeed or not */
-    delete_crypto_blk_dev("userdata");
-
-    free(vol_list);
-
-    if (! rc) {
-        /* Success */
-        crypt_ftr.flags &= ~CRYPT_INCONSISTENT_STATE;
-
-        if (crypt_ftr.encrypted_upto != crypt_ftr.fs_size) {
-            printf("Encrypted up to sector %lld - will continue after reboot",
-                  crypt_ftr.encrypted_upto);
-            crypt_ftr.flags |= CRYPT_ENCRYPTION_IN_PROGRESS;
-        }
-
-        put_crypt_ftr_and_key(&crypt_ftr);
-
-        if (crypt_ftr.encrypted_upto == crypt_ftr.fs_size) {
-          char value[PROPERTY_VALUE_MAX];
-          property_get("ro.crypto.state", value, "");
-          if (!strcmp(value, "")) {
-            /* default encryption - continue first boot sequence */
-            property_set("ro.crypto.state", "encrypted");
-            release_wake_lock(lockid);
-            cryptfs_check_passwd(DEFAULT_PASSWORD);
-            cryptfs_restart_internal(1);
-            return 0;
-          } else {
-            sleep(2); /* Give the UI a chance to show 100% progress */
-            cryptfs_reboot(reboot);
-          }
-        } else {
-            sleep(2); /* Partially encrypted, ensure writes flushed to ssd */
-            cryptfs_reboot(shutdown);
-        }
-    } else {
-        char value[PROPERTY_VALUE_MAX];
-
-        property_get("ro.vold.wipe_on_crypt_fail", value, "0");
-        if (!strcmp(value, "1")) {
-            /* wipe data if encryption failed */
-            printf("encryption failed - rebooting into recovery to wipe data\n");
-            mkdir("/cache/recovery", 0700);
-            int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC, 0600);
-            if (fd >= 0) {
-                write(fd, "--wipe_data\n", strlen("--wipe_data\n") + 1);
-                write(fd, "--reason=cryptfs_enable_internal\n", strlen("--reason=cryptfs_enable_internal\n") + 1);
-                close(fd);
-            } else {
-                printf("could not open /cache/recovery/command\n");
-            }
-            cryptfs_reboot(recovery);
-        } else {
-            /* set property to trigger dialog */
-            property_set("vold.encrypt_progress", "error_partially_encrypted");
-            release_wake_lock(lockid);
-        }
-        return -1;
-    }
-
-    /* hrm, the encrypt step claims success, but the reboot failed.
-     * This should not happen.
-     * Set the property and return.  Hope the framework can deal with it.
-     */
-    property_set("vold.encrypt_progress", "error_reboot_failed");
-    release_wake_lock(lockid);
-    return rc;
-
-error_unencrypted:
-    free(vol_list);
-    property_set("vold.encrypt_progress", "error_not_encrypted");
-    if (lockid[0]) {
-        release_wake_lock(lockid);
-    }
-    return -1;
-
-error_shutting_down:
-    /* we failed, and have not encrypted anthing, so the users's data is still intact,
-     * but the framework is stopped and not restarted to show the error, so it's up to
-     * vold to restart the system.
-     */
-    printf("Error enabling encryption after framework is shutdown, no data changed, restarting system");
-    cryptfs_reboot(reboot);
-
-    /* shouldn't get here */
-    property_set("vold.encrypt_progress", "error_shutting_down");
-    free(vol_list);
-    if (lockid[0]) {
-        release_wake_lock(lockid);
-    }
-    return -1;
-}
-
-int cryptfs_enable(char *howarg, int type, char *passwd, int allow_reboot)
-{
-    char* adjusted_passwd = adjust_passwd(passwd);
-    if (adjusted_passwd) {
-        passwd = adjusted_passwd;
-    }
-
-    int rc = cryptfs_enable_internal(howarg, type, passwd, allow_reboot);
-
-    free(adjusted_passwd);
-    return rc;
-}
-
-int cryptfs_enable_default(char *howarg, int allow_reboot)
-{
-    return cryptfs_enable_internal(howarg, CRYPT_TYPE_DEFAULT,
-                          DEFAULT_PASSWORD, allow_reboot);
-}
-
-int cryptfs_changepw(int crypt_type, const char *newpw)
-{
-    struct crypt_mnt_ftr crypt_ftr;
-    unsigned char decrypted_master_key[KEY_LEN_BYTES];
-
-    /* This is only allowed after we've successfully decrypted the master key */
-    if (!master_key_saved) {
-        printf("Key not saved, aborting");
-        return -1;
-    }
-
-    if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
-        printf("Invalid crypt_type %d", crypt_type);
-        return -1;
-    }
-
-    /* get key */
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        printf("Error getting crypt footer and key");
-        return -1;
-    }
-
-    crypt_ftr.crypt_type = crypt_type;
-
-    char* adjusted_passwd = adjust_passwd(newpw);
-    if (adjusted_passwd) {
-        newpw = adjusted_passwd;
-    }
-
-    encrypt_master_key(crypt_type == CRYPT_TYPE_DEFAULT ? DEFAULT_PASSWORD
-                                                        : newpw,
-                       crypt_ftr.salt,
-                       saved_master_key,
-                       crypt_ftr.master_key,
-                       &crypt_ftr);
-
-    /* save the key */
-    put_crypt_ftr_and_key(&crypt_ftr);
-
-    free(adjusted_passwd);
-    return 0;
-}
-
-static int persist_get_key(char *fieldname, char *value)
-{
-    unsigned int i;
-
-    if (persist_data == NULL) {
-        return -1;
-    }
-    for (i = 0; i < persist_data->persist_valid_entries; i++) {
-        if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) {
-            /* We found it! */
-            strlcpy(value, persist_data->persist_entry[i].val, PROPERTY_VALUE_MAX);
-            return 0;
-        }
-    }
-
-    return -1;
-}
-
-static int persist_set_key(char *fieldname, char *value, int encrypted)
-{
-    unsigned int i;
-    unsigned int num;
-    struct crypt_mnt_ftr crypt_ftr;
-    unsigned int max_persistent_entries;
-    unsigned int dsize;
-
-    if (persist_data == NULL) {
-        return -1;
-    }
-
-    /* If encrypted, use the values from the crypt_ftr, otherwise
-     * use the values for the current spec.
-     */
-    if (encrypted) {
-        if(get_crypt_ftr_and_key(&crypt_ftr)) {
-            return -1;
-        }
-        dsize = crypt_ftr.persist_data_size;
-    } else {
-        dsize = CRYPT_PERSIST_DATA_SIZE;
-    }
-    max_persistent_entries = (dsize - sizeof(struct crypt_persist_data)) /
-                             sizeof(struct crypt_persist_entry);
-
-    num = persist_data->persist_valid_entries;
-
-    for (i = 0; i < num; i++) {
-        if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) {
-            /* We found an existing entry, update it! */
-            memset(persist_data->persist_entry[i].val, 0, PROPERTY_VALUE_MAX);
-            strlcpy(persist_data->persist_entry[i].val, value, PROPERTY_VALUE_MAX);
-            return 0;
-        }
-    }
-
-    /* We didn't find it, add it to the end, if there is room */
-    if (persist_data->persist_valid_entries < max_persistent_entries) {
-        memset(&persist_data->persist_entry[num], 0, sizeof(struct crypt_persist_entry));
-        strlcpy(persist_data->persist_entry[num].key, fieldname, PROPERTY_KEY_MAX);
-        strlcpy(persist_data->persist_entry[num].val, value, PROPERTY_VALUE_MAX);
-        persist_data->persist_valid_entries++;
-        return 0;
-    }
-
-    return -1;
-}
-
-/* Return the value of the specified field. */
-int cryptfs_getfield(char *fieldname, char *value, int len)
-{
-    char temp_value[PROPERTY_VALUE_MAX];
-    char real_blkdev[MAXPATHLEN];
-    /* 0 is success, 1 is not encrypted,
-     * -1 is value not set, -2 is any other error
-     */
-    int rc = -2;
-
-    if (persist_data == NULL) {
-        load_persistent_data();
-        if (persist_data == NULL) {
-            printf("Getfield error, cannot load persistent data");
-            goto out;
-        }
-    }
-
-    if (!persist_get_key(fieldname, temp_value)) {
-        /* We found it, copy it to the caller's buffer and return */
-        strlcpy(value, temp_value, len);
-        rc = 0;
-    } else {
-        /* Sadness, it's not there.  Return the error */
-        rc = -1;
-    }
-
-out:
-    return rc;
-}
-
-/* Set the value of the specified field. */
-int cryptfs_setfield(char *fieldname, char *value)
-{
-    struct crypt_persist_data stored_pdata;
-    struct crypt_persist_data *pdata_p;
-    struct crypt_mnt_ftr crypt_ftr;
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    /* 0 is success, -1 is an error */
-    int rc = -1;
-    int encrypted = 0;
-
-    if (persist_data == NULL) {
-        load_persistent_data();
-        if (persist_data == NULL) {
-            printf("Setfield error, cannot load persistent data");
-            goto out;
-        }
-    }
-
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (!strcmp(encrypted_state, "encrypted") ) {
-        encrypted = 1;
-    }
-
-    if (persist_set_key(fieldname, value, encrypted)) {
-        goto out;
-    }
-
-    /* If we are running encrypted, save the persistent data now */
-    if (encrypted) {
-        if (save_persistent_data()) {
-            printf("Setfield error, cannot save persistent data");
-            goto out;
-        }
-    }
-
-    rc = 0;
-
-out:
-    return rc;
-}
-
-/* Checks userdata. Attempt to mount the volume if default-
- * encrypted.
- * On success trigger next init phase and return 0.
- * Currently do not handle failure - see TODO below.
- */
-int cryptfs_mount_default_encrypted(void)
-{
-    char decrypt_state[PROPERTY_VALUE_MAX];
-    property_get("vold.decrypt", decrypt_state, "0");
-    if (!strcmp(decrypt_state, "0")) {
-        printf("Not encrypted - should not call here");
-    } else {
-        int crypt_type = cryptfs_get_password_type();
-        if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
-            printf("Bad crypt type - error");
-        } else if (crypt_type != CRYPT_TYPE_DEFAULT) {
-            printf("Password is not default - "
-                  "starting min framework to prompt");
-            property_set("vold.decrypt", "trigger_restart_min_framework");
-            return 0;
-        } else if (cryptfs_check_passwd(DEFAULT_PASSWORD) == 0) {
-            printf("Password is default - restarting filesystem");
-            cryptfs_restart_internal(0);
-            return 0;
-        } else {
-            printf("Encrypted, default crypt type but can't decrypt");
-        }
-    }
-
-    /** Corrupt. Allow us to boot into framework, which will detect bad
-        crypto when it calls do_crypto_complete, then do a factory reset
-     */
-    property_set("vold.decrypt", "trigger_restart_min_framework");
-    return 0;
-}
-
 /* Returns type of the password, default, pattern, pin or password.
  */
 int cryptfs_get_password_type(void)
 {
     struct crypt_mnt_ftr crypt_ftr;
-    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
-    char propbuf[PROPERTY_VALUE_MAX];
-
-    property_get("ro.hardware", propbuf, "");
-    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
-
-    fstab = fs_mgr_read_fstab(fstab_filename);
-    if (!fstab) {
-        printf("failed to open %s\n", fstab_filename);
-        return -1;
-    }
 
     if (get_crypt_ftr_and_key(&crypt_ftr)) {
         printf("Error getting crypt footer and key\n");
@@ -3595,26 +1445,3 @@
 
     return crypt_ftr.crypt_type;
 }
-
-char* cryptfs_get_password()
-{
-    struct timespec now;
-    clock_gettime(CLOCK_MONOTONIC, &now);
-    if (now.tv_sec < password_expiry_time) {
-        return password;
-    } else {
-        cryptfs_clear_password();
-        return 0;
-    }
-}
-
-void cryptfs_clear_password()
-{
-    if (password) {
-        size_t len = strlen(password);
-        memset(password, 0, len);
-        free(password);
-        password = 0;
-        password_expiry_time = 0;
-    }
-}
