pygpt: Correct Resize calculation.

When resizing, we should keep FirstUsableLBA unchanged. There is no
reason to enlarge partition table sections by looking at the gap between
partition entries and first usable LBA. And for backup partitions, there
is also no reason to pad more blocks.

As a result, the calculation should be pretty simple:
 1. Find new Backup LBA (as total blocks - 1).
 2. Calculate the LastUsableLBA by BackupLBA - size of backup partition table.
 3. Make sure the new LastUsable LBA is not less than any partition's LastLBA.

By the new algorithm, GetMinUsedLBA is not needed. Also GetMaxUsedLBA
should look at any partitions (even if there are unused partitions
before it) that has claimed space (i.e., TYPE_GUID is not UNUSED).

BUG=chromium:834237
TEST=make test

Change-Id: I70a9d59bc34b4dea02dfc9aa718e167dcc35970d
Reviewed-on: https://chromium-review.googlesource.com/1018741
Commit-Ready: Hung-Te Lin <hungte@chromium.org>
Tested-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-by: Pi-Hsun Shih <pihsun@chromium.org>
diff --git a/py/utils/pygpt.py b/py/utils/pygpt.py
index aa38da9..de4eb9e 100755
--- a/py/utils/pygpt.py
+++ b/py/utils/pygpt.py
@@ -207,12 +207,10 @@
     return self.partitions
 
   def GetMaxUsedLBA(self):
-    """Returns the max LastLBA from all valid partitions."""
-    return max(p.LastLBA for p in self.GetValidPartitions())
-
-  def GetMinUsedLBA(self):
-    """Returns the min FirstLBA from all valid partitions."""
-    return min(p.FirstLBA for p in self.GetValidPartitions())
+    """Returns the max LastLBA from all used partitions."""
+    parts = [p for p in self.partitions if p.TypeGUID != GPT.TYPE_GUID_UNUSED]
+    return (max(p.LastLBA for p in parts)
+            if parts else self.header.FirstUsableLBA - 1)
 
   def GetPartitionTableBlocks(self, header=None):
     """Returns the blocks (or LBA) of partition table from given header."""
@@ -241,28 +239,16 @@
     else:
       logging.info('Image size (%d, LBA=%d) not changed.',
                    new_size, new_blocks)
+      return
 
-    # Re-calculate all related fields.
+    # Expected location
     backup_lba = new_blocks - 1
-    partitions_blocks = self.GetPartitionTableBlocks()
+    last_usable_lba = backup_lba - self.header.FirstUsableLBA
 
-    # To add allow adding more blocks for partition table, we should reserve
-    # same space between primary and backup partition tables and real
-    # partitions.
-    min_used_lba = self.GetMinUsedLBA()
-    max_used_lba = self.GetMaxUsedLBA()
-    primary_reserved = min_used_lba - self.header.PartitionEntriesStartingLBA
-    primary_last_lba = (self.header.PartitionEntriesStartingLBA +
-                        partitions_blocks - 1)
-
-    if primary_last_lba >= min_used_lba:
-      raise ValueError('Partition table overlaps partitions.')
-    if max_used_lba + partitions_blocks >= backup_lba:
-      raise ValueError('Partitions overlaps backup partition table.')
-
-    last_usable_lba = backup_lba - primary_reserved - 1
-    if last_usable_lba < max_used_lba:
-      last_usable_lba = max_used_lba
+    if last_usable_lba < self.header.LastUsableLBA:
+      max_used_lba = self.GetMaxUsedLBA()
+      if last_usable_lba < max_used_lba:
+        raise ValueError('Backup partition tables will overlap used partitions')
 
     self.header = self.NewNamedTuple(
         self.header,