Merge "Reset failed decryption count on successful decryptions" into lmp-dev
diff --git a/cryptfs.c b/cryptfs.c
index 01dfec3..ec565c8 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -40,6 +40,7 @@
#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"
@@ -1426,26 +1427,38 @@
return encrypt_master_key(passwd, salt, key_buf, master_key, crypt_ftr);
}
-static int wait_and_unmount(char *mountpoint)
+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)) {
- 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;
- sleep(1);
- i++;
- } else {
- break;
+ 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)) {
+ SLOGW("sending SIGHUP to processes with open files\n");
+ vold_killProcessesWithOpenFiles(mountpoint, 1);
+ } else if (i == (WAIT_UNMOUNT_COUNT - 2)) {
+ SLOGW("sending SIGKILL to processes with open files\n");
+ vold_killProcessesWithOpenFiles(mountpoint, 2);
+ }
+ }
+
+ sleep(1);
}
if (i < WAIT_UNMOUNT_COUNT) {
@@ -1587,7 +1600,7 @@
return -1;
}
- if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) {
+ 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.
@@ -2130,21 +2143,26 @@
}
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);
+ struct timespec time_now;
+ if (clock_gettime(CLOCK_MONOTONIC, &time_now)) {
+ SLOGW("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;
+ // 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;
+ }
}
}
}
@@ -2352,7 +2370,13 @@
data.one_pct = data.tot_used_blocks / 100;
data.cur_pct = 0;
- data.time_started = time(NULL);
+
+ struct timespec time_started = {0};
+ if (clock_gettime(CLOCK_MONOTONIC, &time_started)) {
+ SLOGW("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);
@@ -2877,13 +2901,13 @@
* 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)) {
+ if (wait_and_unmount(sd_mnt_point, false)) {
goto error_shutting_down;
}
}
/* Now unmount the /data partition. */
- if (wait_and_unmount(DATA_MNT_POINT)) {
+ if (wait_and_unmount(DATA_MNT_POINT, false)) {
if (allow_reboot) {
goto error_shutting_down;
} else {