e2fsdroid: Fix logical block sequencing in BaseFS.

By iterating over blocks to write BaseFS, holes in the extent tree are
skipped. This is problematic because the purpose of BaseFS is to
preserve the logical to physical block assignment between builds. By not
preserving the location of holes, the assignment can be incorrect.

For example, consider the following block list for a file:
   1 2 3 0 4 5

If this is recorded as:
   1 2 3 4 5

If the first block changes to a hole, the intended mapping will not be
preserved at all:
   0 1 2 0 3

This patch makes two changes to e2fsdroid to fix this. The first change
is that holes are now recorded in BaseFS, by iterating over the extent
tree rather than the block list, and inserting zeroes where appropriate.

The second change is that the block allocator now recognizes when blocks
have been skipped (either to deduplication or to holes), and skips the
same number of logical blocks in BaseFS as well.

In a Virtual A/B simulation, this reduces the COW snapshot size by
approximately 100MB.

Bug: 139201772
Test: m target-files-package, inspect .map files
2 files changed