am df293f14: merge in master-release history after reset to b31f33b5e41bf295705b8f0c1582c6277e8fec64

* commit 'df293f14f5bdb4f572c7f836ebb0802a177836ff':
  Fix encryption on Nakasi
diff --git a/DirectVolume.cpp b/DirectVolume.cpp
index 62c0560..fdefeaf 100644
--- a/DirectVolume.cpp
+++ b/DirectVolume.cpp
@@ -18,6 +18,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <fnmatch.h>
 
 #include <linux/kdev_t.h>
 
@@ -33,6 +34,42 @@
 
 // #define PARTITION_DEBUG
 
+PathInfo::PathInfo(const char *p)
+{
+    warned = false;
+    pattern = strdup(p);
+
+    if (!strchr(pattern, '*')) {
+        patternType = prefix;
+    } else {
+        patternType = wildcard;
+    }
+}
+
+PathInfo::~PathInfo()
+{
+    free(pattern);
+}
+
+bool PathInfo::match(const char *path)
+{
+    switch (patternType) {
+    case prefix:
+    {
+        bool ret = (strncmp(path, pattern, strlen(pattern)) == 0);
+        if (!warned && ret && (strlen(pattern) != strlen(path))) {
+            SLOGW("Deprecated implied prefix pattern detected, please use '%s*' instead", pattern);
+            warned = true;
+        }
+        return ret;
+    }
+    case wildcard:
+        return fnmatch(pattern, path, 0) == 0;
+    }
+    SLOGE("Bad matching type");
+    return false;
+}
+
 DirectVolume::DirectVolume(VolumeManager *vm, const fstab_rec* rec, int flags) :
         Volume(vm, rec, flags) {
     mPaths = new PathCollection();
@@ -62,12 +99,12 @@
     PathCollection::iterator it;
 
     for (it = mPaths->begin(); it != mPaths->end(); ++it)
-        free(*it);
+        delete *it;
     delete mPaths;
 }
 
 int DirectVolume::addPath(const char *path) {
-    mPaths->push_back(strdup(path));
+    mPaths->push_back(new PathInfo(path));
     return 0;
 }
 
@@ -96,7 +133,7 @@
 
     PathCollection::iterator  it;
     for (it = mPaths->begin(); it != mPaths->end(); ++it) {
-        if (!strncmp(dp, *it, strlen(*it))) {
+        if ((*it)->match(dp)) {
             /* We can handle this disk */
             int action = evt->getAction();
             const char *devtype = evt->findParam("DEVTYPE");
@@ -401,7 +438,7 @@
     }
 
     it = mPaths->begin();
-    free(*it); /* Free the string storage */
+    delete *it; /* Free the string storage */
     mPaths->erase(it); /* Remove it from the list */
     addPath(new_path); /* Put the new path on the list */
 
diff --git a/DirectVolume.h b/DirectVolume.h
index 4495256..5e0df74 100644
--- a/DirectVolume.h
+++ b/DirectVolume.h
@@ -21,7 +21,19 @@
 
 #include "Volume.h"
 
-typedef android::List<char *> PathCollection;
+class PathInfo {
+public:
+	PathInfo(const char *pattern);
+	~PathInfo();
+	bool match(const char *path);
+private:
+	bool warned;
+	char *pattern;
+	enum PatternType { prefix, wildcard };
+	PatternType patternType;
+};
+
+typedef android::List<PathInfo *> PathCollection;
 
 class DirectVolume : public Volume {
 public:
diff --git a/Ext4.cpp b/Ext4.cpp
index b82b4c5..acf1777 100644
--- a/Ext4.cpp
+++ b/Ext4.cpp
@@ -67,9 +67,9 @@
     return rc;
 }
 
-int Ext4::format(const char *fsPath, const char *mountpoint) {
+int Ext4::format(const char *fsPath, unsigned int numSectors, const char *mountpoint) {
     int fd;
-    const char *args[5];
+    const char *args[7];
     int rc;
     int status;
 
@@ -77,7 +77,18 @@
     args[1] = "-J";
     args[2] = "-a";
     args[3] = mountpoint;
-    args[4] = fsPath;
+    if (numSectors) {
+        char tmp[32];
+        snprintf(tmp, sizeof(tmp), "%u", numSectors * 512);
+        const char *size = tmp;
+        args[4] = "-l";
+        args[5] = size;
+        args[6] = fsPath;
+        rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false, true);
+    } else {
+        args[4] = fsPath;
+        rc = android_fork_execvp(5, (char **)args, &status, false, true);
+    }
     rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
             true);
     if (rc != 0) {
diff --git a/Ext4.h b/Ext4.h
index c5ab78a..54fbec3 100644
--- a/Ext4.h
+++ b/Ext4.h
@@ -23,7 +23,7 @@
 public:
     static int doMount(const char *fsPath, const char *mountPoint, bool ro, bool remount,
             bool executable);
-    static int format(const char *fsPath, const char *mountpoint);
+    static int format(const char *fsPath, unsigned int numSectors, const char *mountpoint);
 };
 
 #endif
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 2049706..9889653 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -54,6 +54,9 @@
 
 #define MASS_STORAGE_FILE_PATH  "/sys/class/android_usb/android0/f_mass_storage/lun/file"
 
+#define ROUND_UP_POWER_OF_2(number, po2) (((!!(number & ((1U << po2) - 1))) << po2)\
+                                         + (number & (~((1U << po2) - 1))))
+
 VolumeManager *VolumeManager::sInstance = NULL;
 
 VolumeManager *VolumeManager::Instance() {
@@ -332,13 +335,17 @@
 
     /*
      * Add some headroom
+     * This is likely off by a bit, and we may want to do something different for ext4
      */
     unsigned fatSize = (((numSectors * 4) / 512) + 1) * 2;
     unsigned numImgSectors = numSectors + fatSize + 2;
-
-    if (numImgSectors % 63) {
-        numImgSectors += (63 - (numImgSectors % 63));
-    }
+    /*
+     * ext4 is aligned to 4kb. fat is aligned to 32kb. Sectors are 512b.
+     */
+    if (usingExt4)
+        numImgSectors = ROUND_UP_POWER_OF_2(numImgSectors, 3);
+    else
+        numImgSectors = ROUND_UP_POWER_OF_2(numImgSectors, 6);
 
     // Add +1 for our superblock which is at the end
     if (Loop::createImageFile(asecFileName, numImgSectors + 1)) {
@@ -433,7 +440,7 @@
         }
 
         if (usingExt4) {
-            formatStatus = Ext4::format(dmDevice, mountPoint);
+            formatStatus = Ext4::format(dmDevice, numImgSectors, mountPoint);
         } else {
             formatStatus = Fat::format(dmDevice, numImgSectors, 0);
         }
diff --git a/cryptfs.c b/cryptfs.c
index 0648231..8680698 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -1900,23 +1900,55 @@
     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)
+static void update_progress(struct encryptGroupsData* data, int is_used)
 {
     data->blocks_already_done++;
-    data->new_pct = data->blocks_already_done / data->one_pct;
+
+    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), "%lld", data->cur_pct);
         property_set("vold.encrypt_progress", buf);
