From 1aab3909f79d56d0f779674ec85190ec41fc5cb4 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 3 Aug 2018 10:56:53 -0700 Subject: [PATCH] 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 --- fs_mgr/liblp/builder.cpp | 13 +++++++++++++ fs_mgr/liblp/builder_test.cpp | 5 +++++ fs_mgr/liblp/include/liblp/builder.h | 1 + 3 files changed, 19 insertions(+) diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp index eb429b930..68d024b70 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_;