diff options
author | Tianjie Xu <xunchang@google.com> | 2017-01-07 02:11:12 +0100 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2017-01-07 02:11:13 +0100 |
commit | ceafe69fb8126369125eec3c115a45be8244c57d (patch) | |
tree | 010dda78c69434582489d6d9aa4a2205a74caf66 /uncrypt/uncrypt.cpp | |
parent | Merge "recovery: Clean up try_update_binary() in install.cpp." (diff) | |
parent | Retry ioctl in uncrypt if it returns block# 0 (diff) | |
download | android_bootable_recovery-ceafe69fb8126369125eec3c115a45be8244c57d.tar android_bootable_recovery-ceafe69fb8126369125eec3c115a45be8244c57d.tar.gz android_bootable_recovery-ceafe69fb8126369125eec3c115a45be8244c57d.tar.bz2 android_bootable_recovery-ceafe69fb8126369125eec3c115a45be8244c57d.tar.lz android_bootable_recovery-ceafe69fb8126369125eec3c115a45be8244c57d.tar.xz android_bootable_recovery-ceafe69fb8126369125eec3c115a45be8244c57d.tar.zst android_bootable_recovery-ceafe69fb8126369125eec3c115a45be8244c57d.zip |
Diffstat (limited to 'uncrypt/uncrypt.cpp')
-rw-r--r-- | uncrypt/uncrypt.cpp | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp index 4ac516d21..a06384dd5 100644 --- a/uncrypt/uncrypt.cpp +++ b/uncrypt/uncrypt.cpp @@ -118,7 +118,8 @@ #include "error_code.h" -#define WINDOW_SIZE 5 +static constexpr int WINDOW_SIZE = 5; +static constexpr int FIBMAP_RETRY_LIMIT = 3; // uncrypt provides three services: SETUP_BCB, CLEAR_BCB and UNCRYPT. // @@ -233,6 +234,26 @@ static bool find_uncrypt_package(const std::string& uncrypt_path_file, std::stri return true; } +static int retry_fibmap(const int fd, const char* name, int* block, const int head_block) { + CHECK(block != nullptr); + for (size_t i = 0; i < FIBMAP_RETRY_LIMIT; i++) { + if (fsync(fd) == -1) { + PLOG(ERROR) << "failed to fsync \"" << name << "\""; + return kUncryptFileSyncError; + } + if (ioctl(fd, FIBMAP, block) != 0) { + PLOG(ERROR) << "failed to find block " << head_block; + return kUncryptIoctlError; + } + if (*block != 0) { + return kUncryptNoError; + } + sleep(1); + } + LOG(ERROR) << "fibmap of " << head_block << "always returns 0"; + return kUncryptIoctlError; +} + static int produce_block_map(const char* path, const char* map_file, const char* blk_dev, bool encrypted, int socket) { std::string err; @@ -314,6 +335,15 @@ static int produce_block_map(const char* path, const char* map_file, const char* PLOG(ERROR) << "failed to find block " << head_block; return kUncryptIoctlError; } + + if (block == 0) { + LOG(ERROR) << "failed to find block " << head_block << ", retrying"; + int error = retry_fibmap(fd, path, &block, head_block); + if (error != kUncryptNoError) { + return error; + } + } + add_block_to_ranges(ranges, block); if (encrypted) { if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd, @@ -350,6 +380,15 @@ static int produce_block_map(const char* path, const char* map_file, const char* PLOG(ERROR) << "failed to find block " << head_block; return kUncryptIoctlError; } + + if (block == 0) { + LOG(ERROR) << "failed to find block " << head_block << ", retrying"; + int error = retry_fibmap(fd, path, &block, head_block); + if (error != kUncryptNoError) { + return error; + } + } + add_block_to_ranges(ranges, block); if (encrypted) { if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd, |