+        SLOGI("Encrypted %lld percent of drive", data->cur_pct);
+    }
+
+    if (data->cur_pct >= 5) {
+        double elapsed_time = difftime(time(NULL), 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);
+        if (data->remaining_time == -1
+            || remaining_time < data->remaining_time) {
+            char buf[8];
+            snprintf(buf, sizeof(buf), "%d", remaining_time);
+            property_set("vold.encrypt_time_remaining", buf);
+
+            SLOGI("Encrypted %lld percent of drive, %d seconds to go",
+                  data->cur_pct, remaining_time);
+            data->remaining_time = remaining_time;
+        }
     }
 }
 
@@ -1994,8 +2026,9 @@
         data->count = 0;
 
         for (block = 0; block < block_count; block++) {
-            update_progress(data);
-            if (bitmap_get_bit(block_bitmap, block)) {
+            int used = bitmap_get_bit(block_bitmap, block);
+            update_progress(data, used);
+            if (used) {
                 if (data->count == 0) {
                     data->offset = offset;
                 }
@@ -2044,7 +2077,7 @@
                                        off64_t tot_size,
                                        off64_t previously_encrypted_upto)
 {
-    int i;
+    u32 i;
     struct encryptGroupsData data;
     int rc = -1;
 
@@ -2085,8 +2118,15 @@
 
     SLOGI("Encrypting filesystem in place...");
 
-    data.one_pct = data.tot_numblocks / 100;
+    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;
+    data.time_started = time(NULL);
+    data.remaining_time = -1;
 
     rc = encrypt_groups(&data);
     if (rc) {
diff --git a/vdc.c b/vdc.c
index 371f1e4..dcd2bc3 100644
--- a/vdc.c
+++ b/vdc.c
@@ -80,7 +80,7 @@
     for (i = 1; i < argc; i++) {
         char *cmp;
 
-        if (!index(argv[i], ' '))
+        if (!strchr(argv[i], ' '))
             asprintf(&cmp, "%s%s", argv[i], (i == (argc -1)) ? "" : " ");
         else
             asprintf(&cmp, "\"%s\"%s", argv[i], (i == (argc -1)) ? "" : " ");