diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp index 42c3eac0c..2015e4d78 100644 --- a/fs_mgr/liblp/builder.cpp +++ b/fs_mgr/liblp/builder.cpp @@ -84,6 +84,19 @@ Partition::Partition(const std::string& name, const std::string& guid, uint32_t void Partition::AddExtent(std::unique_ptr&& 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( + 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 f1a91c479..da9c8f37e 100644 --- a/fs_mgr/liblp/builder_test.cpp +++ b/fs_mgr/liblp/builder_test.cpp @@ -69,6 +69,11 @@ TEST(liblp, ResizePartition) { 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 e83b92297..a35cf8e3a 100644 --- a/fs_mgr/liblp/include/liblp/builder.h +++ b/fs_mgr/liblp/include/liblp/builder.h @@ -81,6 +81,7 @@ class LinearExtent final : public Extent { 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_;