AU: When generating delta, use scratch off end of filesystem
This idea was originally coded by Darin Petkov, but was lost during a
separate bug fix a while ago. This CL restores the functionality.
The partition limit is set to 1GiB right now.
BUG=7444
TEST=tested generating/applying on host and checking results; unittest; tested specific case 110.9->128.4 that release engineers saw
Change-Id: I28a9a8d7025b83ec20b91e97dce5b783fc060b7c
Review URL: http://codereview.chromium.org/5548002
diff --git a/delta_diff_generator.cc b/delta_diff_generator.cc
index d084138..21a4c03 100644
--- a/delta_diff_generator.cc
+++ b/delta_diff_generator.cc
@@ -54,6 +54,9 @@
namespace {
const size_t kBlockSize = 4096; // bytes
+
+// TODO(adlr): switch from 1GiB to 2GiB when we no longer care about old
+// clients:
const size_t kRootFSPartitionSize = 1 * 1024 * 1024 * 1024; // bytes
const uint64_t kVersionNumber = 1;
const uint64_t kFullUpdateChunkSize = 1024 * 1024; // bytes
@@ -1027,7 +1030,7 @@
if (ranges.blocks() + scratch_blocks_found > blocks_needed) {
// trim down ranges
vector<Extent> new_ranges = ranges.GetExtentsForBlockCount(
- blocks_needed - scratch_blocks_found);
+ blocks_needed - scratch_blocks_found);
ranges = ExtentRanges();
ranges.AddExtents(new_ranges);
}
@@ -1256,7 +1259,8 @@
const string& new_root,
int fd,
off_t* data_file_size,
- vector<Vertex::Index>* final_order) {
+ vector<Vertex::Index>* final_order,
+ Vertex::Index scratch_vertex) {
CycleBreaker cycle_breaker;
LOG(INFO) << "Finding cycles...";
set<Edge> cut_edges;
@@ -1297,12 +1301,32 @@
cuts));
LOG(INFO) << "Making sure all temp blocks have been allocated";
+ // Remove the scratch node, if any
+ if (scratch_vertex != Vertex::kInvalidIndex) {
+ final_order->erase(final_order->begin() +
+ inverse_final_order[scratch_vertex]);
+ (*graph)[scratch_vertex].valid = false;
+ GenerateReverseTopoOrderMap(*final_order, &inverse_final_order);
+ }
+
graph_utils::DumpGraph(*graph);
CHECK(NoTempBlocksRemain(*graph));
LOG(INFO) << "done making sure all temp blocks are allocated";
return true;
}
+void DeltaDiffGenerator::CreateScratchNode(uint64_t start_block,
+ uint64_t num_blocks,
+ Vertex* vertex) {
+ vertex->file_name = "<scratch>";
+ vertex->op.set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ);
+ vertex->op.set_data_offset(0);
+ vertex->op.set_data_length(0);
+ Extent* extent = vertex->op.add_dst_extents();
+ extent->set_start_block(start_block);
+ extent->set_num_blocks(num_blocks);
+}
+
bool DeltaDiffGenerator::GenerateDeltaUpdateFile(
const string& old_root,
const string& old_image,
@@ -1347,6 +1371,7 @@
vector<DeltaArchiveManifest_InstallOperation> kernel_ops;
vector<Vertex::Index> final_order;
+ Vertex::Index scratch_vertex = Vertex::kInvalidIndex;
{
int fd;
TEST_AND_RETURN_FALSE(
@@ -1372,6 +1397,15 @@
new_image,
&graph.back()));
+ // Final scratch block (if there's space)
+ if (blocks.size() < (kRootFSPartitionSize / kBlockSize)) {
+ scratch_vertex = graph.size();
+ graph.resize(graph.size() + 1);
+ CreateScratchNode(blocks.size(),
+ (kRootFSPartitionSize / kBlockSize) - blocks.size(),
+ &graph.back());
+ }
+
// Read kernel partition
TEST_AND_RETURN_FALSE(DeltaCompressKernelPartition(old_kernel_part,
new_kernel_part,
@@ -1391,7 +1425,8 @@
new_root,
fd,
&data_file_size,
- &final_order));
+ &final_order,
+ scratch_vertex));
} else {
// Full update
off_t new_image_size =