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

Commit adb98df1 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "PartitionCowCreator accounts for extra extents"

parents 4ac630b5 33836a60
Loading
Loading
Loading
Loading
+18 −11
Original line number Diff line number Diff line
@@ -62,27 +62,34 @@ bool PartitionCowCreator::HasExtent(Partition* p, Extent* e) {
    return false;
}

void WriteExtent(DmSnapCowSizeCalculator* sc, const chromeos_update_engine::Extent& de,
                 unsigned int sectors_per_block) {
    const auto block_boundary = de.start_block() + de.num_blocks();
    for (auto b = de.start_block(); b < block_boundary; ++b) {
        for (unsigned int s = 0; s < sectors_per_block; ++s) {
            const auto sector_id = b * sectors_per_block + s;
            sc->WriteSector(sector_id);
        }
    }
}

uint64_t PartitionCowCreator::GetCowSize() {
    // WARNING: The origin partition should be READ-ONLY
    const uint64_t logical_block_size = current_metadata->logical_block_size();
    const unsigned int sectors_per_block = logical_block_size / kSectorSize;
    DmSnapCowSizeCalculator sc(kSectorSize, kSnapshotChunkSize);

    // Allocate space for extra extents (if any). These extents are those that can be
    // used for error corrections or to store verity hash trees.
    for (const auto& de : extra_extents) {
        WriteExtent(&sc, de, sectors_per_block);
    }

    if (operations == nullptr) return sc.cow_size_bytes();

    for (const auto& iop : *operations) {
        for (const auto& de : iop.dst_extents()) {
            // Skip if no blocks are written
            if (de.num_blocks() == 0) continue;

            // Flag all the blocks that were written
            const auto block_boundary = de.start_block() + de.num_blocks();
            for (auto b = de.start_block(); b < block_boundary; ++b) {
                for (unsigned int s = 0; s < sectors_per_block; ++s) {
                    const auto sector_id = b * sectors_per_block + s;
                    sc.WriteSector(sector_id);
                }
            }
            WriteExtent(&sc, de, sectors_per_block);
        }
    }

+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <optional>
#include <string>
#include <vector>

#include <liblp/builder.h>
#include <update_engine/update_metadata.pb.h>
@@ -30,6 +31,7 @@ namespace snapshot {
// Helper class that creates COW for a partition.
struct PartitionCowCreator {
    using Extent = android::fs_mgr::Extent;
    using ChromeOSExtent = chromeos_update_engine::Extent;
    using Interval = android::fs_mgr::Interval;
    using MetadataBuilder = android::fs_mgr::MetadataBuilder;
    using Partition = android::fs_mgr::Partition;
@@ -50,6 +52,9 @@ struct PartitionCowCreator {
    std::string current_suffix;
    // List of operations to be applied on the partition.
    const RepeatedPtrField<InstallOperation>* operations = nullptr;
    // Extra extents that are going to be invalidated during the update
    // process.
    std::vector<ChromeOSExtent> extra_extents = {};

    struct Return {
        SnapshotStatus snapshot_status;
+27 −8
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ using android::fs_mgr::MetadataBuilder;
using android::fs_mgr::SlotNumberForSlotSuffix;
using android::hardware::boot::V1_1::MergeStatus;
using chromeos_update_engine::DeltaArchiveManifest;
using chromeos_update_engine::Extent;
using chromeos_update_engine::InstallOperation;
template <typename T>
using RepeatedPtrField = google::protobuf::RepeatedPtrField<T>;
@@ -1886,12 +1887,15 @@ bool SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manifest
    // these devices.
    AutoDeviceList created_devices;

    PartitionCowCreator cow_creator{.target_metadata = target_metadata.get(),
    PartitionCowCreator cow_creator{
            .target_metadata = target_metadata.get(),
            .target_suffix = target_suffix,
            .target_partition = nullptr,
            .current_metadata = current_metadata.get(),
            .current_suffix = current_suffix,
                                    .operations = nullptr};
            .operations = nullptr,
            .extra_extents = {},
    };

    if (!CreateUpdateSnapshotsInternal(lock.get(), manifest, &cow_creator, &created_devices,
                                       &all_snapshot_status)) {
@@ -1937,15 +1941,24 @@ bool SnapshotManager::CreateUpdateSnapshotsInternal(
    }

    std::map<std::string, const RepeatedPtrField<InstallOperation>*> install_operation_map;
    std::map<std::string, std::vector<Extent>> extra_extents_map;
    for (const auto& partition_update : manifest.partitions()) {
        auto suffixed_name = partition_update.partition_name() + target_suffix;
        auto&& [it, inserted] = install_operation_map.emplace(std::move(suffixed_name),
                                                              &partition_update.operations());
        auto&& [it, inserted] =
                install_operation_map.emplace(suffixed_name, &partition_update.operations());
        if (!inserted) {
            LOG(ERROR) << "Duplicated partition " << partition_update.partition_name()
                       << " in update manifest.";
            return false;
        }

        auto& extra_extents = extra_extents_map[suffixed_name];
        if (partition_update.has_hash_tree_extent()) {
            extra_extents.push_back(partition_update.hash_tree_extent());
        }
        if (partition_update.has_fec_extent()) {
            extra_extents.push_back(partition_update.fec_extent());
        }
    }

    for (auto* target_partition : ListPartitionsWithSuffix(target_metadata, target_suffix)) {
@@ -1956,6 +1969,12 @@ bool SnapshotManager::CreateUpdateSnapshotsInternal(
            cow_creator->operations = operations_it->second;
        }

        cow_creator->extra_extents.clear();
        auto extra_extents_it = extra_extents_map.find(target_partition->name());
        if (extra_extents_it != extra_extents_map.end()) {
            cow_creator->extra_extents = std::move(extra_extents_it->second);
        }

        // Compute the device sizes for the partition.
        auto cow_creator_ret = cow_creator->Run();
        if (!cow_creator_ret.has_value()) {