liblp: Add MetadataBuilder::UsedSpace()

MetadataBuilder::AllocatableSpace() represents the total space
available.  Adding MetadataBuilder::UsedSpace() to represent the
space used by the existing set of partitions.  This will allow a
caller to predict if a partition can be resized (Grown), or to
create a partition to use up the free space (i.e. scratch).

Test: gTest liblp.UseAllDiskSpace
Bug: 109821005
Change-Id: Iae487d869fe18310c76b48c4281f1d6c1ee333cd
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index 018c280..352647b 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -482,6 +482,14 @@
     return (geometry_.last_logical_sector - geometry_.first_logical_sector + 1) * LP_SECTOR_SIZE;
 }
 
+uint64_t MetadataBuilder::UsedSpace() const {
+    uint64_t size = 0;
+    for (const auto& partition : partitions_) {
+        size += partition->size();
+    }
+    return size;
+}
+
 uint64_t MetadataBuilder::AlignSector(uint64_t sector) {
     // Note: when reading alignment info from the Kernel, we don't assume it
     // is aligned to the sector size, so we round up to the nearest sector.
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
index da9c8f3..0c7e43d 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -202,14 +202,28 @@
 }
 
 TEST(liblp, UseAllDiskSpace) {
-    unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
-    EXPECT_EQ(builder->AllocatableSpace(), 1036288);
+    static constexpr uint64_t total = 1024 * 1024;
+    static constexpr uint64_t metadata = 1024;
+    static constexpr uint64_t slots = 2;
+    unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(total, metadata, slots);
+    // We reserve a geometry block (4KB) plus space for each copy of the
+    // maximum size of a metadata blob. Then, we double that space since
+    // we store a backup copy of everything.
+    static constexpr uint64_t geometry = 4 * 1024;
+    static constexpr uint64_t allocatable = total - (metadata * slots + geometry) * 2;
+    EXPECT_EQ(builder->AllocatableSpace(), allocatable);
+    EXPECT_EQ(builder->UsedSpace(), 0);
 
     Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
-    EXPECT_EQ(builder->ResizePartition(system, 1036288), true);
-    EXPECT_EQ(system->size(), 1036288);
-    EXPECT_EQ(builder->ResizePartition(system, 1036289), false);
+    EXPECT_EQ(builder->ResizePartition(system, allocatable), true);
+    EXPECT_EQ(system->size(), allocatable);
+    EXPECT_EQ(builder->UsedSpace(), allocatable);
+    EXPECT_EQ(builder->AllocatableSpace(), allocatable);
+    EXPECT_EQ(builder->ResizePartition(system, allocatable + 1), false);
+    EXPECT_EQ(system->size(), allocatable);
+    EXPECT_EQ(builder->UsedSpace(), allocatable);
+    EXPECT_EQ(builder->AllocatableSpace(), allocatable);
 }
 
 TEST(liblp, BuildComplex) {
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index 38842a4..2780825 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -184,6 +184,7 @@
 
     // Amount of space that can be allocated to logical partitions.
     uint64_t AllocatableSpace() const;
+    uint64_t UsedSpace() const;
 
     // Merge new block device information into previous values. Alignment values
     // are only overwritten if the new values are non-zero.