diff --git a/EncryptInplace.cpp b/EncryptInplace.cpp
index 471daef..8baed78 100644
--- a/EncryptInplace.cpp
+++ b/EncryptInplace.cpp
@@ -20,539 +20,356 @@
 #include <ext4_utils/ext4_utils.h>
 #include <f2fs_sparseblock.h>
 #include <fcntl.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/types.h>
 #include <time.h>
 
 #include <algorithm>
+#include <vector>
 
 #include <android-base/logging.h>
 #include <android-base/properties.h>
+#include <android-base/unique_fd.h>
 
-// FIXME horrible cut-and-paste code
-static inline int unix_read(int fd, void* buff, int len) {
-    return TEMP_FAILURE_RETRY(read(fd, buff, len));
-}
-
-static inline int unix_write(int fd, const void* buff, int len) {
-    return TEMP_FAILURE_RETRY(write(fd, buff, len));
-}
-
-#define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / CRYPT_SECTOR_SIZE)
-
-/* 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 one_pct, cur_pct, new_pct;
-    off64_t blocks_already_done;
-    off64_t used_blocks_already_done, tot_used_blocks;
-    const char* real_blkdev;
-    const char* crypto_blkdev;
-    int count;
-    off64_t offset;
-    char* buffer;
-    time_t time_started;
-    int remaining_time;
-    bool set_progress_properties;
+enum EncryptInPlaceError {
+    kSuccess,
+    kFailed,
+    kFilesystemNotFound,
 };
 
-static void update_progress(struct encryptGroupsData* data, int is_used) {
-    data->blocks_already_done++;
+static uint64_t round_up(uint64_t val, size_t amount) {
+    if (val % amount) val += amount - (val % amount);
+    return val;
+}
 
-    if (is_used) {
-        data->used_blocks_already_done++;
-    }
-    if (data->tot_used_blocks) {
-        data->new_pct = data->used_blocks_already_done / data->one_pct;
+class InPlaceEncrypter {
+  public:
+    bool EncryptInPlace(const std::string& crypto_blkdev, const std::string& real_blkdev,
+                        uint64_t nr_sec, bool set_progress_properties);
+    bool ProcessUsedBlock(uint64_t block_num);
+
+  private:
+    // aligned 32K writes tends to make flash happy.
+    // SD card association recommends it.
+    static const size_t kIOBufferSize = 32768;
+
+    // Avoid spamming the logs.  Print the "Encrypting blocks" log message once
+    // every 10000 blocks (which is usually every 40 MB or so), and once at the end.
+    static const int kLogInterval = 10000;
+
+    std::string DescribeFilesystem();
+    void InitFs(const std::string& fs_type, uint64_t blocks_to_encrypt, uint64_t total_blocks,
+                unsigned int block_size);
+    void UpdateProgress(size_t blocks, bool done);
+    bool EncryptPendingData();
+    bool DoEncryptInPlace();
+
+    // ext4 methods
+    bool ReadExt4BlockBitmap(uint32_t group, uint8_t* buf);
+    uint64_t FirstBlockInGroup(uint32_t group);
+    uint32_t NumBlocksInGroup(uint32_t group);
+    uint32_t NumBaseMetaBlocksInGroup(uint64_t group);
+    EncryptInPlaceError EncryptInPlaceExt4();
+
+    // f2fs methods
+    EncryptInPlaceError EncryptInPlaceF2fs();
+
+    std::string real_blkdev_;
+    std::string crypto_blkdev_;
+    uint64_t nr_sec_;
+    bool set_progress_properties_;
+
+    android::base::unique_fd realfd_;
+    android::base::unique_fd cryptofd_;
+
+    time_t time_started_;
+    int remaining_time_;
+
+    std::string fs_type_;
+    uint64_t blocks_done_;
+    uint64_t blocks_to_encrypt_;
+    unsigned int block_size_;
+    unsigned int cur_pct_;
+
+    std::vector<uint8_t> io_buffer_;
+    uint64_t first_pending_block_;
+    size_t blocks_pending_;
+};
+
+std::string InPlaceEncrypter::DescribeFilesystem() {
+    if (fs_type_.empty())
+        return "full block device " + real_blkdev_;
+    else
+        return fs_type_ + " filesystem on " + real_blkdev_;
+}
+
+// Finishes initializing the encrypter, now that the filesystem details are known.
+void InPlaceEncrypter::InitFs(const std::string& fs_type, uint64_t blocks_to_encrypt,
+                              uint64_t total_blocks, unsigned int block_size) {
+    fs_type_ = fs_type;
+    blocks_done_ = 0;
+    blocks_to_encrypt_ = blocks_to_encrypt;
+    block_size_ = block_size;
+    cur_pct_ = 0;
+
+    // Allocate the I/O buffer.  kIOBufferSize should always be a multiple of
+    // the filesystem block size, but round it up just in case.
+    io_buffer_.resize(round_up(kIOBufferSize, block_size));
+    first_pending_block_ = 0;
+    blocks_pending_ = 0;
+
+    LOG(INFO) << "Encrypting " << DescribeFilesystem() << " in-place via " << crypto_blkdev_;
+    LOG(INFO) << blocks_to_encrypt << " blocks (" << (blocks_to_encrypt * block_size) / 1000000
+              << " MB) of " << total_blocks << " blocks are in-use";
+}
+
+void InPlaceEncrypter::UpdateProgress(size_t blocks, bool done) {
+    // A log message already got printed for blocks_done_ if one was due, so the
+    // next message will be due at the *next* block rounded up to kLogInterval.
+    uint64_t blocks_next_msg = round_up(blocks_done_ + 1, kLogInterval);
+
+    blocks_done_ += blocks;
+
+    // Ensure that a log message gets printed at the end, but not if one was
+    // already printed due to the block count being a multiple of kLogInterval.
+    // E.g. we want to show "50000 of 50327" and then "50327 of "50327", but not
+    // "50000 of 50000" and then redundantly "50000 of 50000" again.
+    if (done && blocks_done_ % kLogInterval != 0) blocks_next_msg = blocks_done_;
+
+    if (blocks_done_ >= blocks_next_msg)
+        LOG(DEBUG) << "Encrypted " << blocks_next_msg << " of " << blocks_to_encrypt_ << " blocks";
+
+    if (!set_progress_properties_) return;
+
+    uint64_t new_pct;
+    if (done) {
+        new_pct = 100;
     } else {
-        data->new_pct = data->blocks_already_done / data->one_pct;
+        new_pct = (blocks_done_ * 100) / std::max<uint64_t>(blocks_to_encrypt_, 1);
+        new_pct = std::min<uint64_t>(new_pct, 99);
+    }
+    if (new_pct > cur_pct_) {
+        cur_pct_ = new_pct;
+        android::base::SetProperty("vold.encrypt_progress", std::to_string(new_pct));
     }
 
-    if (!data->set_progress_properties) return;
-
-    if (data->new_pct > data->cur_pct) {
-        char buf[8];
-        data->cur_pct = data->new_pct;
-        snprintf(buf, sizeof(buf), "%" PRId64, data->cur_pct);
-        android::base::SetProperty("vold.encrypt_progress", buf);
-    }
-
-    if (data->cur_pct >= 5) {
+    if (cur_pct_ >= 5) {
         struct timespec time_now;
         if (clock_gettime(CLOCK_MONOTONIC, &time_now)) {
-            LOG(WARNING) << "Error getting time";
+            PLOG(WARNING) << "Error getting time while updating encryption progress";
         } 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);
+            double elapsed_time = difftime(time_now.tv_sec, time_started_);
+
+            uint64_t remaining_blocks = 0;
+            if (blocks_done_ < blocks_to_encrypt_)
+                remaining_blocks = blocks_to_encrypt_ - blocks_done_;
+
+            int remaining_time = 0;
+            if (blocks_done_ != 0)
+                remaining_time = (int)(elapsed_time * remaining_blocks / blocks_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);
-                android::base::SetProperty("vold.encrypt_time_remaining", buf);
-                data->remaining_time = remaining_time;
+            if (remaining_time_ == -1 || remaining_time < remaining_time_ ||
+                remaining_time > remaining_time_ + 60) {
+                remaining_time_ = remaining_time;
+                android::base::SetProperty("vold.encrypt_time_remaining",
+                                           std::to_string(remaining_time));
             }
         }
     }
 }
 
-static void log_progress(struct encryptGroupsData const* data, bool completed) {
-    // Precondition - if completed data = 0 else data != 0
+bool InPlaceEncrypter::EncryptPendingData() {
+    if (blocks_pending_ == 0) return true;
 
-    // Track progress so we can skip logging blocks
-    static off64_t offset = -1;
+    ssize_t bytes = blocks_pending_ * block_size_;
+    uint64_t offset = first_pending_block_ * block_size_;
 
-    // Need to close existing 'Encrypting from' log?
-    if (completed || (offset != -1 && data->offset != offset)) {
-        LOG(INFO) << "Encrypted to sector " << offset / info.block_size * CRYPT_SECTOR_SIZE;
-        offset = -1;
+    if (pread64(realfd_, &io_buffer_[0], bytes, offset) != bytes) {
+        PLOG(ERROR) << "Error reading real_blkdev " << real_blkdev_ << " for inplace encrypt";
+        return false;
     }
 
-    // Need to start new 'Encrypting from' log?
-    if (!completed && offset != data->offset) {
-        LOG(INFO) << "Encrypting from sector " << data->offset / info.block_size * CRYPT_SECTOR_SIZE;
+    if (pwrite64(cryptofd_, &io_buffer_[0], bytes, offset) != bytes) {
+        PLOG(ERROR) << "Error writing crypto_blkdev " << crypto_blkdev_ << " for inplace encrypt";
+        return false;
     }
 
-    // Update offset
-    if (!completed) {
-        offset = data->offset + (off64_t)data->count * info.block_size;
-    }
+    UpdateProgress(blocks_pending_, false);
+
+    blocks_pending_ = 0;
+    return true;
 }
 
-static int flush_outstanding_data(struct encryptGroupsData* data) {
-    if (data->count == 0) {
-        return 0;
+bool InPlaceEncrypter::ProcessUsedBlock(uint64_t block_num) {
+    // Flush if the amount of pending data has reached the I/O buffer size, if
+    // there's a gap between the pending blocks and the next block (due to
+    // block(s) not being used by the filesystem and thus not needing
+    // encryption), or if the next block will be aligned to the I/O buffer size.
+    if (blocks_pending_ * block_size_ == io_buffer_.size() ||
+        block_num != first_pending_block_ + blocks_pending_ ||
+        (block_num * block_size_) % io_buffer_.size() == 0) {
+        if (!EncryptPendingData()) return false;
+        first_pending_block_ = block_num;
     }
-
-    LOG(DEBUG) << "Copying " << data->count << " blocks at offset " << data->offset;
-
-    if (pread64(data->realfd, data->buffer, info.block_size * data->count, data->offset) <= 0) {
-        LOG(ERROR) << "Error reading real_blkdev " << data->real_blkdev << " for inplace encrypt";
-        return -1;
-    }
-
-    if (pwrite64(data->cryptofd, data->buffer, info.block_size * data->count, data->offset) <= 0) {
-        LOG(ERROR) << "Error writing crypto_blkdev " << data->crypto_blkdev
-                   << " for inplace encrypt";
-        return -1;
-    } else {
-        log_progress(data, false);
-    }
-
-    data->count = 0;
-    return 0;
+    blocks_pending_++;
+    return true;
 }
 
-static uint64_t first_block_in_group(uint32_t group) {
+// Reads the block bitmap for block group |group| into |buf|.
+bool InPlaceEncrypter::ReadExt4BlockBitmap(uint32_t group, uint8_t* buf) {
+    uint64_t offset = (uint64_t)aux_info.bg_desc[group].bg_block_bitmap * info.block_size;
+    if (pread64(realfd_, buf, info.block_size, offset) != (ssize_t)info.block_size) {
+        PLOG(ERROR) << "Failed to read block bitmap for block group " << group;
+        return false;
+    }
+    return true;
+}
+
+uint64_t InPlaceEncrypter::FirstBlockInGroup(uint32_t group) {
     return aux_info.first_data_block + (group * (uint64_t)info.blocks_per_group);
 }
 
-static uint32_t num_blocks_in_group(uint32_t group) {
-    uint64_t remaining = aux_info.len_blocks - first_block_in_group(group);
+uint32_t InPlaceEncrypter::NumBlocksInGroup(uint32_t group) {
+    uint64_t remaining = aux_info.len_blocks - FirstBlockInGroup(group);
     return std::min<uint64_t>(info.blocks_per_group, remaining);
 }
 
 // In block groups with an uninitialized block bitmap, we only need to encrypt
 // the backup superblock and the block group descriptors (if they are present).
-static uint32_t num_base_meta_blocks_in_group(uint64_t group) {
+uint32_t InPlaceEncrypter::NumBaseMetaBlocksInGroup(uint64_t group) {
     if (!ext4_bg_has_super_block(group)) return 0;
     return 1 + aux_info.bg_desc_blocks;
 }
 
-static int encrypt_groups(struct encryptGroupsData* data) {
-    unsigned int i;
-    u8* block_bitmap = 0;
-    unsigned int block;
-    off64_t ret;
-    int rc = -1;
+EncryptInPlaceError InPlaceEncrypter::EncryptInPlaceExt4() {
+    if (setjmp(setjmp_env))  // NOLINT
+        return kFilesystemNotFound;
 
-    data->buffer = (char*)malloc(info.block_size * BLOCKS_AT_A_TIME);
-    if (!data->buffer) {
-        LOG(ERROR) << "Failed to allocate crypto buffer";
-        goto errout;
-    }
+    if (read_ext(realfd_, 0) != 0) return kFilesystemNotFound;
 
-    block_bitmap = (u8*)malloc(info.block_size);
-    if (!block_bitmap) {
-        LOG(ERROR) << "failed to allocate block bitmap";
-        goto errout;
-    }
+    LOG(DEBUG) << "ext4 filesystem has " << aux_info.groups << " block groups";
 
-    for (i = 0; i < aux_info.groups; ++i) {
-        LOG(INFO) << "Encrypting group " << i;
-
-        u32 block_count = num_blocks_in_group(i);
-
-        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) {
-            LOG(ERROR) << "failed to read all of block group bitmap " << i;
-            goto errout;
-        }
-
-        offset = (u64)info.block_size * first_block_in_group(i);
-
-        data->count = 0;
-
-        for (block = 0; block < block_count; block++) {
-            int used;
-
-            if (aux_info.bg_desc[i].bg_flags & EXT4_BG_BLOCK_UNINIT)
-                used = (block < num_base_meta_blocks_in_group(i));
-            else
-                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 (flush_outstanding_data(data)) {
-            goto errout;
-        }
-    }
-
-    rc = 0;
-
-errout:
-    log_progress(0, true);
-    free(data->buffer);
-    free(block_bitmap);
-    return rc;
-}
-
-static int cryptfs_enable_inplace_ext4(const char* crypto_blkdev, const char* real_blkdev,
-                                       off64_t size, bool set_progress_properties) {
-    u32 i;
-    struct encryptGroupsData data;
-    int rc;  // Can't initialize without causing warning -Wclobbered
-    int retries = RETRY_MOUNT_ATTEMPTS;
-    struct timespec time_started = {0};
-
-    memset(&data, 0, sizeof(data));
-    data.real_blkdev = real_blkdev;
-    data.crypto_blkdev = crypto_blkdev;
-    data.set_progress_properties = set_progress_properties;
-
-    LOG(DEBUG) << "Opening" << real_blkdev;
-    if ((data.realfd = open(real_blkdev, O_RDWR | O_CLOEXEC)) < 0) {
-        PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
-        rc = -1;
-        goto errout;
-    }
-
-    LOG(DEBUG) << "Opening" << crypto_blkdev;
-    if ((data.cryptofd = open(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
-        PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev << " for inplace encrypt";
-        rc = -1;
-        goto errout;
-    }
-
-    if (setjmp(setjmp_env)) {  // NOLINT
-        LOG(ERROR) << "Reading ext4 extent caused an exception";
-        rc = -1;
-        goto errout;
-    }
-
-    if (read_ext(data.realfd, 0) != 0) {
-        LOG(ERROR) << "Failed to read ext4 extent";
-        rc = -1;
-        goto errout;
-    }
-
-    data.blocks_already_done = 0;
-
-    LOG(INFO) << "Encrypting ext4 filesystem in place...";
-
-    data.tot_used_blocks = 0;
-    for (i = 0; i < aux_info.groups; ++i) {
-        if (aux_info.bg_desc[i].bg_flags & EXT4_BG_BLOCK_UNINIT)
-            data.tot_used_blocks += num_base_meta_blocks_in_group(i);
+    uint64_t blocks_to_encrypt = 0;
+    for (uint32_t group = 0; group < aux_info.groups; group++) {
+        if (aux_info.bg_desc[group].bg_flags & EXT4_BG_BLOCK_UNINIT)
+            blocks_to_encrypt += NumBaseMetaBlocksInGroup(group);
         else
-            data.tot_used_blocks +=
-                    (num_blocks_in_group(i) - aux_info.bg_desc[i].bg_free_blocks_count);
+            blocks_to_encrypt +=
+                    (NumBlocksInGroup(group) - aux_info.bg_desc[group].bg_free_blocks_count);
     }
 
-    data.one_pct = data.tot_used_blocks / 100;
-    data.cur_pct = 0;
+    InitFs("ext4", blocks_to_encrypt, aux_info.len_blocks, info.block_size);
 
-    if (clock_gettime(CLOCK_MONOTONIC, &time_started)) {
-        LOG(WARNING) << "Error getting time at start";
-        // Note - continue anyway - we'll run with 0
+    // Encrypt each block group.
+    std::vector<uint8_t> block_bitmap(info.block_size);
+    for (uint32_t group = 0; group < aux_info.groups; group++) {
+        if (!ReadExt4BlockBitmap(group, &block_bitmap[0])) return kFailed;
+
+        uint64_t first_block_num = FirstBlockInGroup(group);
+        bool uninit = (aux_info.bg_desc[group].bg_flags & EXT4_BG_BLOCK_UNINIT);
+        uint32_t block_count = uninit ? NumBaseMetaBlocksInGroup(group) : NumBlocksInGroup(group);
+
+        // Encrypt each used block in the block group.
+        for (uint32_t i = 0; i < block_count; i++) {
+            if (uninit || bitmap_get_bit(&block_bitmap[0], i))
+                ProcessUsedBlock(first_block_num + i);
+        }
     }
-    data.time_started = time_started.tv_sec;
-    data.remaining_time = -1;
-
-    rc = encrypt_groups(&data);
-    if (rc) {
-        LOG(ERROR) << "Error encrypting groups";
-        goto errout;
-    }
-
-    rc = 0;
-
-errout:
-    close(data.realfd);
-    close(data.cryptofd);
-
-    return rc;
+    return kSuccess;
 }
 
-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)) {
-        LOG(INFO) << "Encrypted to block " << last_block;
-        last_block = -1;
-    }
-
-    // Need to start new 'Encrypting from' log?
-    if (!completed && (last_block == (u64)-1 || block != last_block + 1)) {
-        LOG(INFO) << "Encrypting from block " << 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) {
-        LOG(ERROR) << "Error reading real_blkdev " << priv_dat->crypto_blkdev
-                   << " for f2fs inplace encrypt";
-        return -1;
-    }
-
-    if (pwrite64(priv_dat->cryptofd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
-        LOG(ERROR) << "Error writing crypto_blkdev " << priv_dat->crypto_blkdev
-                   << " for f2fs inplace encrypt";
-        return -1;
-    } else {
-        log_progress_f2fs(pos, false);
-    }
-
+static int encrypt_f2fs_block(uint64_t block_num, void* _encrypter) {
+    InPlaceEncrypter* encrypter = reinterpret_cast<InPlaceEncrypter*>(_encrypter);
+    if (!encrypter->ProcessUsedBlock(block_num)) return -1;
     return 0;
 }
 
-static int cryptfs_enable_inplace_f2fs(const char* crypto_blkdev, const char* real_blkdev,
-                                       off64_t size, bool set_progress_properties) {
-    struct encryptGroupsData data;
-    struct f2fs_info* f2fs_info = NULL;
-    int rc = ENABLE_INPLACE_ERR_OTHER;
+EncryptInPlaceError InPlaceEncrypter::EncryptInPlaceF2fs() {
+    std::unique_ptr<struct f2fs_info, void (*)(struct f2fs_info*)> fs_info(
+            generate_f2fs_info(realfd_), free_f2fs_info);
+    if (!fs_info) return kFilesystemNotFound;
+
+    InitFs("f2fs", get_num_blocks_used(fs_info.get()), fs_info->total_blocks, fs_info->block_size);
+    if (run_on_used_blocks(0, fs_info.get(), encrypt_f2fs_block, this) != 0) return kFailed;
+    return kSuccess;
+}
+
+bool InPlaceEncrypter::DoEncryptInPlace() {
+    EncryptInPlaceError rc;
+
+    rc = EncryptInPlaceExt4();
+    if (rc != kFilesystemNotFound) return rc == kSuccess;
+
+    rc = EncryptInPlaceF2fs();
+    if (rc != kFilesystemNotFound) return rc == kSuccess;
+
+    LOG(WARNING) << "No recognized filesystem found on " << real_blkdev_
+                 << ".  Falling back to encrypting the full block device.";
+    InitFs("", nr_sec_, nr_sec_, 512);
+    for (uint64_t i = 0; i < nr_sec_; i++) {
+        if (!ProcessUsedBlock(i)) return false;
+    }
+    return true;
+}
+
+bool InPlaceEncrypter::EncryptInPlace(const std::string& crypto_blkdev,
+                                      const std::string& real_blkdev, uint64_t nr_sec,
+                                      bool set_progress_properties) {
     struct timespec time_started = {0};
 
-    memset(&data, 0, sizeof(data));
-    data.real_blkdev = real_blkdev;
-    data.crypto_blkdev = crypto_blkdev;
-    data.set_progress_properties = set_progress_properties;
-    data.realfd = -1;
-    data.cryptofd = -1;
-    if ((data.realfd = open64(real_blkdev, O_RDWR | O_CLOEXEC)) < 0) {
-        PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for f2fs inplace encrypt";
-        goto errout;
-    }
-    if ((data.cryptofd = open64(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
-        PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev
-                    << " for f2fs inplace encrypt";
-        goto errout;
+    real_blkdev_ = real_blkdev;
+    crypto_blkdev_ = crypto_blkdev;
+    nr_sec_ = nr_sec;
+    set_progress_properties_ = set_progress_properties;
+
+    realfd_.reset(open64(real_blkdev.c_str(), O_RDONLY | O_CLOEXEC));
+    if (realfd_ < 0) {
+        PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
+        return false;
     }
 
-    f2fs_info = generate_f2fs_info(data.realfd);
-    if (!f2fs_info) goto errout;
+    cryptofd_.reset(open64(crypto_blkdev.c_str(), O_WRONLY | O_CLOEXEC));
+    if (cryptofd_ < 0) {
+        PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev << " for inplace encrypt";
+        return false;
+    }
 
-    data.blocks_already_done = 0;
-
-    data.tot_used_blocks = get_num_blocks_used(f2fs_info);
-
-    data.one_pct = data.tot_used_blocks / 100;
-    data.cur_pct = 0;
     if (clock_gettime(CLOCK_MONOTONIC, &time_started)) {
-        LOG(WARNING) << "Error getting time at start";
+        PLOG(WARNING) << "Error getting time at start of in-place encryption";
         // Note - continue anyway - we'll run with 0
     }
-    data.time_started = time_started.tv_sec;
-    data.remaining_time = -1;
+    time_started_ = time_started.tv_sec;
+    remaining_time_ = -1;
 
+    bool success = DoEncryptInPlace();
 
-    data.buffer = (char*)malloc(f2fs_info->block_size);
-    if (!data.buffer) {
-        LOG(ERROR) << "Failed to allocate crypto buffer";
-        goto errout;
+    if (success) success &= EncryptPendingData();
+
+    if (!success) {
+        LOG(ERROR) << "In-place encryption of " << DescribeFilesystem() << " failed";
+        return false;
     }
-
-    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) {
-        LOG(ERROR) << "Error in running over f2fs blocks";
-        rc = ENABLE_INPLACE_ERR_OTHER;
-        goto errout;
+    if (blocks_done_ != blocks_to_encrypt_) {
+        LOG(WARNING) << "blocks_to_encrypt (" << blocks_to_encrypt_
+                     << ") was incorrect; we actually encrypted " << blocks_done_
+                     << " blocks.  Encryption progress was inaccurate";
     }
-
-    rc = 0;
-
-errout:
-    if (rc) LOG(ERROR) << "Failed to encrypt f2fs filesystem on " << real_blkdev;
-
-    log_progress_f2fs(0, true);
-    free_f2fs_info(f2fs_info);
-    free(data.buffer);
-    close(data.realfd);
-    close(data.cryptofd);
-
-    return rc;
+    // Make sure vold.encrypt_progress gets set to 100.
+    UpdateProgress(0, true);
+    LOG(INFO) << "Successfully encrypted " << DescribeFilesystem();
+    return true;
 }
 
-static int cryptfs_enable_inplace_full(const char* crypto_blkdev, const char* real_blkdev,
-                                       off64_t size, bool set_progress_properties) {
-    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;
+// Encrypts |real_blkdev| in-place by reading the data from |real_blkdev| and
+// writing it to |crypto_blkdev|, which should be a dm-crypt or dm-default-key
+// device backed by |real_blkdev|.  The size to encrypt is |nr_sec| 512-byte
+// sectors; however, if a filesystem is detected, then its size will be used
+// instead, and only the in-use blocks of the filesystem will be encrypted.
+bool encrypt_inplace(const std::string& crypto_blkdev, const std::string& real_blkdev,
+                     uint64_t nr_sec, bool set_progress_properties) {
+    LOG(DEBUG) << "encrypt_inplace(" << crypto_blkdev << ", " << real_blkdev << ", " << nr_sec
+               << ", " << (set_progress_properties ? "true" : "false") << ")";
 
-    if ((realfd = open(real_blkdev, O_RDONLY | O_CLOEXEC)) < 0) {
-        PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
-        return ENABLE_INPLACE_ERR_OTHER;
-    }
-
-    if ((cryptofd = open(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
-        PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev << " for inplace encrypt";
-        close(realfd);
-        return ENABLE_INPLACE_ERR_OTHER;
-    }
-
-    /* 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;
-
-    LOG(ERROR) << "Encrypting filesystem in place...";
-
-    one_pct = numblocks / 100;
-    cur_pct = 0;
-    /* process the majority of the filesystem in blocks */
-    for (i = 0; i < numblocks; i++) {
-        new_pct = i / one_pct;
-        if (set_progress_properties && new_pct > cur_pct) {
-            char property_buf[8];
-
-            cur_pct = new_pct;
-            snprintf(property_buf, sizeof(property_buf), "%" PRId64, cur_pct);
-            android::base::SetProperty("vold.encrypt_progress", property_buf);
-        }
-        if (unix_read(realfd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
-            PLOG(ERROR) << "Error reading real_blkdev " << real_blkdev << " for inplace encrypt";
-            goto errout;
-        }
-        if (unix_write(cryptofd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
-            PLOG(ERROR) << "Error writing crypto_blkdev " << crypto_blkdev << " for inplace encrypt";
-            goto errout;
-        } else {
-            LOG(DEBUG) << "Encrypted " << CRYPT_SECTORS_PER_BUFSIZE << " block at "
-                       << i * CRYPT_SECTORS_PER_BUFSIZE;
-        }
-    }
-
-    /* Do any remaining sectors */
-    for (i = 0; i < remainder; i++) {
-        if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
-            LOG(ERROR) << "Error reading final sectors from real_blkdev " << real_blkdev
-                       << " for inplace encrypt";
-            goto errout;
-        }
-        if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) {
-            LOG(ERROR) << "Error writing final sectors to crypto_blkdev " << crypto_blkdev
-                       << " for inplace encrypt";
-            goto errout;
-        } else {
-            LOG(INFO) << "Encrypted 1 block at next location";
-        }
-    }
-
-    rc = 0;
-
-errout:
-    close(realfd);
-    close(cryptofd);
-
-    return rc;
-}
-
-/* returns on of the ENABLE_INPLACE_* return codes */
-int cryptfs_enable_inplace(const char* crypto_blkdev, const char* real_blkdev, off64_t size,
-                           bool set_progress_properties) {
-    int rc_ext4, rc_f2fs, rc_full;
-    LOG(DEBUG) << "cryptfs_enable_inplace(" << crypto_blkdev << ", " << real_blkdev << ", " << size
-               << ", " << set_progress_properties << ")";
-
-    /* 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,
-                                               set_progress_properties)) == 0) {
-        LOG(DEBUG) << "cryptfs_enable_inplace_ext4 success";
-        return 0;
-    }
-    LOG(DEBUG) << "cryptfs_enable_inplace_ext4()=" << rc_ext4;
-
-    if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev, size,
-                                               set_progress_properties)) == 0) {
-        LOG(DEBUG) << "cryptfs_enable_inplace_f2fs success";
-        return 0;
-    }
-    LOG(DEBUG) << "cryptfs_enable_inplace_f2fs()=" << rc_f2fs;
-
-    rc_full =
-            cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev, size, set_progress_properties);
-    LOG(DEBUG) << "cryptfs_enable_inplace_full()=" << rc_full;
-    return rc_full;
+    InPlaceEncrypter encrypter;
+    return encrypter.EncryptInPlace(crypto_blkdev, real_blkdev, nr_sec, set_progress_properties);
 }
