update_engine: Remove sparse hole extents.

Whenever there is an extent beginning with a sparse hole, that extent
will be filtered out. Extents are now read in from the partition rather
than the file itself in ReadFileToDiff. src/dst_length are set to the
number of blocks in src/dst_extents * block_size.

This was tested manually with _GenerateSinglePayload to generate a delta
payload between test images.

BUG=chromium:469792,chromium:474497
TEST=`FEATURES=test emerge-link update_engine` and manual testing.

Change-Id: I384ec3f16f7fd9087159817358308f22d29e9edf
Reviewed-on: https://chromium-review.googlesource.com/264442
Reviewed-by: Don Garrett <dgarrett@chromium.org>
Trybot-Ready: Alex Deymo <deymo@chromium.org>
Commit-Queue: Allie Wood <alliewood@chromium.org>
Tested-by: Allie Wood <alliewood@chromium.org>
diff --git a/delta_performer.cc b/delta_performer.cc
index e6441fe..0544e12 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -486,7 +486,6 @@
   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|.
@@ -734,16 +733,12 @@
     ssize_t bytes_read_this_iteration = 0;
     const Extent& extent = operation.src_extents(i);
     const size_t bytes = extent.num_blocks() * block_size_;
-    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(extent.start_block() != kSparseHole);
+    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;
@@ -762,18 +757,11 @@
   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_;
-    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_));
-    }
+    TEST_AND_RETURN_FALSE(extent.start_block() != kSparseHole);
+    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);
@@ -790,13 +778,9 @@
   uint64_t length = 0;
   for (int i = 0; i < extents.size(); i++) {
     Extent extent = extents.Get(i);
-    int64_t start = extent.start_block();
+    int64_t start = extent.start_block() * block_size;
     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;
   }