Merge "PartitionCowCreator accounts for extra extents"
This commit is contained in:
commit
adb98df120
3 changed files with 50 additions and 19 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
.target_suffix = target_suffix,
|
||||
.target_partition = nullptr,
|
||||
.current_metadata = current_metadata.get(),
|
||||
.current_suffix = current_suffix,
|
||||
.operations = nullptr};
|
||||
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,
|
||||
.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()) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue