Revert "update_engine: Remove sparse hole extents."
Speculatively reverting commit 96b659d794be39762e8e7fd9f72fe6f723e21ec8 due to crbug.com/474497.
Change-Id: I17fd91c8568b30eafea9e70c9f2255ac2dc459a6
Reviewed-on: https://chromium-review.googlesource.com/264306
Reviewed-by: Shawn N <shawnn@chromium.org>
Commit-Queue: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
diff --git a/delta_performer.cc b/delta_performer.cc
index 0544e12..e6441fe 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -486,6 +486,7 @@
return kMetadataParseSuccess;
}
+
// Wrapper around write. Returns true if all requested bytes
// were written, or false on any error, regardless of progress
// and stores an action exit code in |error|.
@@ -733,12 +734,16 @@
ssize_t bytes_read_this_iteration = 0;
const Extent& extent = operation.src_extents(i);
const size_t bytes = extent.num_blocks() * block_size_;
- TEST_AND_RETURN_FALSE(extent.start_block() != kSparseHole);
- TEST_AND_RETURN_FALSE(utils::PReadAll(fd,
- &buf[bytes_read],
- bytes,
- extent.start_block() * block_size_,
- &bytes_read_this_iteration));
+ if (extent.start_block() == kSparseHole) {
+ bytes_read_this_iteration = bytes;
+ memset(&buf[bytes_read], 0, bytes);
+ } else {
+ TEST_AND_RETURN_FALSE(utils::PReadAll(fd,
+ &buf[bytes_read],
+ bytes,
+ extent.start_block() * block_size_,
+ &bytes_read_this_iteration));
+ }
TEST_AND_RETURN_FALSE(
bytes_read_this_iteration == static_cast<ssize_t>(bytes));
bytes_read += bytes_read_this_iteration;
@@ -757,11 +762,18 @@
for (int i = 0; i < operation.dst_extents_size(); i++) {
const Extent& extent = operation.dst_extents(i);
const size_t bytes = extent.num_blocks() * block_size_;
- TEST_AND_RETURN_FALSE(extent.start_block() != kSparseHole);
- TEST_AND_RETURN_FALSE(utils::PWriteAll(fd,
- &buf[bytes_written],
- bytes,
- extent.start_block() * block_size_));
+ if (extent.start_block() == kSparseHole) {
+ DCHECK(buf.begin() + bytes_written ==
+ std::search_n(buf.begin() + bytes_written,
+ buf.begin() + bytes_written + bytes,
+ bytes, 0));
+ } else {
+ TEST_AND_RETURN_FALSE(
+ utils::PWriteAll(fd,
+ &buf[bytes_written],
+ bytes,
+ extent.start_block() * block_size_));
+ }
bytes_written += bytes;
}
DCHECK_EQ(bytes_written, bytes_read);
@@ -778,9 +790,13 @@
uint64_t length = 0;
for (int i = 0; i < extents.size(); i++) {
Extent extent = extents.Get(i);
- int64_t start = extent.start_block() * block_size;
+ int64_t start = extent.start_block();
uint64_t this_length = min(full_length - length,
extent.num_blocks() * block_size);
+ if (start == static_cast<int64_t>(kSparseHole))
+ start = -1;
+ else
+ start *= block_size;
ret += base::StringPrintf("%" PRIi64 ":%" PRIu64 ",", start, this_length);
length += this_length;
}