Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0059bc76 authored by David Anderson's avatar David Anderson Committed by Gerrit Code Review
Browse files

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

parents e610ad61 dccfdca1
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -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();
+37 −13
Original line number Diff line number Diff line
@@ -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);
}