Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ba8eea4 authored by Akilesh Kailash's avatar Akilesh Kailash
Browse files

snapuserd: Sort REPLACE ops for batch merge



Since we will be iterating forward for user-space
merge, we need to sort the blocks in increasing order
so that blocks can be batch merged if contiguous.

For dm-snapshot merging, we will continue to sort
in decreasing order.

Bug: 193863397
Test: Snapuserd_test
Signed-off-by: default avatarAkilesh Kailash <akailash@google.com>
Change-Id: I25fb5fce054f716a2ad0dddc0d0c3afef18bc7ad
parent b94353ca
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -34,11 +34,12 @@
namespace android {
namespace snapshot {

CowReader::CowReader()
CowReader::CowReader(ReaderFlags reader_flag)
    : fd_(-1),
      header_(),
      fd_size_(0),
      merge_op_blocks_(std::make_shared<std::vector<uint32_t>>()) {}
      merge_op_blocks_(std::make_shared<std::vector<uint32_t>>()),
      reader_flag_(reader_flag) {}

static void SHA256(const void*, size_t, uint8_t[]) {
#if 0
@@ -415,7 +416,7 @@ bool CowReader::ParseOps(std::optional<uint64_t> label) {
//==============================================================
bool CowReader::PrepMergeOps() {
    auto merge_op_blocks = std::make_shared<std::vector<uint32_t>>();
    std::set<int, std::greater<int>> other_ops;
    std::vector<int> other_ops;
    auto seq_ops_set = std::unordered_set<uint32_t>();
    auto block_map = std::make_shared<std::unordered_map<uint32_t, int>>();
    size_t num_seqs = 0;
@@ -446,7 +447,7 @@ bool CowReader::PrepMergeOps() {
        if (!has_seq_ops_ && IsOrderedOp(current_op)) {
            merge_op_blocks->emplace_back(current_op.new_block);
        } else if (seq_ops_set.count(current_op.new_block) == 0) {
            other_ops.insert(current_op.new_block);
            other_ops.push_back(current_op.new_block);
        }
        block_map->insert({current_op.new_block, i});
    }
@@ -462,6 +463,18 @@ bool CowReader::PrepMergeOps() {
    } else {
        num_ordered_ops_to_merge_ = 0;
    }

    // Sort the vector in increasing order if merging in user-space as
    // we can batch merge them when iterating from forward.
    //
    // dm-snapshot-merge requires decreasing order as we iterate the blocks
    // in reverse order.
    if (reader_flag_ == ReaderFlags::USERSPACE_MERGE) {
        std::sort(other_ops.begin(), other_ops.end());
    } else {
        std::sort(other_ops.begin(), other_ops.end(), std::greater<int>());
    }

    merge_op_blocks->reserve(merge_op_blocks->size() + other_ops.size());
    for (auto block : other_ops) {
        merge_op_blocks->emplace_back(block);
+7 −1
Original line number Diff line number Diff line
@@ -104,7 +104,12 @@ class ICowOpIter {

class CowReader final : public ICowReader {
  public:
    CowReader();
    enum class ReaderFlags {
        DEFAULT = 0,
        USERSPACE_MERGE = 1,
    };

    CowReader(ReaderFlags reader_flag = ReaderFlags::DEFAULT);
    ~CowReader() { owned_fd_ = {}; }

    // Parse the COW, optionally, up to the given label. If no label is
@@ -166,6 +171,7 @@ class CowReader final : public ICowReader {
    uint64_t num_ordered_ops_to_merge_;
    bool has_seq_ops_;
    std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc_;
    ReaderFlags reader_flag_;
};

}  // namespace snapshot
+1 −1
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ void SnapshotHandler::CheckMergeCompletionStatus() {
}

bool SnapshotHandler::ReadMetadata() {
    reader_ = std::make_unique<CowReader>();
    reader_ = std::make_unique<CowReader>(CowReader::ReaderFlags::USERSPACE_MERGE);
    CowHeader header;
    CowOptions options;