liblp: Try to merge extents during partition resizes.

When adding extents to partitions, if the previous extent and new extent
are contiguous, merge them together to avoid allocating unnecessary
device-mapper targets.

Bug: 79173901
Test: liblp_test gtest
Change-Id: I80087df9aea8141c5e16f8d4cdb3dd7da02aee8c
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index eb429b9..68d024b 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -84,6 +84,19 @@
 
 void Partition::AddExtent(std::unique_ptr<Extent>&& extent) {
     size_ += extent->num_sectors() * LP_SECTOR_SIZE;
+
+    if (LinearExtent* new_extent = extent->AsLinearExtent()) {
+        if (!extents_.empty() && extents_.back()->AsLinearExtent() &&
+            extents_.back()->AsLinearExtent()->end_sector() == new_extent->physical_sector()) {
+            // If the previous extent can be merged into this new one, do so
+            // to avoid creating unnecessary extents.
+            LinearExtent* prev_extent = extents_.back()->AsLinearExtent();
+            extent = std::make_unique<LinearExtent>(
+                    prev_extent->num_sectors() + new_extent->num_sectors(),
+                    prev_extent->physical_sector());
+            extents_.pop_back();
+        }
+    }
     extents_.push_back(std::move(extent));
 }
 
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
index f1a91c4..da9c8f3 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -69,6 +69,11 @@
     EXPECT_EQ(system->size(), 131072);
     EXPECT_EQ(system->extents().size(), 1);
     EXPECT_EQ(system->extents()[0]->num_sectors(), 131072 / LP_SECTOR_SIZE);
+    // Test resizing again, that the extents are merged together.
+    builder->ResizePartition(system, 1024 * 256);
+    EXPECT_EQ(system->size(), 1024 * 256);
+    EXPECT_EQ(system->extents().size(), 1);
+    EXPECT_EQ(system->extents()[0]->num_sectors(), (1024 * 256) / LP_SECTOR_SIZE);
 
     // Test shrinking within the same extent.
     builder->ResizePartition(system, 32768);
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index e83b922..a35cf8e 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -81,6 +81,7 @@
     LinearExtent* AsLinearExtent() override { return this; }
 
     uint64_t physical_sector() const { return physical_sector_; }
+    uint64_t end_sector() const { return physical_sector_ + num_sectors_; }
 
   private:
     uint64_t physical_sector_;