Merge "liblp: Reclaim wasted space from unaligned partitions."

am: 0059bc76c3

Change-Id: I45f97a3bd14d669012bbd09368ca8abc94f4a1f9
This commit is contained in:
David Anderson 2018-12-10 16:56:37 -08:00 committed by android-build-merger
commit 0447f87bad
2 changed files with 48 additions and 15 deletions

View file

@ -606,14 +606,23 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size)
}
uint64_t sectors = std::min(sectors_needed, region.length());
if (sectors < region.length()) {
const auto& block_device = block_devices_[region.device_index];
if (block_device.alignment) {
const uint64_t alignment = block_device.alignment / LP_SECTOR_SIZE;
sectors = AlignTo(sectors, alignment);
sectors = std::min(sectors, region.length());
}
}
CHECK(sectors % sectors_per_block == 0);
auto extent = std::make_unique<LinearExtent>(sectors, region.device_index, region.start);
new_extents.push_back(std::move(extent));
sectors_needed -= sectors;
if (!sectors_needed) {
if (sectors >= sectors_needed) {
sectors_needed = 0;
break;
}
sectors_needed -= sectors;
}
if (sectors_needed) {
LERROR << "Not enough free space to expand partition: " << partition->name();

View file

@ -209,8 +209,8 @@ TEST_F(BuilderTest, InternalPartitionAlignment) {
ASSERT_TRUE(builder->ResizePartition(a, a->size() + 4096));
ASSERT_TRUE(builder->ResizePartition(b, b->size() + 4096));
}
EXPECT_EQ(a->size(), 40960);
EXPECT_EQ(b->size(), 40960);
EXPECT_EQ(a->size(), 7864320);
EXPECT_EQ(b->size(), 7864320);
unique_ptr<LpMetadata> exported = builder->Export();
ASSERT_NE(exported, nullptr);
@ -218,7 +218,7 @@ TEST_F(BuilderTest, InternalPartitionAlignment) {
// Check that each starting sector is aligned.
for (const auto& extent : exported->extents) {
ASSERT_EQ(extent.target_type, LP_TARGET_TYPE_LINEAR);
EXPECT_EQ(extent.num_sectors, 8);
EXPECT_EQ(extent.num_sectors, 1536);
uint64_t lba = extent.target_data * LP_SECTOR_SIZE;
uint64_t aligned_lba = AlignTo(lba, device_info.alignment, device_info.alignment_offset);
@ -645,7 +645,7 @@ TEST_F(BuilderTest, MultipleBlockDevices) {
EXPECT_EQ(metadata->extents[1].target_type, LP_TARGET_TYPE_LINEAR);
EXPECT_EQ(metadata->extents[1].target_data, 1472);
EXPECT_EQ(metadata->extents[1].target_source, 1);
EXPECT_EQ(metadata->extents[2].num_sectors, 129088);
EXPECT_EQ(metadata->extents[2].num_sectors, 129600);
EXPECT_EQ(metadata->extents[2].target_type, LP_TARGET_TYPE_LINEAR);
EXPECT_EQ(metadata->extents[2].target_data, 1472);
EXPECT_EQ(metadata->extents[2].target_source, 2);
@ -744,17 +744,41 @@ TEST_F(BuilderTest, ABExtents) {
EXPECT_EQ(system_a->extents().size(), static_cast<size_t>(1));
EXPECT_EQ(system_b->extents().size(), static_cast<size_t>(1));
ASSERT_TRUE(builder->ResizePartition(system_b, 6_GiB));
EXPECT_EQ(system_b->extents().size(), static_cast<size_t>(3));
EXPECT_EQ(system_b->extents().size(), static_cast<size_t>(2));
unique_ptr<LpMetadata> exported = builder->Export();
ASSERT_NE(exported, nullptr);
ASSERT_EQ(exported->extents.size(), static_cast<size_t>(4));
ASSERT_EQ(exported->extents.size(), static_cast<size_t>(3));
EXPECT_EQ(exported->extents[0].target_data, 10487808);
EXPECT_EQ(exported->extents[0].num_sectors, 4194304);
EXPECT_EQ(exported->extents[1].target_data, 14682624);
EXPECT_EQ(exported->extents[1].num_sectors, 6288896);
EXPECT_EQ(exported->extents[2].target_data, 6292992);
EXPECT_EQ(exported->extents[2].num_sectors, 2099712);
EXPECT_EQ(exported->extents[3].target_data, 1536);
EXPECT_EQ(exported->extents[3].num_sectors, 6291456);
EXPECT_EQ(exported->extents[0].num_sectors, 10483712);
EXPECT_EQ(exported->extents[1].target_data, 6292992);
EXPECT_EQ(exported->extents[1].num_sectors, 2099712);
EXPECT_EQ(exported->extents[2].target_data, 1536);
EXPECT_EQ(exported->extents[2].num_sectors, 6291456);
}
TEST_F(BuilderTest, PartialExtents) {
// super has a minimum extent size of 768KiB.
BlockDeviceInfo device_info("super", 1_GiB, 768 * 1024, 0, 4096);
auto builder = MetadataBuilder::New(device_info, 65536, 1);
ASSERT_NE(builder, nullptr);
Partition* system = builder->AddPartition("system", 0);
ASSERT_NE(system, nullptr);
Partition* vendor = builder->AddPartition("vendor", 0);
ASSERT_NE(vendor, nullptr);
ASSERT_TRUE(builder->ResizePartition(system, device_info.alignment + 4096));
ASSERT_TRUE(builder->ResizePartition(vendor, device_info.alignment));
ASSERT_EQ(system->size(), device_info.alignment * 2);
ASSERT_EQ(vendor->size(), device_info.alignment);
ASSERT_TRUE(builder->ResizePartition(system, device_info.alignment * 2));
ASSERT_EQ(system->extents().size(), static_cast<size_t>(1));
unique_ptr<LpMetadata> exported = builder->Export();
ASSERT_NE(exported, nullptr);
ASSERT_EQ(exported->extents.size(), static_cast<size_t>(2));
EXPECT_EQ(exported->extents[0].target_data, 1536);
EXPECT_EQ(exported->extents[0].num_sectors, 3072);
EXPECT_EQ(exported->extents[1].target_data, 4608);
EXPECT_EQ(exported->extents[1].num_sectors, 1536);
}