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

Commit dff772c2 authored by Alessio Balsini's avatar Alessio Balsini Committed by android-build-merger
Browse files

Merge "PartitionCowCreator accounts for extra extents"

am: adb98df1

Change-Id: I0df9eb0def72ea3fdcb1fa8b9c034010cabf21b5
parents eea98abc adb98df1
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()) {